-
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 7 commits
42ff51a
821aece
39f17b8
5d24e5a
f4f44c8
8575306
a3f5ac2
185ccc0
56f8cbe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1581,6 +1581,10 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) | |
|
|
||
| class AnsiStringMarshaller : Marshaller | ||
| { | ||
| const int MAX_LOCAL_BUFFER_LENGTH = 260 + 1; // MAX_PATH + 1 | ||
|
|
||
| private ILLocalVariable _localBuffer = default; | ||
|
|
||
| internal override bool CleanupRequired | ||
mangod9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| get | ||
|
|
@@ -1605,12 +1609,75 @@ protected override void TransformManagedToNative(ILCodeStream codeStream) | |
|
|
||
| #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; | ||
|
|
||
| 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.IntPtr)); | ||
|
|
||
| // 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); | ||
|
|
||
| if (_localBuffer != default) | ||
mangod9 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| codeStream.EmitLdLoc(_localBuffer); | ||
| } | ||
| else | ||
| { | ||
| codeStream.Emit(ILOpcode.ldnull); | ||
| } | ||
|
|
||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); | ||
| #else | ||
| LoadManagedValue(codeStream); | ||
|
|
@@ -1631,7 +1698,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"); | ||
|
|
@@ -1645,11 +1712,28 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream) | |
| { | ||
| var emitter = _ilCodeStreams.Emitter; | ||
| #if READYTORUN | ||
| var optimize = emitter.NewCodeLabel(); | ||
|
|
||
| MethodDesc clearNative = | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "AnsiBSTRMarshaler") | ||
| Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") | ||
| .GetKnownMethod("ClearNative", null); | ||
|
|
||
| if (_localBuffer != default) | ||
| { | ||
| // if (m_dwLocalBuffer) goto Optimize | ||
| codeStream.EmitLdLoc(_localBuffer); | ||
| codeStream.Emit(ILOpcode.brtrue, optimize); | ||
| } | ||
|
|
||
| LoadNativeValue(codeStream); | ||
| // static void m_idClearNative(IntPtr ptr) | ||
| codeStream.Emit(ILOpcode.call, emitter.NewToken(clearNative)); | ||
|
|
||
| // Optimize: | ||
| if (_localBuffer != default) | ||
| { | ||
| codeStream.EmitLabel(optimize); | ||
| } | ||
| #else | ||
| var lNullCheck = emitter.NewCodeLabel(); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.