Esempio n. 1
0
        /// <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 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
        }
Esempio n. 3
0
        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
        }
Esempio n. 4
0
        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);
        }
        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
            }
        }
Esempio n. 6
0
            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>)));
            }
Esempio n. 7
0
        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>)));
        }
Esempio n. 8
0
        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()));
        }
Esempio n. 9
0
        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>)));
        }
Esempio n. 10
0
            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);
            }
        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)));
        }
Esempio n. 12
0
        /// <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
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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>));
        }
Esempio n. 15
0
        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));
        }
Esempio n. 16
0
        /// <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));
        }
Esempio n. 17
0
        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
        }
Esempio n. 18
0
        /// <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));
            }
        }
Esempio n. 20
0
            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
                });
            }
Esempio n. 21
0
        /// <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)));
        }
Esempio n. 22
0
        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;
        }
Esempio n. 23
0
        static EnumMapper()
        {
            var dyn = new System.Reflection.Emit.DynamicMethod("Map_Enum_" + typeof(T).Name, typeof(T), new[] { typeof(int) }, restrictedSkipVisibility: true);
            var il  = dyn.GetILGenerator();

            var underlying = Enum.GetUnderlyingType(typeof(T));

            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);            // ---int---
            if (underlying == typeof(byte))
            {
                il.Emit(System.Reflection.Emit.OpCodes.Conv_U1);
            }
            else
            {
                if (underlying == typeof(sbyte))
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Conv_I1);
                }
                else
                {
                    if (underlying == typeof(short))
                    {
                        il.Emit(System.Reflection.Emit.OpCodes.Conv_I2);
                    }
                    else
                    {
                        if (underlying == typeof(ushort))
                        {
                            il.Emit(System.Reflection.Emit.OpCodes.Conv_U2);
                        }
                        else
                        {
                            if (underlying == typeof(int))
                            {
                                // Nothing to be done
                            }
                            else
                            {
                                if (underlying == typeof(uint))
                                {
                                    il.Emit(System.Reflection.Emit.OpCodes.Conv_U4);
                                }
                                else
                                {
                                    if (underlying == typeof(long))
                                    {
                                        il.Emit(System.Reflection.Emit.OpCodes.Conv_I8);
                                    }
                                    else
                                    {
                                        if (underlying == typeof(ulong))
                                        {
                                            il.Emit(System.Reflection.Emit.OpCodes.Conv_U8);
                                        }
                                        else
                                        {
                                            throw new InvalidOperationException($"\"Impossible\" (don't get cute) enum found, underlying type isn't an integral type {typeof(T).Name}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            il.Emit(System.Reflection.Emit.OpCodes.Ret);

            Delegate = (Func <int, T>)dyn.CreateDelegate(typeof(Func <int, T>));
        }
Esempio n. 24
0
        /// <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();

            optimizationInfo.AbstractSyntaxTree      = this.AbstractSyntaxTree;
            optimizationInfo.StrictMode              = this.StrictMode;
            optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints;
            optimizationInfo.FunctionName            = this.GetStackName();
            optimizationInfo.Source = this.Source;

            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 = 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.
#if USE_DYNAMIC_IL_INFO
                generator = new DynamicILGenerator(dynamicMethod);
#else
                generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator(), emitDebugInfo: false);
#endif

                if (this.Options.EnableILAnalysis == true)
                {
                    // Replace the generator with one that logs.
                    generator = new LoggingILGenerator(generator);
                }

                // Initialization code will appear to come from line 1.
                optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1));

                // 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 ENABLE_DEBUGGING
                // Debugging or low trust path.
                ReflectionEmitModuleInfo           reflectionEmitInfo;
                System.Reflection.Emit.TypeBuilder typeBuilder;
                lock (reflectionEmitInfoLock)
                {
                    reflectionEmitInfo = ReflectionEmitInfo;
                    if (reflectionEmitInfo == null)
                    {
                        reflectionEmitInfo = new 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);

                        ReflectionEmitInfo = reflectionEmitInfo;
                    }

                    // Create a new type to hold our method.
                    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(), emitDebugInfo: true);

                if (this.Options.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, LanguageType, LanguageVendor, DocumentType);
                    var parameterNames = GetParameterNames();
                    for (var i = 0; i < parameterNames.Length; i++)
                    {
                        methodBuilder.DefineParameter(i + 1, System.Reflection.ParameterAttributes.In, parameterNames[i]);
                    }
                }
                optimizationInfo.MarkSequencePoint(generator, 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);
#else
                throw new NotImplementedException();
#endif // ENABLE_DEBUGGING
            }

            if (this.Options.EnableILAnalysis == true)
            {
                // Store the disassembled IL so it can be retrieved for analysis purposes.
                this.GeneratedMethod.DisassembledIL = generator.ToString();
            }
        }
        //todo working on scope for better emit
        public System.Delegate Compile(System.Type target, IExpressionVisitor <object> visitor)
        {
            //pass scoped arguments // refer System.Linq.Expression.Compiler folder
            var context = TypeContext.Default;

            System.Type returnType;
            if (ReturnSyntax != null)
            {
                returnType = ReturnSyntax.ResolveType(context);
            }
            else
            {
                returnType = TypeProvider.AnyType;
            }
            var names  = Parameters.Map(para => para.Name).AddFirst("closure");
            int length = Parameters.Count;

            System.Type[] types      = new System.Type[length];
            var           parameters = new ParameterInfo[length];

            for (int i = 0; i < Parameters.Count; i++)
            {
                var         para = Parameters[i];
                System.Type type = para.Type == null ? TypeProvider.AnyType : para.Type.ResolveType(context);
                parameters[i] = new ParameterInfo(para.Name, i + 1, type, para.IsVarArgs);
                types[i]      = type;
            }
            // Emit First Argument
            var lamdaVisit = new LamdaVisitor(names);

            Body.Accept(lamdaVisit);
            var parameterTypes = types.AddFirst(typeof(Closure));
            var method         = new System.Reflection.Emit.DynamicMethod("lambda_method", returnType, parameterTypes, true);

            var methodGen = new Generators.DynamicMethodGenerator(method, parameters, target)
            {
                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(Closure).GetField("Values");
                foreach (var item in lamdaVisit.HoistedLocals)
                {
                    var value = item.Value;
                    values[index] = value.Accept(visitor);
                    var variable = bodyGen.DeclareVariable(value.Type, item.Key);
                    bodyGen.LoadArgument(0);
                    bodyGen.LoadField(field);
                    bodyGen.LoadInt32(index);
                    bodyGen.LoadArrayElement(typeof(object));
                    bodyGen.UnboxObject(value.Type);
                    bodyGen.StoreVariable(variable);
                    index++;
                }
            }
            bodyGen.Compile();
            var delgateType = DelegateGen.MakeNewDelegate(types, returnType);

            Type = delgateType;
            return(method.CreateDelegate(delgateType, new Runtime.Closure(values)));
        }
Esempio n. 26
0
        /// <summary>
        /// Registers the type to library. This must be done for all types.
        /// </summary>
        /// <param name="module">The module base address where this type is in. If zero then it's current process main module.</param>
        /// <param name="interfaceType">Type of the interface.</param>
        /// <param name="implementationType">Type of the implementation.</param>
        /// <param name="vtable">The virtual function table address.</param>
        /// <param name="offsetInFullType">The offset of this vtable in full type.</param>
        /// <exception cref="System.ArgumentNullException">
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// </exception>
        internal void RegisterType(IntPtr module, Type interfaceType, Type implementationType, IntPtr?vtable, int offsetInFullType)
        {
            if (module == IntPtr.Zero)
            {
                module = Main.GetMainTargetedModule().BaseAddress;
            }
            if (interfaceType == null)
            {
                throw new ArgumentNullException("interfaceType");
            }
            if (implementationType == null)
            {
                throw new ArgumentNullException("implementationType");
            }
            if (!interfaceType.IsInterface)
            {
                throw new ArgumentException("Interface type must be an interface!", "interfaceType");
            }
            if (interfaceType != typeof(IMemoryObject) && !typeof(IMemoryObject).IsAssignableFrom(interfaceType))
            {
                throw new ArgumentException("Interface type must inherit from IMemoryObject interface!", "interfaceType");
            }
            if (implementationType != typeof(MemoryObject) && !implementationType.IsSubclassOf(typeof(MemoryObject)))
            {
                throw new ArgumentException("Implementation type must inherit from MemoryObject!", "implementationType");
            }
            if (implementationType.IsAbstract)
            {
                throw new ArgumentException("Implementation type must not be abstract!", "implementationType");
            }
            if (!interfaceType.IsAssignableFrom(implementationType))
            {
                throw new ArgumentException("Interface type must be assignable from implementation! The implementation is `" + implementationType.Name + "` and interface is `" + interfaceType.Name + "`.");
            }
            if (offsetInFullType < 0)
            {
                throw new ArgumentOutOfRangeException("offsetInFullType");
            }

            // This is actually normal and should be allowed!
            //if (offsetInFullType > 0 && !vtable.HasValue) throw new ArgumentException("Can't set offset in full type without setting vtable address! The implementation is `" + implementationType.Name + "` and interface is `" + interfaceType.Name + "`.");

            TypeDescriptor t = null;

            ConstructorInfo ci = null;

            {
                var cis = implementationType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(q => !q.IsStatic && q.GetParameters().Length == 0).ToList();
                if (cis.Count != 1)
                {
                    throw new ArgumentException("A valid parameterless constructor was not found on type \"" + implementationType.Name + "\"!");
                }
                ci = cis[0];
            }

            t = new TypeDescriptor();
            t.InterfaceType      = interfaceType;
            t.ImplementationType = implementationType;
            t.VTable             = vtable;
            t.OffsetInFullType   = offsetInFullType;
            t.Module             = module;

            var builder   = new System.Reflection.Emit.DynamicMethod("Creator", typeof(MemoryObject), new Type[0], true);
            var generator = builder.GetILGenerator();

            generator.Emit(System.Reflection.Emit.OpCodes.Newobj, ci);
            generator.Emit(System.Reflection.Emit.OpCodes.Ret);
            t.Creator = (TypeDescriptor.CreatorDelegate)builder.CreateDelegate(typeof(TypeDescriptor.CreatorDelegate));

            List <TypeDescriptor> ls = null;

            if (!this.Types.TypesByImplementation.TryGetValue(t.ImplementationType, out ls))
            {
                ls = new List <TypeDescriptor>(2);
                this.Types.TypesByImplementation[t.ImplementationType] = ls;
            }
            ls.Add(t);

            this.Types.All.Add(t);

            if (vtable.HasValue)
            {
                if (this.Types.TypesByVTable.ContainsKey(vtable.Value))
                {
                    throw new ArgumentException("Multiple type registrations with same vtable address! (" + t.InterfaceType.Name + ")");
                }
                this.Types.TypesByVTable[vtable.Value] = t;
                this.Types.TypesWithVTable.Add(t.InterfaceType);
            }
            else
            {
                if (this.Types.TypesByNoVTable.ContainsKey(t.InterfaceType))
                {
                    throw new ArgumentException("Multiple type registrations with same interface type and without vtable address! (" + t.InterfaceType.Name + ")");
                }
                this.Types.TypesByNoVTable[t.InterfaceType] = t;
            }
        }
Esempio n. 27
0
        /// <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();
            }
        }
        /// <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;
            optimizationInfo.FunctionName            = this.GetStackName();
            optimizationInfo.Source = this.Source;

            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);
                }

                // Initialization code will appear to come from line 1.
                optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1));

                // 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");
                }
                optimizationInfo.MarkSequencePoint(generator, 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();
            }
        }
        public static EmptyCtorDelegate GetConstructorMethodToCache(Type type)
        {
            if (type == typeof(string))
            {
                return(() => string.Empty);
            }
            else if (type.IsInterface)
            {
                if (type.HasGenericType())
                {
                    var genericType = type.GetTypeWithGenericTypeDefinitionOfAny(
                        typeof(IDictionary <,>));

                    if (genericType != null)
                    {
                        var keyType   = genericType.GetGenericArguments()[0];
                        var valueType = genericType.GetGenericArguments()[1];
                        return(GetConstructorMethodToCache(typeof(Dictionary <,>).MakeGenericType(keyType, valueType)));
                    }

                    genericType = type.GetTypeWithGenericTypeDefinitionOfAny(
                        typeof(IEnumerable <>),
                        typeof(ICollection <>),
                        typeof(IList <>));

                    if (genericType != null)
                    {
                        var elementType = genericType.GetGenericArguments()[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.GetConstructor(Type.EmptyTypes);

            if (emptyCtor != null)
            {
                if (PclExport.Instance.SupportsEmit)
                {
                    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)));
                }

                return(() => Activator.CreateInstance(type));
            }

            // Anonymous types don't have empty constructors
            return(() => FormatterServices.GetUninitializedObject(type));
        }
Esempio n. 30
0
        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();
            } );
        }
Esempio n. 31
0
        /// <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);
        }
Esempio n. 32
0
            private ItemInfo GetItemInfo(Type type, Type key, Type value, System.Reflection.MethodInfo setter)
            {
                var method = new System.Reflection.Emit.DynamicMethod("Add", null, new Type[] { typeof(object), typeof(JsonParser), typeof(int), typeof(int) }, typeof(string), true);
                var sBrace = typeof(JsonParser).GetMethod("SBrace", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                var eBrace = typeof(JsonParser).GetMethod("EBrace", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                var kColon = typeof(JsonParser).GetMethod("KColon", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                var sComma = typeof(JsonParser).GetMethod("SComma", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                var vParse = GetParserParse(GetParseName(value));
                var kParse = GetParserParse(GetParseName(key));
                var il     = method.GetILGenerator();

                il.DeclareLocal(key);
                il.DeclareLocal(value);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, sBrace);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, kColon);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, kParse);
                if (key.IsValueType && (kParse.ReturnType == typeof(object)))
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, key);
                }
                if (kParse.ReturnType.IsValueType && (key == typeof(object)))
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Box, kParse.ReturnType);
                }
                il.Emit(System.Reflection.Emit.OpCodes.Stloc_0);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, sComma);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, kColon);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, vParse);
                if (value.IsValueType && (vParse.ReturnType == typeof(object)))
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, value);
                }
                if (vParse.ReturnType.IsValueType && (value == typeof(object)))
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Box, vParse.ReturnType);
                }
                il.Emit(System.Reflection.Emit.OpCodes.Stloc_1);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, eBrace);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
                il.Emit(System.Reflection.Emit.OpCodes.Ldloc_0);
                il.Emit(System.Reflection.Emit.OpCodes.Ldloc_1);
                il.Emit(System.Reflection.Emit.OpCodes.Callvirt, setter);
                il.Emit(System.Reflection.Emit.OpCodes.Ret);
                return(new ItemInfo {
                    Type = type, Name = String.Empty, Set = (Action <object, JsonParser, int, int>)method.CreateDelegate(typeof(Action <object, JsonParser, int, int>))
                });
            }
Esempio n. 33
0
        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;
        }
Esempio n. 34
0
        /// <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));
        }
Esempio n. 35
0
        /// <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
        }
        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
        }
Esempio n. 38
0
        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();
            }));
        }
        internal static object Creator(this Type type, bool validateArgs = true, params object[] parameters)
        {
            try
            {
                var key         = type.FullName + string.Join("", parameters?.Select(x => x.GetType().FullName));
                var constructor = type.GetConstructorInfo(parameters ?? new object[0]);
                if (constructor == null && parameters?.Length > 0)
                {
                    constructor = type.GetConstructorInfo(new object[0]);
                }
                if (constructor != null)
                {
                    var constParam = constructor.GetParameters();
                    if (validateArgs && (parameters?.Any() ?? false))
                    {
                        for (var i = 0; i < parameters.Length; i++)
                        {
                            if (constParam.Length <= i)
                            {
                                continue;
                            }
                            if (constParam[i].ParameterType != parameters[i].GetType())
                            {
                                try
                                {
                                    parameters[i] = Convert.ChangeType(parameters[i], constParam[i].ParameterType);
                                }
                                catch
                                {
                                    // Ignore
                                }
                            }
                        }
                    }

#if NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5
                    if (!constParam.Any())
                    {
                        if (CachedConstructor.ContainsKey(key))
                        {
                            return(CachedConstructor[key]());
                        }
                    }
                    else if (CachedConstructorWithParameter.ContainsKey(key))
                    {
                        return(CachedConstructorWithParameter[key](parameters));
                    }

                    if (!(parameters?.Any() ?? false))
                    {
                        return(CachedConstructor.GetOrAdd(key, Expression.Lambda <Func <object> >(Expression.New(type)).Compile())());
                    }
                    else
                    {
                        // Create a single param of type object[].
                        ParameterExpression param = Expression.Parameter(typeof(object[]), "args");

                        // Pick each arg from the params array and create a typed expression of them.
                        Expression[] argsExpressions = new Expression[constParam.Length];

                        for (int i = 0; i < constParam.Length; i++)
                        {
                            Expression index            = Expression.Constant(i);
                            Type       paramType        = constParam[i].ParameterType;
                            Expression paramAccessorExp = Expression.ArrayIndex(param, index);
                            Expression paramCastExp     = Expression.Convert(paramAccessorExp, paramType);
                            argsExpressions[i] = paramCastExp;
                        }


                        return(CachedConstructorWithParameter.GetOrAdd(key, Expression.Lambda <Func <object[], object> >(Expression.New(constructor, argsExpressions), param).Compile())(parameters));
                    }
#else
                    if (!constParam.Any())
                    {
                        if (CachedDynamicMethod.ContainsKey(key))
                        {
                            return(CachedDynamicMethod[key]());
                        }
                    }
                    else if (CachedDynamicMethodWithParameters.ContainsKey(key))
                    {
                        return(CachedDynamicMethodWithParameters[key](parameters));
                    }

                    lock (CachedDynamicMethod)
                    {
                        var dynamicMethod = new System.Reflection.Emit.DynamicMethod("CreateInstance", type, (constParam.Any() ? new Type[] { typeof(object[]) } : Type.EmptyTypes), true);
                        System.Reflection.Emit.ILGenerator ilGenerator = dynamicMethod.GetILGenerator();


                        if (constructor.GetParameters().Any())
                        {
                            for (int i = 0; i < constParam.Length; i++)
                            {
                                Type paramType = constParam[i].ParameterType;
                                ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);    // Push array (method argument)
                                ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);  // Push i
                                ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref); // Pop array and i and push array[i]
                                if (paramType.IsValueType)
                                {
                                    ilGenerator.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, paramType); // Cast to Type t
                                }
                                else
                                {
                                    ilGenerator.Emit(System.Reflection.Emit.OpCodes.Castclass, paramType); //Cast to Type t
                                }
                            }
                        }


                        //ilGenerator.Emit(System.Reflection.Emit.OpCodes.Nop);
                        ilGenerator.Emit(System.Reflection.Emit.OpCodes.Newobj, constructor);
                        //ilGenerator.Emit(System.Reflection.Emit.OpCodes.Stloc_1); // nothing
                        ilGenerator.Emit(System.Reflection.Emit.OpCodes.Ret);

                        if (!constParam.Any())
                        {
                            return(CachedDynamicMethod.GetOrAdd(key, (ObjectActivator)dynamicMethod.CreateDelegate(typeof(ObjectActivator)))());
                        }
                        else
                        {
                            return(CachedDynamicMethodWithParameters.GetOrAdd(key, (ObjectActivatorWithParameters)dynamicMethod.CreateDelegate(typeof(ObjectActivatorWithParameters)))(parameters));
                        }
                    }
#endif
                }
                else
                {
#if !NETSTANDARD1_3
                    return(FormatterServices.GetUninitializedObject(type));
#else
                    try
                    {
                        if (CachedConstructor.ContainsKey(key))
                        {
                            return(CachedConstructor[key]());
                        }
                        return(CachedConstructor.GetOrAdd(key, Expression.Lambda <Func <object> >(Expression.New(type)).Compile())());
                    }
                    catch
                    {
                        throw new Exception("DeepClonerError: Default constructor is require for NETSTANDARD1_3 for type " + type.FullName);
                    }
#endif
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }