Comments (2)
Good news! I noticed the following interesting thing. Final logic from implemented managed EmitCalli() and its calling convention 'Standard' is much closely related to actual logic that's required for our unmanaged type :)
Decompiled versions below was just for my convenience when debugging at this case. But the original code you can find in original coreclr repo or from my mod repo for .NET DllExport project.
See src part for System.Private.CoreLib
So! What I found:
All code below has been trimmed (+added specific parts to this case) just to illustrate the main flow between different implementations.
Unmanaged EmitCalli ~
...
ModuleBuilder moduleBuilder = (ModuleBuilder)m_methodBuilder.Module;
...
SignatureHelper methodSigHelper = SignatureHelper.GetMethodSigHelper(moduleBuilder, unmanagedCallConv, returnType);
if (parameterTypes != null)
{
for (int i = 0; i < num2; i++)
{
methodSigHelper.AddArgument(parameterTypes[i]);
}
}
if (returnType != typeof(void))
{
num++;
}
if (parameterTypes != null)
{
num -= num2; // num2 = parameterTypes.Length;
}
num--;
UpdateStackSize(OpCodes.Calli, num);
EnsureCapacity(7);
Emit(OpCodes.Calli);
RecordTokenFixup();
PutInteger4(moduleBuilder.GetSignatureToken(methodSigHelper).Token);
Managed EmitCalli when 'Standard' ~
...
ModuleBuilder moduleBuilder = (ModuleBuilder)m_methodBuilder.Module;
SignatureHelper memberRefSignature = GetMemberRefSignature(callingConvention, returnType, parameterTypes, optionalParameterTypes);
EnsureCapacity(7);
Emit(OpCodes.Calli);
if (returnType != typeof(void))
{
num++;
}
if (parameterTypes != null)
{
num -= parameterTypes.Length;
}
...
num--;
UpdateStackSize(OpCodes.Calli, num);
RecordTokenFixup();
PutInteger4(moduleBuilder.GetSignatureToken(memberRefSignature).Token);
// >> GetMemberRefSignature
return GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, 0);
// >> GetMemberRefSignature
return ((ModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, cGenericParameters);
// >> GetMemberRefSignature
SignatureHelper methodSigHelper = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);
if (parameterTypes != null)
{
foreach (Type clsArgument in parameterTypes)
{
methodSigHelper.AddArgument(clsArgument);
}
}
...
return methodSigHelper;
Did you notice it? All minimal instructions are the same to unmanaged implementation as we can see here.
Good! We only need to inspect method signature!
Method signature and internal GetMethodSigHelper
Both implementations above uses internal MdSigCallingConvention:
CallConvMask = 0xF,
Default = 0x0,
C = 0x1,
StdCall = 0x2,
ThisCall = 0x3,
FastCall = 0x4,
Vararg = 0x5,
Field = 0x6,
LocalSig = 0x7,
Property = 0x8,
Unmgd = 0x9,
GenericInst = 0xA,
Generic = 0x10,
HasThis = 0x20,
ExplicitThis = 0x40
After some different layers they have the final m_signature processing as follow:
if (m_currSig + 4 > m_signature.Length)
{
m_signature = ExpandArray(m_signature);
}
if (data <= 127)
{
m_signature[m_currSig++] = (byte)(data & 0xFF);
return;
}
if (data <= 16383)
{
m_signature[m_currSig++] = (byte)((data >> 8) | 0x80);
m_signature[m_currSig++] = (byte)(data & 0xFF);
return;
}
if (data <= 536870911)
{
m_signature[m_currSig++] = (byte)((data >> 24) | 0xC0);
m_signature[m_currSig++] = (byte)((data >> 16) & 0xFF);
m_signature[m_currSig++] = (byte)((data >> 8) & 0xFF);
m_signature[m_currSig++] = (byte)(data & 0xFF);
return;
}
And this is it, an added m_signature item above (means when MdSigCallingConvention data) will be between 1 - 4 (inclusive) for unmanaged, and 0 for managed ('Standard' should be processed as MdSigCallingConvention.Default).
That is, for example, we can try to control it like:
0 1 1 8 0 ... -> 2 1 1 8 0 ...
I'll update PR soon because I already have a working draft :p
from conari.
Cross-link to a project that provides an independent Unmanaged EmitCalli implementation
- https://github.com/3F/UnmanagedEmitCalli
from conari.
Related Issues (20)
- logo HOT 1
- Speed
- File Not Found HOT 8
- The BreakPionts Not Work HOT 2
- LoadLibrary/Ex vs Conari. Same memory regions between processes and threads
- Support [Guide to add DllExport attribute to my project] HOT 4
- ExVar.getVar returning wrong value HOT 4
- Failed loading '...': Check used architecture or existence of file.[Error: 126] HOT 5
- The type or namespace name 'DotNet' does not exist HOT 3
- Work with Native C/C++ structures without declaration HOT 1
- Does it support for .net5 sdk? HOT 1
- How to properly use the "NativeStruct" from current Conari Version? HOT 19
- Undecorate functions from C++ compilers HOT 2
- Failed loading '...': Check used architecture or existence of file.[Error: 193]
- Support of .NET libraries
- Incorrect boolean values from unmanaged code HOT 1
- Support of exported variables / constants HOT 2
- IUnknown. COM Interface support
- Aliases for exported-functions and variables HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from conari.