internal static Type EmitExpression(Expression expr, EmitState es) { if (expr is BinaryExpression) { return(EmitExpressionNode((BinaryExpression)expr, es)); } else if (expr is UnaryExpression) { return(EmitExpressionNode((UnaryExpression)expr, es)); } else if (expr is ParameterExpression) { return(EmitExpressionNode((ParameterExpression)expr, es)); } else if (expr is MethodCallExpression) { return(EmitExpressionNode((MethodCallExpression)expr, es)); } else if (expr is ConstantExpression) { return(EmitExpressionNode((ConstantExpression)expr, es)); } else { throw new InvalidOperationException(String.Format("Cannot compile expression nodes of type {0}", expr.GetType().Name)); } }
internal static Type EmitExpressionNode(MethodCallExpression expr, EmitState es) { if (expr.NodeType == ExpressionType.Call) { var paramInfo = expr.Method.GetParameters(); for (int i = 0; i < expr.Arguments.Count; i++) { var arg = expr.Arguments[i]; var parInfo = paramInfo[i]; Type argType = EmitExpression(arg, es); if (!parInfo.ParameterType.IsAssignableFrom(argType)) { EmitConversion(parInfo.ParameterType, es); } } es.ILGenerator.EmitCall(OpCodes.Call, expr.Method, null); return(expr.Method.ReturnType); } else { throw new InvalidOperationException(String.Format("Method calls of type {0} not supported in expressions", expr.NodeType)); } }
internal static Type EmitExpressionNode(ConstantExpression expr, EmitState es) { Type t = expr.Type; if (t == typeof(byte)) { es.ILGenerator.Emit(OpCodes.Ldc_I4_S, (byte)expr.Value); } else if (t == typeof(Int32)) { es.ILGenerator.Emit(OpCodes.Ldc_I4, (Int32)expr.Value); } else if (t == typeof(Int64)) { es.ILGenerator.Emit(OpCodes.Ldc_I8, (Int64)expr.Value); } else if (t == typeof(Single)) { es.ILGenerator.Emit(OpCodes.Ldc_R4, (Single)expr.Value); } else if (t == typeof(Double)) { es.ILGenerator.Emit(OpCodes.Ldc_R8, (Double)expr.Value); } else { throw new InvalidOperationException(String.Format("Constants of type {0} not supported in expressions", expr.Type.Name)); } return(t); }
internal static Type EmitExpressionNode(ParameterExpression expr, EmitState es) { string paramName = expr.Name; UInt16 paramIndex = es.ParameterIndices[paramName]; Type paramType = es.ParameterTypes[paramIndex]; switch (paramIndex) { case 0: es.ILGenerator.Emit(OpCodes.Ldarg_0); break; case 1: es.ILGenerator.Emit(OpCodes.Ldarg_1); break; case 2: es.ILGenerator.Emit(OpCodes.Ldarg_2); break; case 3: es.ILGenerator.Emit(OpCodes.Ldarg_3); break; default: es.ILGenerator.Emit(OpCodes.Ldarg, paramIndex); break; } return(paramType); }
internal RCMethod Compile(RNode main) { EmitScope es = CreateMethodScope("main"); PushScope(es); state = EmitState.RESOLVING; main.Walk(this); state = EmitState.EMITTING; EmitScopeInitializer(); main.Walk(this); Type main_type = CloseScope(es); if (save) { assembly_builder.Save(filename); } // Call constructor object method = main_type.InvokeMember(null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.CreateInstance, null, null, new object[] {} ); return((RCMethod)method); }
internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, OptimizationLevel optimizations) { Debug.Assert(BitConverter.IsLittleEndian); this.module = module; this.LocalSlotManager = localSlotManager; _emitState = default(EmitState); _scopeManager = new LocalScopeManager(); leaderBlock = _currentBlock = _scopeManager.CreateBlock(this); _labelInfos = new SmallDictionary <object, LabelInfo>(ReferenceEqualityComparer.Instance); _optimizations = optimizations; }
internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, OptimizationLevel optimizations) { Debug.Assert(BitConverter.IsLittleEndian); this.module = module; this.LocalSlotManager = localSlotManager; _emitState = default(EmitState); _scopeManager = new LocalScopeManager(); leaderBlock = _currentBlock = _scopeManager.CreateBlock(this); _labelInfos = new SmallDictionary<object, LabelInfo>(ReferenceEqualityComparer.Instance); _optimizations = optimizations; }
internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, bool isOptimizing) { Debug.Assert(BitConverter.IsLittleEndian); this.module = module; this.LocalSlotManager = localSlotManager; this.emitState = default(EmitState); this.scopeManager = new LocalScopeManager(); leaderBlock = currentBlock = this.scopeManager.CreateBlock(this); labelInfos = new SmallDictionary<object, LabelInfo>(ReferenceEqualityComparer.Instance); this.isOptimizing = isOptimizing; }
internal ILBuilder(ITokenDeferral module, LocalSlotManager localSlotManager, bool isOptimizing) { Debug.Assert(BitConverter.IsLittleEndian); this.module = module; this.LocalSlotManager = localSlotManager; this.emitState = default(EmitState); this.scopeManager = new LocalScopeManager(); leaderBlock = currentBlock = this.scopeManager.CreateBlock(this); labelInfos = new SmallDictionary <object, LabelInfo>(ReferenceEqualityComparer.Instance); this.isOptimizing = isOptimizing; }
internal static void _CompileExpression <T> (LambdaExpression expression, out T result) where T : class { Type t = typeof(T); if (!((t.BaseType == typeof(MulticastDelegate)) || (t.BaseType == typeof(Delegate)))) { throw new InvalidOperationException("Cannot compile an expression to a non-delegate type"); } MethodInfo desiredSignature = t.GetMethod("Invoke"); Type returnType = desiredSignature.ReturnType; Type[] parameterTypes = desiredSignature.GetParameters().Select( (p) => p.ParameterType ).ToArray(); var parameterIndices = new Dictionary <string, UInt16>(); for (int i = 0; i < expression.Parameters.Count; i++) { parameterIndices[expression.Parameters[i].Name] = (UInt16)i; } DynamicMethod newMethod = new DynamicMethod( String.Format("CompiledExpression<{0}>", t.Name), returnType, parameterTypes, true ); ILGenerator ilGenerator = newMethod.GetILGenerator(); EmitState es = new EmitState { ILGenerator = ilGenerator, ReturnType = returnType, ParameterTypes = parameterTypes, ParameterIndices = parameterIndices }; Type resultType = EmitExpression(expression.Body, es); if (!returnType.IsAssignableFrom(resultType)) { EmitConversion(returnType, es); } ilGenerator.Emit(OpCodes.Ret); result = newMethod.CreateDelegate(t) as T; }
internal static Type EmitExpressionNode(UnaryExpression expr, EmitState es) { Type t = EmitExpression(expr.Operand, es); if (expr.NodeType == ExpressionType.Convert) { EmitConversion(t, es); return(t); } else { var oi = GetOperatorInfo(expr.NodeType); es.ILGenerator.Emit(oi.OpCode); return(t); } }
internal static Type EmitExpressionNode(BinaryExpression expr, EmitState es) { Type typeLeft = EmitExpression(expr.Left, es); Type typeRight = EmitExpression(expr.Right, es); var oi = GetOperatorInfo(expr.NodeType); GenerateOperatorIL(es.ILGenerator, new [] { typeLeft, typeRight }, GetOperator(expr.NodeType)); if (expr.Conversion != null) { return(EmitExpression(expr.Conversion, es)); } else if (oi.IsComparison) { return(typeof(Boolean)); } else { return(typeLeft); } }
internal static Type EmitConversion(Type desiredType, EmitState es) { if (desiredType == typeof(Single)) { es.ILGenerator.Emit(OpCodes.Conv_R4); } else if (desiredType == typeof(Double)) { es.ILGenerator.Emit(OpCodes.Conv_R8); } else if (desiredType == typeof(Int32)) { es.ILGenerator.Emit(OpCodes.Conv_I4); } else if (desiredType == typeof(Int64)) { es.ILGenerator.Emit(OpCodes.Conv_I8); } else { throw new InvalidOperationException(String.Format("Conversions to type {0} not supported in expressions", desiredType.Name)); } return(desiredType); }
internal RCMethod Compile(RNode main) { EmitScope es = CreateMethodScope("main"); PushScope(es); state = EmitState.RESOLVING; main.Walk(this); state = EmitState.EMITTING; EmitScopeInitializer(); main.Walk(this); Type main_type = CloseScope(es); if(save) { assembly_builder.Save(filename); } // Call constructor object method = main_type.InvokeMember(null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.CreateInstance, null, null, new object[] {} ); return (RCMethod)method; }
private void InitializeLevel() { _levelData = levelData[0]; emitState = EmitState.Regular; levelState = LevelState.L1; }