summaryrefslogtreecommitdiff
path: root/src/zap/zapimport.cpp
diff options
context:
space:
mode:
authortijoytom <tijoytom.com>2015-09-03 13:58:14 -0700
committertijoytom <tijoytom.com>2015-09-18 10:00:14 -0700
commit1e62862b631fb64c6a9fae0a0084c0ae1d9fbeba (patch)
tree46c2fd40ae20d229c97cb9a1966cba78c6f04f52 /src/zap/zapimport.cpp
parentb2964aff2a5a77b1df87b94005face366921a9b8 (diff)
downloadcoreclr-1e62862b631fb64c6a9fae0a0084c0ae1d9fbeba.tar.gz
coreclr-1e62862b631fb64c6a9fae0a0084c0ae1d9fbeba.tar.bz2
coreclr-1e62862b631fb64c6a9fae0a0084c0ae1d9fbeba.zip
Add support for NativeCallableAttribute
Apply [NativeCallable] attribute to a managed method and then it can be called from native code.Typical use would be passing a managed method as callback to native, now it can be done by wrapping the method in a delegate or directly using Marshal.GetFunctionPointerForDelegate.This's fine as long as we make sure that delegate is not garbage collected.[NativeCallable] introduce another way, where you can directly load the function pointer of a native callable method and use it as callback.This feature cannot be directly used from C#,but can be very useful in dynamic code generation scenarios where you want a callback to be passed to native. Here's an example of how it can be used. public static class NativeMethods { [DllImport("user32.dll")] public static extern int EnumWindows(IntPtr enumProc, IntPtr lParam); } //Method attributed with NativeCallable [NativeCallable] public static int CallbackMethod(IntPtr hWnd, IntPtr lParam){ return 1; } Now you can generate the below IL to load native callable function pointer ( LDFTN) and then pass it a native method. .locals init ([0] native int ptr) nop ldftn int32 CallbackMethod(native int,native int) stloc.0 ldloc.0 ldsfld native int System.IntPtr::Zero call bool NativeMethods::EnumWindows(native int,native int) pop ret Encoding native callable methods as ENCODE_METHOD_NATIVECALLABLE_HANDLE so that we don't have to check for the custom attribute at runtime to decode the method.Also fixing the remaining code review comments. Adding runtime check to prevent Native Callable methods from being used as calli target with an ldftn. Also adding some negative test cases , they are disabled for now since the tests failfast and msbuild report it as failure.
Diffstat (limited to 'src/zap/zapimport.cpp')
-rw-r--r--src/zap/zapimport.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp
index 6252d524e1..890392f478 100644
--- a/src/zap/zapimport.cpp
+++ b/src/zap/zapimport.cpp
@@ -1287,10 +1287,18 @@ public:
if (token != mdTokenNil)
{
_ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
-
- pTable->EncodeModule(
- (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
- referencingModule, pSigBuilder);
+
+ // It's a NativeCallable method , then encode it as ENCODE_METHOD_NATIVE_ENTRY
+ if (pTable->GetCompileInfo()->IsNativeCallableMethod(handle))
+ {
+ pTable->EncodeModule(ENCODE_METHOD_NATIVE_ENTRY, referencingModule, pSigBuilder);
+ }
+ else
+ {
+ pTable->EncodeModule(
+ (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
+ referencingModule, pSigBuilder);
+ }
pSigBuilder->AppendData(RidFromToken(token));
}