Exemple #1
0
        public static void EmitArrayStore(FleeILGenerator ilg, Type elementType)
        {
            TypeCode tc = Type.GetTypeCode(elementType);

            switch (tc)
            {
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Boolean:
                ilg.Emit(OpCodes.Stelem_I1);
                break;

            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Char:
                ilg.Emit(OpCodes.Stelem_I2);
                break;

            case TypeCode.Int32:
            case TypeCode.UInt32:
                ilg.Emit(OpCodes.Stelem_I4);
                break;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                ilg.Emit(OpCodes.Stelem_I8);
                break;

            case TypeCode.Single:
                ilg.Emit(OpCodes.Stelem_R4);
                break;

            case TypeCode.Double:
                ilg.Emit(OpCodes.Stelem_R8);
                break;

            case TypeCode.Object:
                // TimeSpan EmitArrayStore bugfix. TimeSpan TypeCode returns Object but Emit(OpCodes.Stelem, elementType) must be called
                if (elementType == typeof(TimeSpan))
                {
                    ilg.Emit(OpCodes.Stelem, elementType);
                }
                else
                {
                    ilg.Emit(OpCodes.Stelem_Ref);
                }

                break;

            case TypeCode.String:
                ilg.Emit(OpCodes.Stelem_Ref);
                break;

            default:
                // Must be a non-primitive value type
                ilg.Emit(OpCodes.Stelem, elementType);
                break;
            }
        }
Exemple #2
0
        /// <summary>
        /// Add a branch from a location to a target label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void AddBranch(FleeILGenerator ilg, Label target)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);

            BranchInfo bi = new BranchInfo(startLoc, target);

            MyBranchInfos.Add(bi);
        }
        /// <summary>
        /// Add a branch from a location to a target label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void AddBranch(FleeILGenerator ilg, Label target)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);

            BranchInfo bi = new BranchInfo(startLoc, target);

            // branches will be sorted in order
            MyBranchInfos.Add(bi);
        }
Exemple #4
0
        /// <summary>
        /// Set the position for a label
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <remarks></remarks>
        public void MarkLabel(FleeILGenerator ilg, Label target)
        {
            int pos = ilg.Length;

            foreach (BranchInfo bi in MyBranchInfos)
            {
                bi.Mark(target, pos);
            }
        }
Exemple #5
0
        public static void EmitArrayLoad(FleeILGenerator ilg, Type elementType)
        {
            TypeCode tc = Type.GetTypeCode(elementType);

            switch (tc)
            {
            case TypeCode.Byte:
                ilg.Emit(OpCodes.Ldelem_U1);
                break;

            case TypeCode.SByte:
            case TypeCode.Boolean:
                ilg.Emit(OpCodes.Ldelem_I1);
                break;

            case TypeCode.Int16:
                ilg.Emit(OpCodes.Ldelem_I2);
                break;

            case TypeCode.UInt16:
                ilg.Emit(OpCodes.Ldelem_U2);
                break;

            case TypeCode.Int32:
                ilg.Emit(OpCodes.Ldelem_I4);
                break;

            case TypeCode.UInt32:
                ilg.Emit(OpCodes.Ldelem_U4);
                break;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                ilg.Emit(OpCodes.Ldelem_I8);
                break;

            case TypeCode.Single:
                ilg.Emit(OpCodes.Ldelem_R4);
                break;

            case TypeCode.Double:
                ilg.Emit(OpCodes.Ldelem_R8);
                break;

            case TypeCode.Object:
            case TypeCode.String:
                ilg.Emit(OpCodes.Ldelem_Ref);
                break;

            default:
                // Must be a non-primitive value type
                ilg.Emit(OpCodes.Ldelema, elementType);
                ilg.Emit(OpCodes.Ldobj, elementType);
                return;
            }
        }
Exemple #6
0
        /// <summary>
        /// Get a label by a key.  Create the label if it is not present.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="ilg"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public Label GetLabel(object key, FleeILGenerator ilg)
        {
            Label lbl;

            if (MyKeyLabelMap.TryGetValue(key, out lbl) == false)
            {
                lbl = ilg.DefineLabel();
                MyKeyLabelMap.Add(key, lbl);
            }
            return(lbl);
        }
Exemple #7
0
        /// <summary>
        /// Determine if a branch from a point to a label will be long
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool IsLongBranch(FleeILGenerator ilg, Label target)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);
            BranchInfo bi       = new BranchInfo(startLoc, target);

            int index = MyBranchInfos.IndexOf(bi);

            bi = MyBranchInfos[index];

            return(bi.IsLongBranch);
        }
Exemple #8
0
        public static void EmitLoadLocalAddress(FleeILGenerator ilg, int index)
        {
            Debug.Assert(index >= 0, "Invalid index");

            if (index <= byte.MaxValue)
            {
                ilg.Emit(OpCodes.Ldloca_S, Convert.ToByte(index));
            }
            else
            {
                ilg.Emit(OpCodes.Ldloca, index);
            }
        }
        private static bool ImplicitConvertToUInt16(TypeCode sourceTypeCode, FleeILGenerator ilg)
        {
            switch (sourceTypeCode)
            {
            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.UInt16:
                return(true);

            default:
                return(false);
            }
        }
Exemple #10
0
        /// <summary>
        /// Determine if a branch from a point to a label will be long
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool IsLongBranch(FleeILGenerator ilg, Label target)
        {
            //return true;
            ILLocation startLoc = new ILLocation(ilg.Length);
            BranchInfo bi       = new BranchInfo(startLoc, target);

            int index = MyBranchInfos.IndexOf(bi);

            if (index > -1 && index < MyBranchInfos.Count)
            {
                bi = MyBranchInfos[index];
            }

            return(bi.IsLongBranch);
        }
Exemple #11
0
        /// <summary>
        /// Determine if a branch from a point to a label will be long
        /// </summary>
        /// <param name="ilg"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool IsLongBranch(FleeILGenerator ilg)
        {
            ILLocation startLoc = new ILLocation(ilg.Length);

            foreach (var bi in MyBranchInfos)
            {
                if (bi.Equals(startLoc))
                {
                    return(bi.IsLongBranch);
                }
            }

            // we don't really know since this branch didn't exist.
            // we could throw an exceptio but
            // do a long branch to be safe.
            return(true);
        }
Exemple #12
0
        /// <summary>
        /// Determine if a branch from a point to a label will be long
        /// </summary>
        /// <param name="ilg"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool IsLongBranch(FleeILGenerator ilg, Label target)
        {
            //return true;
            ILLocation startLoc = new ILLocation(ilg.Length);
            BranchInfo bi       = new BranchInfo(startLoc, target);

            int index = MyBranchInfos.IndexOf(bi);

            if (index > -1 && index < MyBranchInfos.Count)
            {
                bi = MyBranchInfos[index];
                return(bi.IsLongBranch);
            }
            else
            {
                return(true);                // temp fix: not sure why, but MyBranchInfos seems to be missing elements when executing long scripts
            }
        }
 public static bool EmitImplicitConvert(Type sourceType, Type destType, FleeILGenerator ilg)
 {
     if (object.ReferenceEquals(sourceType, destType))
     {
         return(true);
     }
     else if (EmitOverloadedImplicitConvert(sourceType, destType, ilg) == true)
     {
         return(true);
     }
     else if (ImplicitConvertToReferenceType(sourceType, destType, ilg) == true)
     {
         return(true);
     }
     else
     {
         return(ImplicitConvertToValueType(sourceType, destType, ilg));
     }
 }
Exemple #14
0
        private void Compile(string expression, ExpressionOptions options)
        {
            // Add the services that will be used by elements during the compile
            IServiceContainer services = new ServiceContainer();

            this.AddServices(services);

            // Parse and get the root element of the parse tree
            ExpressionElement topElement = _myContext.Parse(expression, services);

            if (options.ResultType == null)
            {
                options.ResultType = topElement.ResultType;
            }

            RootExpressionElement rootElement = new RootExpressionElement(topElement, options.ResultType);

            DynamicMethod dm = this.CreateDynamicMethod();

            FleeILGenerator ilg = new FleeILGenerator(dm.GetILGenerator());

            // Emit the IL
            rootElement.Emit(ilg, services);
            if (ilg.NeedsSecondPass())
            {
                // second pass required due to long branches.
                dm = this.CreateDynamicMethod();
                ilg.PrepareSecondPass(dm.GetILGenerator());
                rootElement.Emit(ilg, services);
            }

            ilg.ValidateLength();

            // Emit to an assembly if required
            if (options.EmitToAssembly == true)
            {
                EmitToAssembly(ilg, rootElement, services);
            }

            Type delegateType = typeof(ExpressionEvaluator <>).MakeGenericType(typeof(T));

            _myEvaluator = (ExpressionEvaluator <T>)dm.CreateDelegate(delegateType);
        }
        private static bool ImplicitConvertToUInt64(TypeCode sourceTypeCode, FleeILGenerator ilg)
        {
            switch (sourceTypeCode)
            {
            case TypeCode.Char:
            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
                EmitConvert(ilg, OpCodes.Conv_U8);
                break;

            case TypeCode.UInt64:
                break;

            default:
                return(false);
            }

            return(true);
        }
Exemple #16
0
        private static void EmitToAssembly(ExpressionElement rootElement, IServiceContainer services)
        {
            AssemblyName assemblyName = new AssemblyName(EmitAssemblyName);

            string assemblyFileName = string.Format("{0}.dll", EmitAssemblyName);

            AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(assemblyFileName);

            MethodBuilder mb = moduleBuilder.DefineGlobalMethod("Evaluate", MethodAttributes.Public | MethodAttributes.Static, typeof(T), new Type[] {
                typeof(object), typeof(ExpressionContext), typeof(VariableCollection)
            });
            FleeILGenerator ilg = new FleeILGenerator(mb.GetILGenerator());

            rootElement.Emit(ilg, services);

            moduleBuilder.CreateGlobalFunctions();
            //assemblyBuilder.Save(assemblyFileName);
            assemblyBuilder.CreateInstance(assemblyFileName);
        }
Exemple #17
0
 public override void Emit(FleeILGenerator ilg, IServiceProvider services)
 {
     Utility.EmitLoadLocal(ilg, _myIndex);
 }
        /// <summary>
        ///Emit an implicit conversion (if the ilg is not null) and returns a value that determines whether the implicit conversion
        /// succeeded
        /// </summary>
        /// <param name="sourceType"></param>
        /// <param name="destType"></param>
        /// <param name="ilg"></param>
        /// <returns></returns>
        public static bool EmitImplicitNumericConvert(Type sourceType, Type destType, FleeILGenerator ilg)
        {
            TypeCode sourceTypeCode = Type.GetTypeCode(sourceType);
            TypeCode destTypeCode   = Type.GetTypeCode(destType);

            switch (destTypeCode)
            {
            case TypeCode.Int16:
                return(ImplicitConvertToInt16(sourceTypeCode, ilg));

            case TypeCode.UInt16:
                return(ImplicitConvertToUInt16(sourceTypeCode, ilg));

            case TypeCode.Int32:
                return(ImplicitConvertToInt32(sourceTypeCode, ilg));

            case TypeCode.UInt32:
                return(ImplicitConvertToUInt32(sourceTypeCode, ilg));

            case TypeCode.Double:
                return(ImplicitConvertToDouble(sourceTypeCode, ilg));

            case TypeCode.Single:
                return(ImplicitConvertToSingle(sourceTypeCode, ilg));

            case TypeCode.Int64:
                return(ImplicitConvertToInt64(sourceTypeCode, ilg));

            case TypeCode.UInt64:
                return(ImplicitConvertToUInt64(sourceTypeCode, ilg));

            default:
                return(false);
            }
        }
        private static bool ImplicitConvertToValueType(Type sourceType, Type destType, FleeILGenerator ilg)
        {
            // We only handle value types
            if (sourceType.IsValueType == false & destType.IsValueType == false)
            {
                return(false);
            }

            // No implicit conversion to enum.  Have to do this check here since calling GetTypeCode on an enum will return the typecode
            // of the underlying type which screws us up.
            if (sourceType.IsEnum == true | destType.IsEnum == true)
            {
                return(false);
            }

            return(EmitImplicitNumericConvert(sourceType, destType, ilg));
        }
        private static bool ImplicitConvertToReferenceType(Type sourceType, Type destType, FleeILGenerator ilg)
        {
            if (destType.IsValueType == true)
            {
                return(false);
            }

            if (object.ReferenceEquals(sourceType, typeof(Null)))
            {
                // Null is always convertible to a reference type
                return(true);
            }

            if (destType.IsAssignableFrom(sourceType) == false)
            {
                return(false);
            }

            if (sourceType.IsValueType == true)
            {
                if ((ilg != null))
                {
                    ilg.Emit(OpCodes.Box, sourceType);
                }
            }

            return(true);
        }
        private static bool EmitOverloadedImplicitConvert(Type sourceType, Type destType, FleeILGenerator ilg)
        {
            // Look for an implicit operator on the destination type
            MethodInfo mi = Utility.GetSimpleOverloadedOperator("Implicit", sourceType, destType);

            if (mi == null)
            {
                // No match
                return(false);
            }

            if ((ilg != null))
            {
                ilg.Emit(OpCodes.Call, mi);
            }

            return(true);
        }