-
Notifications
You must be signed in to change notification settings - Fork 5.3k
switch to using CSTRMarshaller instead of AnsiBSTR #55032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
42ff51a
821aece
39f17b8
5d24e5a
f4f44c8
8575306
a3f5ac2
185ccc0
56f8cbe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1581,13 +1581,7 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) | |
|
|
||
| class AnsiStringMarshaller : Marshaller | ||
| { | ||
| internal override bool CleanupRequired | ||
| { | ||
| get | ||
| { | ||
| return true; | ||
| } | ||
| } | ||
| const int MAX_LOCAL_BUFFER_LENGTH = 256; // TODO: Is this accurate on all platforms? | ||
|
|
||
| internal override void EmitElementCleanup(ILCodeStream codeStream, ILEmitter emitter) | ||
| { | ||
|
|
@@ -1603,24 +1597,77 @@ protected override void TransformManagedToNative(ILCodeStream codeStream) | |
| // ANSI marshalling. Allocate a byte array, copy characters | ||
| // | ||
|
|
||
| #if READYTORUN | ||
mangod9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| var stringToAnsi = | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "AnsiBSTRMarshaler") | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") | ||
| .GetKnownMethod("ConvertToNative", null); | ||
|
|
||
| bool bPassByValueInOnly = In && !Out && !IsManagedByRef; | ||
| ILLocalVariable localBuffer = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.IntPtr)); | ||
| if (bPassByValueInOnly) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a reason why this logic cant move to
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it would be nice to have majority of the logic in C#, and minimize amount of the hand-emitted IL. |
||
| { | ||
| var bufSize = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32)); | ||
| //localBuffer = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Byte)); | ||
|
|
||
| // LocalBuffer = 0 | ||
| codeStream.Emit(ILOpcode.ldnull); | ||
| codeStream.EmitStLoc(localBuffer); | ||
|
|
||
| var noOptimize = emitter.NewCodeLabel(); | ||
|
|
||
| // if == NULL, goto NoOptimize | ||
| LoadManagedValue(codeStream); | ||
| codeStream.Emit(ILOpcode.brfalse, noOptimize); | ||
|
|
||
| // String.Length + 2 | ||
| LoadManagedValue(codeStream); | ||
| var stringLen = | ||
| Context.SystemModule.GetKnownType("System", "String") | ||
mangod9 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| .GetKnownMethod("get_Length", null); | ||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(stringLen)); | ||
| codeStream.EmitLdc(2); | ||
| codeStream.Emit(ILOpcode.add); | ||
|
|
||
| // (String.Length + 2) * GetMaxDBCSCharByteSize() | ||
| codeStream.Emit(ILOpcode.ldsfld, emitter.NewToken(Context.SystemModule.GetKnownType( | ||
| "System.Runtime.InteropServices","Marshal") | ||
| .GetKnownField("SystemMaxDBCSCharSize"))); | ||
| codeStream.Emit(ILOpcode.mul_ovf); | ||
|
|
||
| // BufSize = (String.Length + 2) * GetMaxDBCSCharByteSize() | ||
| codeStream.EmitStLoc(bufSize); | ||
|
|
||
| // if (MAX_LOCAL_BUFFER_LENGTH < BufSize ) goto NoOptimize | ||
| codeStream.EmitLdc(MAX_LOCAL_BUFFER_LENGTH + 1); | ||
| codeStream.EmitLdLoc(bufSize); | ||
| codeStream.Emit(ILOpcode.clt); | ||
| codeStream.Emit(ILOpcode.brtrue, noOptimize); | ||
|
|
||
| // LocalBuffer = localloc(BufSize); | ||
| codeStream.EmitLdLoc(bufSize); | ||
| codeStream.Emit(ILOpcode.localloc); | ||
| codeStream.EmitStLoc(localBuffer); | ||
|
|
||
| // NoOptimize: | ||
| codeStream.EmitLabel(noOptimize); | ||
| } | ||
|
|
||
| int flags = (PInvokeFlags.BestFitMapping ? 0x1 : 0) | ||
| | (PInvokeFlags.ThrowOnUnmappableChar ? 0x100 : 0); | ||
|
|
||
| // CSTRMarshaler.ConvertToNative pManaged, dwAnsiMarshalFlags, pLocalBuffer | ||
| codeStream.EmitLdc(flags); | ||
| LoadManagedValue(codeStream); | ||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); | ||
| #else | ||
| LoadManagedValue(codeStream); | ||
| var stringToAnsi = Context.GetHelperEntryPoint("InteropHelpers", "StringToAnsiString"); | ||
|
|
||
| codeStream.Emit(PInvokeFlags.BestFitMapping ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0); | ||
| codeStream.Emit(PInvokeFlags.ThrowOnUnmappableChar ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0); | ||
| if (bPassByValueInOnly) | ||
| { | ||
| codeStream.EmitLdLoc(localBuffer); | ||
| } | ||
| else | ||
| { | ||
| codeStream.Emit(ILOpcode.ldnull); | ||
| } | ||
|
|
||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); | ||
| #endif | ||
|
|
||
| StoreNativeValue(codeStream); | ||
| } | ||
|
|
@@ -1631,7 +1678,7 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) | |
|
|
||
| #if READYTORUN | ||
| var ansiToString = | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "AnsiBSTRMarshaler") | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") | ||
| .GetKnownMethod("ConvertToManaged", null); | ||
| #else | ||
| var ansiToString = Context.GetHelperEntryPoint("InteropHelpers", "AnsiStringToString"); | ||
|
|
@@ -1640,30 +1687,6 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream) | |
| codeStream.Emit(ILOpcode.call, emitter.NewToken(ansiToString)); | ||
| StoreManagedValue(codeStream); | ||
| } | ||
|
|
||
| protected override void EmitCleanupManaged(ILCodeStream codeStream) | ||
| { | ||
| var emitter = _ilCodeStreams.Emitter; | ||
| #if READYTORUN | ||
| MethodDesc clearNative = | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "AnsiBSTRMarshaler") | ||
| .GetKnownMethod("ClearNative", null); | ||
| LoadNativeValue(codeStream); | ||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(clearNative)); | ||
| #else | ||
| var lNullCheck = emitter.NewCodeLabel(); | ||
|
|
||
| // Check for null array | ||
| LoadManagedValue(codeStream); | ||
| codeStream.Emit(ILOpcode.brfalse, lNullCheck); | ||
|
|
||
| LoadNativeValue(codeStream); | ||
| codeStream.Emit(ILOpcode.call, emitter.NewToken( | ||
| Context.GetHelperEntryPoint("InteropHelpers", "CoTaskMemFree"))); | ||
|
|
||
| codeStream.EmitLabel(lNullCheck); | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
| class UTF8StringMarshaller : Marshaller | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.