/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dm; ILGenerator generator; if (ScriptEngine.LowPrivilegeEnvironment == false) { // Full trust only - skips visibility checks. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. generator = new DynamicILGenerator(dm); } else { // Partial trust / silverlight. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }); // Parameter types of the generated method. generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); } // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return((BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate))); }
public static TDelegate MethodEmit <TDelegate>(MethodInfo methodInfo) where TDelegate : class { Type[] parameterTypes; parameterTypes = GetFuncDelegateArguments <TDelegate>(); System.Reflection.Emit.DynamicMethod m = new System.Reflection.Emit.DynamicMethod( "call_" + methodInfo.Name, GetFuncDelegateReturnType <TDelegate>(), parameterTypes, methodInfo.DeclaringType, true); System.Reflection.Emit.ILGenerator cg = m.GetILGenerator(); for (int i = 0; i < parameterTypes.Length; i++) { cg.Emit(System.Reflection.Emit.OpCodes.Ldarg, i); if (i > 0 && parameterTypes[i] == typeof(object)) { cg.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, methodInfo.GetParameters()[i - 1].ParameterType); } } cg.Emit(System.Reflection.Emit.OpCodes.Callvirt, methodInfo); if (methodInfo.ReturnType.IsValueType) { cg.Emit(System.Reflection.Emit.OpCodes.Box, methodInfo.ReturnType); } cg.Emit(System.Reflection.Emit.OpCodes.Ret); return(m.CreateDelegate(typeof(TDelegate)) as TDelegate); }
public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } }
public static EmptyCtorDelegate GetConstructorMethodToCache(Type type) { var emptyCtor = type.GetTypeInfo().GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.DeclaredOnly) .FirstOrDefault(c => c.GetParameters().Length == 0); if (emptyCtor != null) { #if MONOTOUCH || SILVERLIGHT || XBOX return(() => Activator.CreateInstance(type)); #else var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).GetTypeInfo().Module, true); var ilgen = dm.GetILGenerator(); ilgen.Emit(System.Reflection.Emit.OpCodes.Nop); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor); ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); return((EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate))); #endif } #if SILVERLIGHT || XBOX || CORE_CLR return(() => throw new JsonSerializationException($"{type.Name} can't be deserialized because it needs a parameterless constructor")); #else //Anonymous types don't have empty constructors return(() => FormatterServices.GetUninitializedObject(type)); #endif }
public static EmptyCtorDelegate GetConstructorMethodToCache(Type type) { var emptyCtor = type.GetConstructor(Type.EmptyTypes); if (emptyCtor != null) { #if MONOTOUCH || c || XBOX return(() => Activator.CreateInstance(type)); #elif WINDOWS_PHONE return(Expression.Lambda <EmptyCtorDelegate>(Expression.New(type)).Compile()); #else #if SILVERLIGHT var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes); #else var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).Module, true); #endif var ilgen = dm.GetILGenerator(); ilgen.Emit(System.Reflection.Emit.OpCodes.Nop); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor); ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); return((EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate))); #endif } #if (SILVERLIGHT && !WINDOWS_PHONE) || XBOX return(() => Activator.CreateInstance(type)); #elif WINDOWS_PHONE return(Expression.Lambda <EmptyCtorDelegate>(Expression.New(type)).Compile()); #else //Anonymous types don't have empty constructors return(() => FormatterServices.GetUninitializedObject(type)); #endif }
private static RuntimeMethodHandle GetDynamicHandle(Reflection.Emit.DynamicMethod dynamicMethod) { // MS API var descr = typeof(Reflection.Emit.DynamicMethod) .GetMethod("GetMethodDescriptor", BindingFlags.Instance | BindingFlags.NonPublic); if (descr != null) { var res = (RuntimeMethodHandle)descr.Invoke(dynamicMethod, null); RuntimeHelpers.PrepareMethod(res); return(res); } // Mono API var descr2 = typeof(Reflection.Emit.DynamicMethod) .GetMethod("CreateDynMethod", BindingFlags.Instance | BindingFlags.NonPublic); if (descr2 != null) { descr2.Invoke(dynamicMethod, null); var res = dynamicMethod.MethodHandle; RuntimeHelpers.PrepareMethod(res); return(res); } { // If everything else fails, force method compilation by creating a delegate of dynamic method. // TODO: We have to call with proper delegate, not just Action<> var method2 = dynamicMethod.CreateDelegate(typeof(Action)).Method; var res = method2.MethodHandle; RuntimeHelpers.PrepareMethod(res); return(res); } }
public static CodeVector makeCodeVector(int controlPointCount, DynamicMethod dm) { CodeDelegate d = (CodeDelegate)dm.CreateDelegate(typeof(CodeDelegate)); return(new DelegateCodeVector(controlPointCount, d)); }
internal static object Creator(this Type type) { #if !NETSTANDARD1_3 if (!DefaultConstructor.ContainsKey(type)) { DefaultConstructor.Add(type, type.GetConstructor(Type.EmptyTypes)); } #endif if (DefaultConstructor.ContainsKey(type) && DefaultConstructor[type] != null) { #if NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5 if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } CachedConstructor.Add(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()); return(CachedConstructor[type].Invoke()); #else if (CachedDynamicMethod.ContainsKey(type)) { return(CachedDynamicMethod[type]()); } lock (CachedDynamicMethod) { var emptyConstructor = DefaultConstructor[type]; var dynamicMethod = new System.Reflection.Emit.DynamicMethod("CreateInstance", type, Type.EmptyTypes, true); System.Reflection.Emit.ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyConstructor); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); CachedDynamicMethod.Add(type, (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator))); } return(CachedDynamicMethod[type]()); #endif } else { #if !NETSTANDARD1_3 return(FormatterServices.GetUninitializedObject(type)); #else try { if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } CachedConstructor.Add(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()); return(CachedConstructor[type].Invoke()); } catch { throw new Exception("CloneError: Default constructor is require for NETSTANDARD1_3 for type " + type.FullName); } #endif } }
internal DynamicILInfo(System.Reflection.Emit.DynamicScope scope, System.Reflection.Emit.DynamicMethod method, byte[] methodSignature) { this.m_method = method; this.m_scope = scope; this.m_methodSignature = this.m_scope.GetTokenFor(methodSignature); this.m_exceptions = new byte[0]; this.m_code = new byte[0]; this.m_localSignature = new byte[0]; }
private void SwapMethod(Reflection.MethodBase method, Reflection.Emit.DynamicMethod replacement) { RuntimeHelpers.PrepareMethod(method.MethodHandle); IntPtr pBody = method.MethodHandle.GetFunctionPointer(); var borrowed = GetDynamicHandle(replacement); IntPtr pBorrowed = borrowed.GetFunctionPointer(); Debug.Trace($"Is 64bit: {Environment.Is64BitProcess}"); unsafe { var ptr = (byte *)pBody.ToPointer(); var ptr2 = (byte *)pBorrowed.ToPointer(); var ptrDiff = ptr2 - ptr - 5; if (ptrDiff < (long)0xFFFFFFFF && ptrDiff > (long)-0xFFFFFFFF) { // 32-bit relative jump, available on both 32 and 64 bit arch. Debug.Trace($"diff is {ptrDiff} doing relative jmp"); Debug.Trace("patching on {0:X}, target: {1:X}", (ulong)ptr, (ulong)ptr2); *ptr = 0xe9; // JMP *((uint *)(ptr + 1)) = (uint)ptrDiff; } else { Debug.Trace($"diff is {ptrDiff} doing push+ret trampoline"); Debug.Trace("patching on {0:X}, target: {1:X}", (ulong)ptr, (ulong)ptr2); if (Environment.Is64BitProcess) { // For 64bit arch and likely 64bit pointers, do: // PUSH bits 0 - 32 of addr // MOV [RSP+4] bits 32 - 64 of addr // RET var cursor = ptr; *(cursor++) = 0x68; // PUSH *((uint *)cursor) = (uint)ptr2; cursor += 4; *(cursor++) = 0xC7; // MOV [RSP+4] *(cursor++) = 0x44; *(cursor++) = 0x24; *(cursor++) = 0x04; *((uint *)cursor) = (uint)((ulong)ptr2 >> 32); cursor += 4; *(cursor++) = 0xc3; // RET } else { // For 32bit arch and 32bit pointers, do: PUSH addr, RET. *ptr = 0x68; *((uint *)(ptr + 1)) = (uint)ptr2; *(ptr + 5) = 0xC3; } } Debug.LogFormat("Patched 0x{0:X} to 0x{1:X}.", (ulong)ptr, (ulong)ptr2); } }
public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { #if !WINRT #if FIRST_PASS return(null); #else TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { #if NO_REF_EMIT java.lang.invoke.MethodType methodType = MethodHandleUtil.GetDelegateMethodType(delegateType); if (methodType.parameterCount() > MethodHandleUtil.MaxArity) { throw new NotImplementedException(); } java.lang.invoke.MethodHandle exception = java.lang.invoke.MethodHandles.publicLookup() .findConstructor(mw == null || mw.IsStatic ? typeof(java.lang.AbstractMethodError) : typeof(java.lang.IllegalAccessError), java.lang.invoke.MethodType.methodType(typeof(void), typeof(string))) .bindTo(tw.Name + ".Invoke" + sig); return(Delegate.CreateDelegate(delegateType, java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments(java.lang.invoke.MethodHandles.throwException(methodType.returnType(), exception.type().returnType()), exception), 0, methodType.parameterArray()).vmtarget, "Invoke")); #else MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); #endif } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } #endif #else throw new NotImplementedException(); #endif }
private Func <object> GetCtor(Type clr, Type key, Type value) { var type = typeof(Dictionary <,>).MakeGenericType(key, value); var ctor = (type = (((type != clr) && clr.IsClass) ? clr : type)).GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.CreateInstance, null, System.Type.EmptyTypes, null); var dyn = new System.Reflection.Emit.DynamicMethod("", typeof(object), null, typeof(string), true); var il = dyn.GetILGenerator(); il.Emit(System.Reflection.Emit.OpCodes.Newobj, ctor); il.Emit(System.Reflection.Emit.OpCodes.Ret); return((Func <object>)dyn.CreateDelegate(typeof(Func <object>))); }
public static int GetManagedSize(Type type) { var method = new System.Reflection.Emit.DynamicMethod("GetManagedSizeImpl", typeof(uint), null); System.Reflection.Emit.ILGenerator gen = method.GetILGenerator(); gen.Emit(System.Reflection.Emit.OpCodes.Sizeof, type); gen.Emit(System.Reflection.Emit.OpCodes.Ret); var func = (Func <uint>)method.CreateDelegate(typeof(Func <uint>)); return(checked ((int)func())); }
public static Action <TField> StaticFieldSet <TField>(this Type source, FieldInfo fieldInfo) { System.Reflection.Emit.DynamicMethod m = new System.Reflection.Emit.DynamicMethod( "setter_" + fieldInfo.Name, typeof(void), new Type[] { typeof(TField) }, source); System.Reflection.Emit.ILGenerator cg = m.GetILGenerator(); // arg0.<field> = arg1 cg.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); cg.Emit(System.Reflection.Emit.OpCodes.Stsfld, fieldInfo); cg.Emit(System.Reflection.Emit.OpCodes.Ret); return((Action <TField>)m.CreateDelegate(typeof(Action <TField>))); }
private Func <object> GetCtor(Type clr, bool list) { var type = (!list ? ((clr == typeof(object)) ? typeof(Dictionary <string, object>) : clr) : typeof(List <>).MakeGenericType(clr)); var ctor = type.GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.CreateInstance, null, System.Type.EmptyTypes, null); if (ctor != null) { var dyn = new System.Reflection.Emit.DynamicMethod("", typeof(object), null, typeof(string), true); var il = dyn.GetILGenerator(); il.Emit(System.Reflection.Emit.OpCodes.Newobj, ctor); il.Emit(System.Reflection.Emit.OpCodes.Ret); return((Func <object>)dyn.CreateDelegate(typeof(Func <object>))); } return(null); }
static Func <object, int> CreateLengthGetter(Type elementType) { var typedCollection = typeof(ICollection <>).MakeGenericType(elementType); var count = typedCollection.GetProperty("Count").GetMethod; var dyn = new System.Reflection.Emit.DynamicMethod($"{nameof(CollectionLengthLookup)}_{nameof(elementType.Name)}", typeof(int), new[] { typeof(object) }, restrictedSkipVisibility: true); var il = dyn.GetILGenerator(); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // object il.Emit(System.Reflection.Emit.OpCodes.Castclass, typedCollection); // ICollection<elementType> il.Emit(System.Reflection.Emit.OpCodes.Callvirt, count); // int il.Emit(System.Reflection.Emit.OpCodes.Ret); // --empty-- return((Func <object, int>)dyn.CreateDelegate(typeof(Func <object, int>))); }
System.Delegate Compile(TypeContext context, System.Type returnType, System.Type[] types, ParameterInfo[] parameters, System.Type delType) { var names = Parameters.Map(para => para.Name).AddFirst("closure"); // Emit First Argument var lamdaVisit = new LamdaVisitor(names); Body.Accept(lamdaVisit); var parameterTypes = types.AddFirst(typeof(Runtime.Closure)); var method = new System.Reflection.Emit.DynamicMethod(Name, returnType, parameterTypes, true); var methodGen = new Generators.DynamicMethodGenerator(method, parameters, null) { SyntaxBody = Body, Context = context }; methodGen.EmitParameterInfo(); var bodyGen = new MethodBodyGenerator(methodGen, method.GetILGenerator()); object[] values = new object[lamdaVisit.HoistedLocals.Count]; if (values.Length > 0) { int index = 0; var field = typeof(Runtime.Closure).GetField("Values"); foreach (var item in lamdaVisit.HoistedLocals) { var value = item.Value; values[index] = value.Accept(ScriptCompiler.Instance); // if binder is null variable or member may not exist if (value.NodeType == ExpressionType.Identifier && ((NameExpression)value).Binder is null) { continue; } var variable = bodyGen.DeclareVariable(value.Type, item.Key); // load closure argument bodyGen.LoadArgument(0); bodyGen.LoadField(field); bodyGen.LoadInt32(index); bodyGen.LoadArrayElement(typeof(object)); bodyGen.UnboxObject(value.Type); bodyGen.StoreVariable(variable); index++; } } bodyGen.Compile(); return(method.CreateDelegate(delType, new Runtime.Closure(values))); }
/// <summary> /// Generates dynamic method to extract '_object' and '_index' fields from <see cref="ReadOnlyMemory{T}"/> /// </summary> /// <returns>Generated method or null</returns> private static ExtractObjectIndexFromMemoryDelegate TryGenerateExtractObjectIndexFromMemoryMethod() { #if NETSTANDARD return(null); #else if (!CanExtractByteArrayOptimized()) { return(null); } var memoryType = typeof(ReadOnlyMemory <byte>); var objectField = memoryType.GetField("_object", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var indexField = memoryType.GetField("_index", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (objectField == null || indexField == null) { return(null); } try { var method = new System.Reflection.Emit.DynamicMethod("ByteString_ExtractByteArray_" + Guid.NewGuid().ToString("N"), null, new Type[] { typeof(ReadOnlyMemory <byte>).MakeByRefType(), typeof(object).MakeByRefType(), typeof(int).MakeByRefType() }, true); var ilGen = method.GetILGenerator(); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldfld, objectField); ilGen.Emit(System.Reflection.Emit.OpCodes.Stind_Ref); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGen.Emit(System.Reflection.Emit.OpCodes.Ldfld, indexField); ilGen.Emit(System.Reflection.Emit.OpCodes.Stind_I4); ilGen.Emit(System.Reflection.Emit.OpCodes.Ret); return((ExtractObjectIndexFromMemoryDelegate)method.CreateDelegate(typeof(ExtractObjectIndexFromMemoryDelegate))); } catch { return(null); } #endif }
/// <summary> /// Calls the method being constructed by the given emit. Emits so used must have been constructed with BuildMethod or related methods. /// /// Pops its arguments in reverse order (left-most deepest in the stack), and pushes the return value if it is non-void. /// /// If the given method is an instance method, the `this` reference should appear before any parameters. /// /// Call does not respect overrides, the implementation defined by the given MethodInfo is what will be called at runtime. /// /// To call overrides of instance methods, use CallVirtual. /// Recursive calls can only be performed with DynamicMethods, other passed in Emits must already have their methods created. /// When calling VarArgs methods, arglist should be set to the types of the extra parameters to be passed. /// </summary> public Emit Call(Emit emit, Type[] arglist = null) { if (emit == null) { throw new ArgumentNullException("emit"); } MethodInfo methodInfo = emit.InnerEmit.MtdBuilder ?? (MethodInfo)emit.InnerEmit.DynMethod; if (methodInfo == null) { var dynMethod = new System.Reflection.Emit.DynamicMethod(emit.Name, emit.ReturnType, emit.ParameterTypes, emit.Module, skipVisibility: true); emit.InnerEmit.DynMethod = dynMethod; methodInfo = dynMethod; } return Call(methodInfo, arglist); }
private static void Main() { System.Reflection.Emit.DynamicMethod lgcMethod = new System.Reflection.Emit.DynamicMethod("HelloWorld", typeof (void), new Type[] {}, typeof (Program), false); System.Reflection.Emit.ILGenerator il = lgcMethod.GetILGenerator(); il.Emit(OpCodes.Ldstr, "Hello World"); il.Emit(OpCodes.Call, typeof (Console).GetMethod("WriteLine", new[] {typeof (string)})); il.Emit(OpCodes.Call, typeof (Console).GetMethod("ReadLine")); il.Emit(OpCodes.Ret); lgcMethod.Invoke(null, null); }
/// <summary> /// Calls the method being constructed by the given emit. Emits so used must have been constructed with BuildMethod or related methods. /// /// Pops its arguments in reverse order (left-most deepest in the stack), and pushes the return value if it is non-void. /// /// If the given method is an instance method, the `this` reference should appear before any parameters. /// /// Call does not respect overrides, the implementation defined by the given MethodInfo is what will be called at runtime. /// /// To call overrides of instance methods, use CallVirtual. /// Recursive calls can only be performed with DynamicMethods, other passed in Emits must already have their methods created. /// When calling VarArgs methods, arglist should be set to the types of the extra parameters to be passed. /// </summary> public Emit Call(Emit emit, Type[] arglist = null) { if (emit == null) { throw new ArgumentNullException("emit"); } MethodInfo methodInfo = emit.InnerEmit.MtdBuilder ?? (MethodInfo)emit.InnerEmit.DynMethod; if (methodInfo == null) { var dynMethod = new System.Reflection.Emit.DynamicMethod(emit.Name, emit.ReturnType, emit.ParameterTypes, emit.Module, skipVisibility: true); emit.InnerEmit.DynMethod = dynMethod; methodInfo = dynMethod; } return(Call(methodInfo, arglist)); }
static UnsafeArrayReader() { var dyn = new System.Reflection.Emit.DynamicMethod("UnsafeArrayReader_" + typeof(T).Name, null, new[] { typeof(MemoryMappedViewAccessor), typeof(long), typeof(T[]), typeof(int), typeof(int) }); var il = dyn.GetILGenerator(); var readArrayGen = typeof(MemoryMappedViewAccessor).GetMethod("ReadArray"); var readArray = readArrayGen.MakeGenericMethod(typeof(T)); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // MemoryMappedViewAccessor il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // MemoryMappedViewAccessor long il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); // MemoryMappedViewAccessor long T[] il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); // MemoryMappedViewAccessor long T[] int il.Emit(System.Reflection.Emit.OpCodes.Ldarg_S, (byte)4); // MemoryMappedViewAccessor long T[] int int il.Emit(System.Reflection.Emit.OpCodes.Call, readArray); // int il.Emit(System.Reflection.Emit.OpCodes.Pop); // --empty-- il.Emit(System.Reflection.Emit.OpCodes.Ret); // --empty-- Delegate = (Action <MemoryMappedViewAccessor, long, T[], int, int>)dyn.CreateDelegate(typeof(Action <MemoryMappedViewAccessor, long, T[], int, int>)); }
static MemoryUtil() { var dynamicMethod = new System.Reflection.Emit.DynamicMethod ( "MemCpy", typeof(void), new[] { typeof(void *), typeof(void *), typeof(uint) }, typeof(MemoryUtil) ); var ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Cpblk); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); MemCpy = (MemCpyFunction)dynamicMethod.CreateDelegate(typeof(MemCpyFunction)); }
/// <summary> /// <para>以IL方式克隆(复制)该对象</para> /// Generic cloning method that clones an object using IL. /// Only the first call of a certain type will hold back performance. /// After the first call, the compiled IL is executed. /// </summary> /// <typeparam name="T">Type of object to clone</typeparam> /// <param name="myObject">Object to clone</param> /// <returns>Cloned object</returns> public static T CloneByIL <T>(this T myObject) { Delegate myExec = null; if (!_cachedIL.TryGetValue(typeof(T), out myExec)) { // Create ILGenerator System.Reflection.Emit.DynamicMethod dymMethod = new System.Reflection.Emit.DynamicMethod("DoClone", typeof(T), new Type[] { typeof(T) }, true); ConstructorInfo cInfo = myObject.GetType().GetConstructor(new Type[] { }); System.Reflection.Emit.ILGenerator generator = dymMethod.GetILGenerator(); System.Reflection.Emit.LocalBuilder lbf = generator.DeclareLocal(typeof(T)); //lbf.SetLocalSymInfo("_temp"); generator.Emit(System.Reflection.Emit.OpCodes.Newobj, cInfo); generator.Emit(System.Reflection.Emit.OpCodes.Stloc_0); foreach (FieldInfo field in myObject.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)) { // Load the new object on the eval stack... (currently 1 item on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_0); // Load initial object (parameter) (currently 2 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // Replace value by field value (still currently 2 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); // Store the value of the top on the eval stack into the object underneath that value on the value stack. // (0 items on eval stack) generator.Emit(System.Reflection.Emit.OpCodes.Stfld, field); } // Load new constructed obj on eval stack -> 1 item on stack generator.Emit(System.Reflection.Emit.OpCodes.Ldloc_0); // Return constructed object. --> 0 items on stack generator.Emit(System.Reflection.Emit.OpCodes.Ret); myExec = dymMethod.CreateDelegate(typeof(Func <T, T>)); _cachedIL.Add(typeof(T), myExec); } return(((Func <T, T>)myExec)(myObject)); }
public static EmptyCtorDelegate GetConstructorMethodToCache(Type type) { var emptyCtor = type.GetConstructor(Type.EmptyTypes); if (emptyCtor != null) { var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).Module, true); var ilgen = dm.GetILGenerator(); ilgen.Emit(System.Reflection.Emit.OpCodes.Nop); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor); ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); return((EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate))); } #if SILVERLIGHT return(() => Activator.CreateInstance(type)); #else //Anonymous types don't have empty constructors return(() => FormatterServices.GetUninitializedObject(type)); #endif }
public static HarmonyDelegate Clone(MethodInfo source, TranspilerImpl transpiler = null) { var types = new List <Type>(source.GetParameters().Select(p => p.ParameterType)); if (source.IsStatic == false) { types.Insert(0, source.DeclaringType); } var dm = new System.Reflection.Emit.DynamicMethod("", source.ReturnType, types.ToArray()); var copier = new Harmony.ILCopying.MethodCopier(source, dm); copier.AddTranspiler(transpiler); copier.Emit(null); types.Add(source.ReturnType); // Use Expression to create Delegate type var delegateType = System.Linq.Expressions.Expression.GetDelegateType(types.ToArray()); var __delegate = dm.CreateDelegate(delegateType); return(new HarmonyDelegate(__delegate)); }
/// <summary> /// IL创建一个对象 /// </summary> /// <param name="type">需要创建对象的类型</param> /// <returns>对象</returns> public static object ILCreateInstance(Type type) { //ConstructorInfo defaultCtor = type.GetConstructor(new Type[] { }); //System.Reflection.Emit.DynamicMethod dynMethod = new System.Reflection.Emit.DynamicMethod( // name: string.Format("_{0:N}", Guid.NewGuid()), // returnType: type, // parameterTypes: null); //var gen = dynMethod.GetILGenerator(); //gen.Emit(System.Reflection.Emit.OpCodes.Newobj, defaultCtor); //gen.Emit(System.Reflection.Emit.OpCodes.Ret); //return dynMethod.CreateDelegate(typeof(Func<T>)) as Func<T>; System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod(string.Empty, typeof(object), Type.EmptyTypes); var gen = dm.GetILGenerator(); gen.Emit(System.Reflection.Emit.OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); gen.Emit(System.Reflection.Emit.OpCodes.Ret); return((Func <object>)dm.CreateDelegate(typeof(Func <object>))); }
internal static object Creator(this Type type) { if (!DefaultConstructor.ContainsKey(type)) { DefaultConstructor.Add(type, type.GetConstructor(Type.EmptyTypes)); } if (DefaultConstructor[type] != null) { #if NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5 if (CachedConstructor.ContainsKey(type)) { return(CachedConstructor[type].Invoke()); } return(CachedConstructor.GetOrAdd(type, Expression.Lambda <Func <object> >(Expression.New(type)).Compile()).Invoke()); #else if (CachedDynamicMethod.ContainsKey(type)) { return(CachedDynamicMethod[type]()); } var emptyConstructor = DefaultConstructor[type]; var dynamicMethod = new System.Reflection.Emit.DynamicMethod("CreateInstance", type, Type.EmptyTypes, true); System.Reflection.Emit.ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyConstructor); ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret); return(CachedDynamicMethod.GetOrAdd(type, (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator)))()); #endif } else { return(FormatterServices.GetUninitializedObject(type)); } }
private ItemInfo GetItemInfo(Type type, string name, System.Reflection.MethodInfo setter) { var method = new System.Reflection.Emit.DynamicMethod("Set" + name, null, new Type[] { typeof(object), typeof(JsonParser), typeof(int), typeof(int) }, typeof(string), true); var parse = GetParserParse(GetParseName(type)); var il = method.GetILGenerator(); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); il.Emit(System.Reflection.Emit.OpCodes.Callvirt, parse); if (type.IsValueType && (parse.ReturnType == typeof(object))) { il.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, type); } if (parse.ReturnType.IsValueType && (type == typeof(object))) { il.Emit(System.Reflection.Emit.OpCodes.Box, parse.ReturnType); } il.Emit(System.Reflection.Emit.OpCodes.Callvirt, setter); il.Emit(System.Reflection.Emit.OpCodes.Ret); return(new ItemInfo { Type = type, Name = name, Set = (Action <object, JsonParser, int, int>)method.CreateDelegate(typeof(Action <object, JsonParser, int, int>)), Len = name.Length }); }
/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. // Full trust only - skips visibility checks. System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new Type[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. ILGenerator generator; #if __MonoCS__ generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); #else generator = new DynamicILGenerator(dm); #endif // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return((BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate))); }
public static CodeVector makeCodeVector( int controlPointCount, DynamicMethod dm ) { CodeDelegate d = (CodeDelegate) dm.CreateDelegate(typeof(CodeDelegate)); return new DelegateCodeVector( controlPointCount, d ); }
static System.Func<StringTemplate, IStringTemplateWriter, bool> GetEvaluator( ASTExpr chunk, ITree condition ) { if ( EnableDynamicMethods ) { try { DynamicMethod method = null; #if CACHE_FUNCTORS if ( !_methods.TryGetValue( condition, out method ) ) #endif { Type[] parameterTypes = { typeof( ASTExpr ), typeof( StringTemplate ), typeof( IStringTemplateWriter ) }; method = new DynamicMethod( "ConditionEvaluator" + _evaluatorNumber, typeof( bool ), parameterTypes, typeof( ConditionalExpr ), true ); method.DefineParameter( 1, ParameterAttributes.None, "chunk" ); method.DefineParameter( 2, ParameterAttributes.None, "self" ); method.DefineParameter( 3, ParameterAttributes.None, "writer" ); _evaluatorNumber++; var gen = method.GetILGenerator(); ActionEvaluator evalCompiled = new ActionEvaluator( null, chunk, null, condition ); evalCompiled.ifConditionCompiled( gen ); gen.Emit( OpCodes.Ret ); #if CACHE_FUNCTORS _methods[condition] = method; #endif } var dynamicEvaluator = (System.Func<StringTemplate, IStringTemplateWriter, bool>)method.CreateDelegate( typeof( System.Func<StringTemplate, IStringTemplateWriter, bool> ), chunk ); return dynamicEvaluator; } catch { // fall back to functional (or interpreted) version } } if ( EnableFunctionalMethods ) { try { ActionEvaluator evalFunctional = new ActionEvaluator( null, chunk, null, condition ); var functionalEvaluator = evalFunctional.ifConditionFunctional(); HoldsConditionFuncAndChunk holder = new HoldsConditionFuncAndChunk() { func = functionalEvaluator, chunk = chunk }; return (System.Func<StringTemplate, IStringTemplateWriter, bool>)System.Delegate.CreateDelegate( typeof( System.Func<StringTemplate, IStringTemplateWriter, bool> ), holder, typeof( ConditionalExpr ).GetMethod( "CallFunctionalConditionEvaluator" ) ); } catch { // fall back to interpreted version } } return new System.Func<StringTemplate, IStringTemplateWriter, bool>( ( self, @out ) => { ActionEvaluator eval = new ActionEvaluator( self, chunk, @out, condition ); return eval.ifCondition(); } ); }
static Func<StringTemplate, TextReader, Antlr.Runtime.Lexer> BuildLexerCtor( Type lexerType ) { if ( lexerType == null ) return null; Func<StringTemplate, TextReader, Antlr.Runtime.Lexer> result; if ( !_ctors.TryGetValue( lexerType, out result ) ) { ConstructorInfo ctor = lexerType.GetConstructor( new Type[] { typeof( StringTemplate ), typeof( TextReader ) } ); System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod( lexerType.Name + "Ctor", typeof( Antlr.Runtime.Lexer ), new Type[] { typeof( StringTemplate ), typeof( TextReader ) } ); var gen = dm.GetILGenerator(); gen.Emit( System.Reflection.Emit.OpCodes.Ldarg_0 ); gen.Emit( System.Reflection.Emit.OpCodes.Ldarg_1 ); gen.Emit( System.Reflection.Emit.OpCodes.Newobj, ctor ); gen.Emit( System.Reflection.Emit.OpCodes.Ret ); result = (Func<StringTemplate, TextReader, Antlr.Runtime.Lexer>)dm.CreateDelegate( typeof( Func<StringTemplate, TextReader, Antlr.Runtime.Lexer> ) ); _ctors[lexerType] = result; } return result; }
/// <summary> /// Generates IL for the script. /// </summary> public void GenerateCode() { // Generate the abstract syntax tree if it hasn't already been generated. if (this.AbstractSyntaxTree == null) { Parse(); Optimize(); } // Initialize global code-gen information. var optimizationInfo = new OptimizationInfo(this.Engine); optimizationInfo.AbstractSyntaxTree = this.AbstractSyntaxTree; optimizationInfo.StrictMode = this.StrictMode; optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints; ILGenerator generator; if (this.Options.EnableDebugging == false) { // DynamicMethod requires full trust because of generator.LoadMethodPointer in the // FunctionExpression class. // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dynamicMethod; #if !SILVERLIGHT if (ScriptEngine.LowPrivilegeEnvironment == false) { // High privilege path. dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes(), // Parameter types of the generated method. typeof(MethodGenerator), // Owner type. true); // Skip visibility checks. // TODO: Figure out why long methods give BadImageFormatException in .NET 3.5 when generated using DynamicILInfo. if (Environment.Version.Major >= 4) generator = new DynamicILGenerator(dynamicMethod); else generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator()); } else { #endif // Low privilege path. dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes()); // Parameter types of the generated method. generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator()); #if !SILVERLIGHT } #endif if (this.Engine.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } // Generate the IL. GenerateCode(generator, optimizationInfo); generator.Complete(); // Create a delegate from the method. this.GeneratedMethod = new GeneratedMethod(dynamicMethod.CreateDelegate(GetDelegate()), optimizationInfo.NestedFunctions); } else { #if WINDOWS_PHONE throw new NotImplementedException(); #else // Debugging or low trust path. ScriptEngine.ReflectionEmitModuleInfo reflectionEmitInfo = this.Engine.ReflectionEmitInfo; if (reflectionEmitInfo == null) { reflectionEmitInfo = new ScriptEngine.ReflectionEmitModuleInfo(); // Create a dynamic assembly and module. reflectionEmitInfo.AssemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly( new System.Reflection.AssemblyName("Jurassic Dynamic Assembly"), System.Reflection.Emit.AssemblyBuilderAccess.Run); // Mark the assembly as debuggable. This must be done before the module is created. var debuggableAttributeConstructor = typeof(System.Diagnostics.DebuggableAttribute).GetConstructor( new Type[] { typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes) }); reflectionEmitInfo.AssemblyBuilder.SetCustomAttribute( new System.Reflection.Emit.CustomAttributeBuilder(debuggableAttributeConstructor, new object[] { System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations | System.Diagnostics.DebuggableAttribute.DebuggingModes.Default })); // Create a dynamic module. reflectionEmitInfo.ModuleBuilder = reflectionEmitInfo.AssemblyBuilder.DefineDynamicModule("Module", this.Options.EnableDebugging); this.Engine.ReflectionEmitInfo = reflectionEmitInfo; } // Create a new type to hold our method. var typeBuilder = reflectionEmitInfo.ModuleBuilder.DefineType("JavaScriptClass" + reflectionEmitInfo.TypeCount.ToString(), System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class); reflectionEmitInfo.TypeCount++; // Create a method. var methodBuilder = typeBuilder.DefineMethod(this.GetMethodName(), System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public, typeof(object), GetParameterTypes()); // Generate the IL for the method. generator = new ReflectionEmitILGenerator(methodBuilder.GetILGenerator()); if (this.Engine.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } if (this.Source.Path != null && this.Options.EnableDebugging == true) { // Initialize the debugging information. optimizationInfo.DebugDocument = reflectionEmitInfo.ModuleBuilder.DefineDocument(this.Source.Path, COMHelpers.LanguageType, COMHelpers.LanguageVendor, COMHelpers.DocumentType); methodBuilder.DefineParameter(1, System.Reflection.ParameterAttributes.None, "scriptEngine"); methodBuilder.DefineParameter(2, System.Reflection.ParameterAttributes.None, "scope"); methodBuilder.DefineParameter(3, System.Reflection.ParameterAttributes.None, "thisValue"); generator.MarkSequencePoint(optimizationInfo.DebugDocument, new SourceCodeSpan(1, 1, 1, 1)); } GenerateCode(generator, optimizationInfo); generator.Complete(); // Bake it. var type = typeBuilder.CreateType(); var methodInfo = type.GetMethod(this.GetMethodName()); this.GeneratedMethod = new GeneratedMethod(Delegate.CreateDelegate(GetDelegate(), methodInfo), optimizationInfo.NestedFunctions); #endif //WINDOWS_PHONE } if (this.Engine.EnableILAnalysis == true) { // Store the disassembled IL so it can be retrieved for analysis purposes. this.GeneratedMethod.DisassembledIL = generator.ToString(); } }
private DynamicMetaObject/*!*/ FallbackInvokeMember(DynamicMetaObject target/*!*/, DynamicMetaObject/*!*/[]/*!*/ args) { // determine run time values and additional restrictions: DTypeDesc classContext = this._classContext; string fieldName = this._fieldName; BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType); //target.Restrictions; int currentArg = 0; if (!ClassContextIsKnown) { Debug.Assert(args.Length > currentArg, "Not enough arguments!"); Debug.Assert(args[currentArg].Value == null || Types.DTypeDesc[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong class context type!"); classContext = (DTypeDesc)args[currentArg].Value; Debug.Assert(classContext == null || !classContext.IsUnknown, "Class context should be known at run time!"); restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(args[currentArg].Expression, classContext)); currentArg++; } if (IsIndirect) { Debug.Assert(args.Length > currentArg, "Not enough arguments!"); Debug.Assert(Types.String[0].IsAssignableFrom(args[currentArg].LimitType), "Wrong field name type!"); fieldName = (string)args[currentArg].Value; restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Expression.Equal( args[currentArg].Expression, Expression.Constant(fieldName, Types.String[0])))); currentArg++; } // ////Debug.Assert(!(var is PhpReference) && name != null); Debug.Assert(target.HasValue && target.LimitType != Types.PhpReference[0], "Target should not be PhpReference!"); ////if (ReferenceEquals(obj, ScriptContext.SetterChainSingletonObject)) ////{ //// ScriptContext.CurrentContext.AbortSetterChain(false); //// return new PhpReference(); ////} if (WantReference && ReferenceEquals(target.Value, ScriptContext.SetterChainSingletonObject)) { // GetObjectPropertyRef: Func<PhpReference> abortSetterChain = () => { ScriptContext.CurrentContext.AbortSetterChain(false); return new PhpReference(); }; return new DynamicMetaObject( Expression.Call(abortSetterChain.Method), BindingRestrictions.GetInstanceRestriction(target.Expression, ScriptContext.SetterChainSingletonObject) ); } DObject obj; ////// a property of a DObject: if ((obj = target.Value as DObject) != null) { if (obj is ClrObject /*|| obj is IClrValue // IClrValue -> ClrValue<T> -> already in restriction */) { // ((DObject)target).RealType == <obj>.RealType restrictions = restrictions.Merge( BindingRestrictions.GetInstanceRestriction( Expression.Property(Expression.Convert(target.Expression, Types.DObject[0]), Properties.DObject_RealType), obj.RealType)); } //// return GetObjectProperty(obj, name, caller, quiet); DPropertyDesc property; GetMemberResult result = obj.TypeDesc.GetInstanceProperty(new VariableName(fieldName), classContext, out property); switch (result) { case GetMemberResult.OK: ////object value = property.Get(this); ////PhpReference reference = value as PhpReference; if (property.Member is PhpField || property.Member is PhpVisibleProperty) { var realType = property.DeclaringType.RealType; FieldInfo realField = (property.Member is PhpField) ? property.PhpField.RealField : null; PropertyInfo realProperty = (property.Member is PhpVisibleProperty) ? ((PhpVisibleProperty)property.Member).RealProperty : null; Debug.Assert(realField != null ^ realProperty != null); MemberExpression getter = null; if (realField != null) getter = Expression.Field(Expression.Convert(target.Expression, realType), realField); else if (realProperty != null) getter = Expression.Property(Expression.Convert(target.Expression, realType), realProperty); if (Types.PhpReference[0].IsAssignableFrom(getter.Type)) { var reference = Expression.Variable(Types.PhpReference[0]); var assignment = Expression.Assign(reference, getter); if (WantReference) { ////value = property.Get(this); ////reference = value as PhpReference; var returnLabel = Expression.Label(this._returnType); ////if (reference != null && reference.IsSet) ////{ //// reference.IsAliased = true; //// return reference; ////} var isset = Expression.IfThen( Expression.Property(assignment, Properties.PhpReference_IsSet), Expression.Block( Expression.Assign(Expression.Property(reference, Properties.PhpReference_IsAliased), Expression.Constant(true)), Expression.Return(returnLabel, reference))); ////// the CT property has been unset -> try to invoke __get ////PhpReference get_ref = InvokeGetterRef(name, caller, out getter_exists); ////if (getter_exists) return (get_ref == null ? new PhpReference() : get_ref); ////if (reference == null) ////{ //// reference = new PhpReference(value); //// property.Set(this, reference); ////} ////else ////{ //// reference.IsAliased = true; //// reference.IsSet = true; ////} ////return reference; return new DynamicMetaObject( Expression.Block(this._returnType, new[]{reference}, new Expression[]{ isset, Expression.Label(returnLabel, Expression.Call(null, new Func<DObject, string, DTypeDesc, PhpReference, PhpReference>(notsetOperation).Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]), reference)) }), restrictions); } else { ////if (reference != null && !reference.IsSet) ////{ //// // the property is CT but has been unset //// if (issetSemantics) //// { //// bool handled; //// return PropertyIssetHandler(name, caller, out handled); //// } //// else return GetRuntimeField(name, caller); ////} ////else return value; var notsetOperation = _issetSemantics ? (Func<DObject, string, DTypeDesc, object>)GetMemberRuntimeFld : GetMemberIsSet; var value = Expression.Block(this._returnType, new[] { reference }, Expression.Condition( Expression.Property(assignment, Properties.PhpReference_IsSet), Expression.Field(reference, Fields.PhpReference_Value), Expression.Call(null, notsetOperation.Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])) )); return new DynamicMetaObject(value, restrictions); } } else { if (WantReference) { return new DynamicMetaObject( Expression.New(Constructors.PhpReference_Object, Expression.Convert(getter, Types.Object[0])), restrictions); } else { return new DynamicMetaObject( Expression.Call(Methods.PhpVariable.Dereference, Expression.Convert(getter, Types.Object[0])), restrictions); } } } else if (property.Member is ClrProperty) { var realType = property.DeclaringType.RealType; var realProperty = property.ClrProperty.RealProperty; // (target.{RealObject|realValue}).<realProperty> Expression value = Expression.Convert( BinderHelper.ClrObjectWrapDynamic( Expression.Property( BinderHelper.ClrRealObject(target, realType), realProperty)), Types.Object[0]); if (WantReference) value = BinderHelper.MakePhpReference(value); return new DynamicMetaObject(value, restrictions); } else if (property.Member is ClrField) { var realType = property.DeclaringType.RealType; var realField = property.ClrField.FieldInfo; // (target.{RealObject|realValue}).<realField> Expression value = Expression.Convert( BinderHelper.ClrObjectWrapDynamic( Expression.Field( BinderHelper.ClrRealObject(target, realType), realField)), Types.Object[0]); if (WantReference) value = BinderHelper.MakePhpReference(value); return new DynamicMetaObject(value, restrictions); } else if (property.Member is ClrEvent) { var clrEvent = (ClrEvent)property.Member; var realType = property.DeclaringType.RealType; // emit stub that Wraps event as [ ClrEventObject<handlerType>.Wrap(<SC>, <event name>, <addMethod>, <removeMethod>) ] var stub = new System.Reflection.Emit.DynamicMethod( string.Format("event<{0}>",fieldName), Types.DObject[0], new[] { realType }, realType); var il = new ILEmitter(stub); clrEvent.EmitGetEventObject( il, new Place(null, Properties.ScriptContext_CurrentContext), new IndexedPlace(PlaceHolder.Argument, 0), false); il.Emit(System.Reflection.Emit.OpCodes.Ret); Expression value = Expression.Call(stub, BinderHelper.ClrRealObject(target, realType)); if (WantReference) value = BinderHelper.MakePhpReference(value); return new DynamicMetaObject(value, restrictions); } else throw new NotImplementedException(); case GetMemberResult.NotFound: if (WantReference) { return new DynamicMetaObject( Expression.Call(null, new Func<DObject, string, DTypeDesc, PhpReference>(GetRefMemberNotFound).Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0])), restrictions); } else { ////if (issetSemantics) ////{ //// OrderedHashtable<string>.Element element; //// if (RuntimeFields != null && (element = RuntimeFields.GetElement(name)) != null) //// { //// return element.Value; //// } //// else //// { //// bool handled; //// return PropertyIssetHandler(name, caller, out handled); //// } ////} ////else return GetRuntimeField(name, caller); if (_issetSemantics) { return new DynamicMetaObject( Expression.Call(Methods.PhpVariable.Dereference, Expression.Call(null, new Func<DObject, string, DTypeDesc, object>(GetMemberNotFoundIsSet).Method, Expression.Convert(target.Expression, Types.DObject[0]), Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))), restrictions); } else { return new DynamicMetaObject( Expression.Call( Methods.PhpVariable.Dereference, Expression.Call( Expression.Convert(target.Expression, Types.DObject[0]), Methods.DObject_GetRuntimeField, Expression.Constant(fieldName), Expression.Constant(classContext, Types.DTypeDesc[0]))), restrictions); }; } case GetMemberResult.BadVisibility: { ////PhpException.PropertyNotAccessible( //// property.DeclaringType.MakeFullName(), //// name.ToString(), //// (caller == null ? String.Empty : caller.MakeFullName()), //// property.IsProtected); string stringResourceKey = property.IsProtected ? "protected_property_accessed" : "private_property_accessed"; return new DynamicMetaObject( Expression.Block(this._returnType, Expression.Call(null, Methods.PhpException.Throw, Expression.Constant(PhpError.Error, Types.PhpError_String[0]), Expression.Constant(CoreResources.GetString(stringResourceKey, property.DeclaringType.MakeFullName(), fieldName, (classContext == null ? String.Empty : classContext.MakeFullName())))), WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null) ), restrictions); } } } ////// warnings: ////if (!quiet) // not in isset() operator only ////{ if (!_issetSemantics) { //// if (PhpVariable.IsEmpty(var)) //// // empty: //// PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object")); //// else //// // PhpArray, string, scalar type: //// PhpException.VariableMisusedAsObject(var, false); Action<object> error = (var) => { if (PhpVariable.IsEmpty(var)) // empty: PhpException.Throw(PhpError.Notice, CoreResources.GetString("empty_used_as_object")); else // PhpArray, string, scalar type: PhpException.VariableMisusedAsObject(var, false); }; return new DynamicMetaObject( Expression.Block(this._returnType, Expression.Call(error.Method, target.Expression), WantReference ? (Expression)Expression.New(Constructors.PhpReference_Void) : Expression.Constant(null)), (target.HasValue && target.Value == null) ? BindingRestrictions.GetInstanceRestriction(target.Expression, null) : BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)); } ////} ////// property does not exist ////return null; return new DynamicMetaObject( Expression.Constant(null), (target.HasValue && target.Value == null) ? BindingRestrictions.GetInstanceRestriction(target.Expression, null) : BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType)); }
/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. // Full trust only - skips visibility checks. System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new Type[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. ILGenerator generator; #if __MonoCS__ generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); #else generator = new DynamicILGenerator(dm); #endif // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return (BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate)); }
public static EmptyCtorDelegate GetConstructorMethodToCache(Type type) { var emptyCtor = type.GetConstructor(Type.EmptyTypes); if (emptyCtor != null) { var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).Module, true); var ilgen = dm.GetILGenerator(); ilgen.Emit(System.Reflection.Emit.OpCodes.Nop); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor); ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); return (EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate)); } #if SILVERLIGHT return () => Activator.CreateInstance(type); #else //Anonymous types don't have empty constructors return () => FormatterServices.GetUninitializedObject(type); #endif }
private Action<object, object> CreateDispatchDelegate(Type subscriberType, MethodInfo methodInfo) { var dynamicMethod = new System.Reflection.Emit.DynamicMethod( methodInfo.Name, typeof(void), new Type[] { typeof(object), typeof(object) }); var il = dynamicMethod.GetILGenerator(); il.Emit(System.Reflection.Emit.OpCodes.Nop); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); il.Emit(System.Reflection.Emit.OpCodes.Isinst, subscriberType); il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); il.Emit(System.Reflection.Emit.OpCodes.Isinst, methodInfo.GetParameters()[0].ParameterType); il.Emit(System.Reflection.Emit.OpCodes.Callvirt, methodInfo); // TODO avoid il.Emit(System.Reflection.Emit.OpCodes.Nop); il.Emit(System.Reflection.Emit.OpCodes.Ret); var methodDelegate = (Action<object, object>)dynamicMethod.CreateDelegate(typeof(Action<object, object>)); return methodDelegate; }
/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dm; ILGenerator generator; #if !SILVERLIGHT if (ScriptEngine.LowPrivilegeEnvironment == false) { // Full trust only - skips visibility checks. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new Type[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. generator = new DynamicILGenerator(dm); } else { #endif // Partial trust / silverlight. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new Type[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }); // Parameter types of the generated method. generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); #if !SILVERLIGHT } #endif // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return (BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate)); }
public static EmptyCtorDelegate GetConstructorMethodToCache(Type type) { if (type.IsInterface) { if (type.HasGenericType()) { var genericType = type.GetTypeWithGenericTypeDefinitionOfAny( typeof(IDictionary <,>)); if (genericType != null) { var keyType = genericType.GenericTypeArguments()[0]; var valueType = genericType.GenericTypeArguments()[1]; return(GetConstructorMethodToCache(typeof(Dictionary <,>).MakeGenericType(keyType, valueType))); } genericType = type.GetTypeWithGenericTypeDefinitionOfAny( typeof(IEnumerable <>), typeof(ICollection <>), typeof(IList <>)); if (genericType != null) { var elementType = genericType.GenericTypeArguments()[0]; return(GetConstructorMethodToCache(typeof(List <>).MakeGenericType(elementType))); } } } else if (type.IsArray) { return(() => Array.CreateInstance(type.GetElementType(), 0)); } else if (type.IsGenericTypeDefinition) { var genericArgs = type.GetGenericArguments(); var typeArgs = new Type[genericArgs.Length]; for (var i = 0; i < genericArgs.Length; i++) { typeArgs[i] = typeof(object); } var realizedType = type.MakeGenericType(typeArgs); return(realizedType.CreateInstance); } var emptyCtor = type.GetEmptyConstructor(); if (emptyCtor != null) { #if MONOTOUCH || c || XBOX || NETFX_CORE return(() => Activator.CreateInstance(type)); #elif WINDOWS_PHONE return(Expression.Lambda <EmptyCtorDelegate>(Expression.New(type)).Compile()); #else #if SILVERLIGHT var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes); #else var dm = new System.Reflection.Emit.DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(ReflectionExtensions).Module, true); #endif var ilgen = dm.GetILGenerator(); ilgen.Emit(System.Reflection.Emit.OpCodes.Nop); ilgen.Emit(System.Reflection.Emit.OpCodes.Newobj, emptyCtor); ilgen.Emit(System.Reflection.Emit.OpCodes.Ret); return((EmptyCtorDelegate)dm.CreateDelegate(typeof(EmptyCtorDelegate))); #endif } #if (SILVERLIGHT && !WINDOWS_PHONE) || XBOX return(() => Activator.CreateInstance(type)); #elif WINDOWS_PHONE return(Expression.Lambda <EmptyCtorDelegate>(Expression.New(type)).Compile()); #else if (type == typeof(string)) { return(() => String.Empty); } //Anonymous types don't have empty constructors return(() => FormatterServices.GetUninitializedObject(type)); #endif }
/// <summary> /// Creates the IQueryable instance for the given resource set and returns it /// </summary> /// <param name="resourceContainer">resource set for which IQueryable instance needs to be created</param> /// <returns>returns the IQueryable instance for the given resource set</returns> protected override IQueryable GetResourceContainerInstance(ResourceSet resourceContainer) { Debug.Assert(resourceContainer != null, "resourceContainer != null"); if (resourceContainer.ReadFromContextDelegate == null) { PropertyInfo propertyInfo = this.Type.GetProperty(resourceContainer.Name, WebUtil.PublicInstanceBindingFlags); MethodInfo getValueMethod = propertyInfo.GetGetMethod(); // return ((TheContext)arg0).get_Property(); Type[] parameterTypes = new Type[] { typeof(object) }; System.Reflection.Emit.DynamicMethod readerMethod = new System.Reflection.Emit.DynamicMethod("queryable_reader", typeof(IQueryable), parameterTypes, false); var generator = readerMethod.GetILGenerator(); generator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); generator.Emit(System.Reflection.Emit.OpCodes.Castclass, this.Type); generator.Emit(System.Reflection.Emit.OpCodes.Call, getValueMethod); generator.Emit(System.Reflection.Emit.OpCodes.Ret); resourceContainer.ReadFromContextDelegate = (Func<object, IQueryable>)readerMethod.CreateDelegate(typeof(Func<object, IQueryable>)); } Debug.Assert(resourceContainer.ReadFromContextDelegate != null, "resourceContainer.ReadFromContextDelegate != null"); return resourceContainer.ReadFromContextDelegate(this.CurrentDataSource); }
static System.Func <StringTemplate, IStringTemplateWriter, bool> GetEvaluator(ASTExpr chunk, ITree condition) { if (EnableDynamicMethods) { try { DynamicMethod method = null; #if CACHE_FUNCTORS if (!_methods.TryGetValue(condition, out method)) #endif { Type[] parameterTypes = { typeof(ASTExpr), typeof(StringTemplate), typeof(IStringTemplateWriter) }; method = new DynamicMethod("ConditionEvaluator" + _evaluatorNumber, typeof(bool), parameterTypes, typeof(ConditionalExpr), true); #if !NETSTANDARD2_0 method.DefineParameter(1, ParameterAttributes.None, "chunk"); method.DefineParameter(2, ParameterAttributes.None, "self"); method.DefineParameter(3, ParameterAttributes.None, "writer"); #endif _evaluatorNumber++; var gen = method.GetILGenerator(); ActionEvaluator evalCompiled = new ActionEvaluator(null, chunk, null, condition); evalCompiled.ifConditionCompiled(gen); gen.Emit(OpCodes.Ret); #if CACHE_FUNCTORS _methods[condition] = method; #endif } var dynamicEvaluator = (System.Func <StringTemplate, IStringTemplateWriter, bool>)method.CreateDelegate(typeof(System.Func <StringTemplate, IStringTemplateWriter, bool>), chunk); return(dynamicEvaluator); } catch { // fall back to functional (or interpreted) version } } if (EnableFunctionalMethods) { try { ActionEvaluator evalFunctional = new ActionEvaluator(null, chunk, null, condition); var functionalEvaluator = evalFunctional.ifConditionFunctional(); HoldsConditionFuncAndChunk holder = new HoldsConditionFuncAndChunk() { func = functionalEvaluator, chunk = chunk }; return((System.Func <StringTemplate, IStringTemplateWriter, bool>)System.Delegate.CreateDelegate(typeof(System.Func <StringTemplate, IStringTemplateWriter, bool>), holder, typeof(ConditionalExpr).GetMethod("CallFunctionalConditionEvaluator"))); } catch { // fall back to interpreted version } } return(new System.Func <StringTemplate, IStringTemplateWriter, bool>((self, @out) => { ActionEvaluator eval = new ActionEvaluator(self, chunk, @out, condition); return eval.ifCondition(); })); }
/// <summary> /// Creates a new DynamicILGenerator instance. /// </summary> /// <param name="dynamicMethod"> The dynamic method to generate code for. </param> public DynamicILGenerator(System.Reflection.Emit.DynamicMethod dynamicMethod) { if (dynamicMethod == null) throw new ArgumentNullException("dynamicMethod"); this.dynamicMethod = dynamicMethod; this.dynamicILInfo = dynamicMethod.GetDynamicILInfo(); this.bytes = new byte[100]; this.localVariables = new List<DynamicILLocalVariable>(); this.signatureHelper = System.Reflection.Emit.SignatureHelper.GetLocalVarSigHelper(null); this.labels = new List<DynamicILLabel>(); this.fixups = new List<Fixup>(); #if DEBUG this.operands = new Stack<VESType>(); #endif }