public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder) { Label forStart = codeGenerator.DefineLabel(); Label forEnd = codeGenerator.DefineLabel(); EndLabel = forEnd; InitExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); UpperBoundExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.MarkLabel(forStart); codeGenerator.Emit(OpCodes.Dup); codeGenerator.Emit(OpCodes.Ldsfld, InitExp.ForVariableBuilder); codeGenerator.Emit(OpCodes.Blt, forEnd); BodyExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Ldsfld, InitExp.ForVariableBuilder); codeGenerator.Emit(OpCodes.Ldc_I4_1); codeGenerator.Emit(OpCodes.Add); codeGenerator.Emit(OpCodes.Stsfld, InitExp.ForVariableBuilder); codeGenerator.Emit(OpCodes.Br, forStart); codeGenerator.MarkLabel(forEnd); codeGenerator.Emit(OpCodes.Pop); InitExp.RestoreVariable(codeGenerator); }
public override void Generate(ILGenerator generator, Symbols s) { var Is_False = generator.DefineLabel(); var End = generator.DefineLabel(); LeftOperand.Generate(generator, s); //Pregunto si hay un 0 en el tope d la pila generator.Emit(OpCodes.Ldc_I4_0); //Si es verdad salto para la etiqueta es falso generator.Emit(OpCodes.Beq, Is_False); RightOperand.Generate(generator, s); //Pregunto si hay un 0 en el tope d la pila generator.Emit(OpCodes.Ldc_I4_0); //Si es verdad salto para la etiqueta es falso generator.Emit(OpCodes.Beq, Is_False); //Si hay un 1 en el tope es porque no salte para el label que me dice si hay algun false , //por lo q el primer operando es true y entonces es true el and generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.Br, End); generator.MarkLabel(Is_False); generator.Emit(OpCodes.Ldc_I4_0); generator.MarkLabel(End); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="typeToBuild"></param> /// <param name="existing"></param> /// <param name="idToBuild"></param> /// <param name="il"></param> protected override void BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild, ILGenerator il) { IConstructorChooserPolicy ctorChooser = GetConstructorChooser(context, typeToBuild, idToBuild); ConstructorInfo ctor = ctorChooser.ChooseConstructor(typeToBuild); Label existingObjectNotNull = il.DefineLabel(); Label done = il.DefineLabel(); // If existing object (arg 2) is null, call the constructor il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, existingObjectNotNull); // resolve all constructor parameters... if (ctor != null) { foreach (ParameterInfo parameter in ctor.GetParameters()) { EmitResolveParameter(il, parameter); FixupParameterType(il, parameter.ParameterType); } } // invoke constructor, leaving the new object on the top of the stack... EmitCallConstructor(il, ctor, typeToBuild); // And skip around the else clause il.Emit(OpCodes.Br_S, done); // We have an existing object, just get it on top of the stack il.MarkLabel(existingObjectNotNull); il.Emit(OpCodes.Ldarg_2); il.MarkLabel(done); }
public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder) { LeftOperand.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); RightOperand.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); Label endLabel = codeGenerator.DefineLabel(); Label trueLabel = codeGenerator.DefineLabel(); if (LeftOperand.ReturnType == StringType.StringInstance) { codeGenerator.Emit(OpCodes.Call, typeof(String).GetMethod("CompareTo", new Type[] { typeof(string) })); codeGenerator.Emit(OpCodes.Ldc_I4_0); codeGenerator.Emit(OpCodes.Bne_Un, trueLabel); } else codeGenerator.Emit(OpCodes.Bne_Un, trueLabel); codeGenerator.Emit(OpCodes.Ldc_I4_0); codeGenerator.Emit(OpCodes.Br, endLabel); codeGenerator.MarkLabel(trueLabel); codeGenerator.Emit(OpCodes.Ldc_I4_1); codeGenerator.MarkLabel(endLabel); }
public override void generar(Emit.ILGenerator il) { Emit.LocalBuilder tmpVarLogico; Console.WriteLine("Generando Nodo Condicional (IF)"); this.condicion.generar(il); il.Emit(Emit.OpCodes.Ldc_I4_0); //Ingreso constante 0 il.Emit(Emit.OpCodes.Ceq); //Comparo si es falso (es 0) //Almaceno este resultado en una variable temporal tmpVarLogico = il.DeclareLocal(typeof(bool)); il.Emit(Emit.OpCodes.Stloc, tmpVarLogico); //cargo el resultado de la variable temporal il.Emit(Emit.OpCodes.Ldloc, tmpVarLogico); Emit.Label bloqueFalso = il.DefineLabel(); //salto en caso que sea verdadero el resultado es decir es cero la evaluacion del (pila==0) hago el sino il.Emit(Emit.OpCodes.Brtrue, bloqueFalso); Entonces.generar(il); Emit.Label finSi = il.DefineLabel(); il.Emit(Emit.OpCodes.Br, finSi); il.MarkLabel(bloqueFalso); if (Sino != null) { Sino.generar(il); } il.MarkLabel(finSi); }
public void GenerateWriterMethod(Type obtype, CodeGenContext ctx, ILGenerator il) { var getTypeIDMethodInfo = typeof(Serializer).GetMethod("GetTypeID", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(object) }, null); var map = ctx.TypeMap; // arg0: Serializer, arg1: Stream, arg2: object var idLocal = il.DeclareLocal(typeof(ushort)); // get TypeID from object's Type il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Call, getTypeIDMethodInfo); il.Emit(OpCodes.Stloc_S, idLocal); // write typeID il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc_S, idLocal); il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(ushort))); // +1 for 0 (null) var jumpTable = new Label[map.Count + 1]; jumpTable[0] = il.DefineLabel(); foreach (var kvp in map) jumpTable[kvp.Value.TypeID] = il.DefineLabel(); il.Emit(OpCodes.Ldloc_S, idLocal); il.Emit(OpCodes.Switch, jumpTable); il.Emit(OpCodes.Newobj, Helpers.ExceptionCtorInfo); il.Emit(OpCodes.Throw); /* null case */ il.MarkLabel(jumpTable[0]); il.Emit(OpCodes.Ret); /* cases for types */ foreach (var kvp in map) { var type = kvp.Key; var data = kvp.Value; il.MarkLabel(jumpTable[data.TypeID]); if (data.NeedsInstanceParameter) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); il.Emit(OpCodes.Tailcall); il.Emit(OpCodes.Call, data.WriterMethodInfo); il.Emit(OpCodes.Ret); } }
internal override void TranslateToIL(ILGenerator il, Type rtype){ Label else_label = il.DefineLabel(); Label endif_label = il.DefineLabel(); this.condition.TranslateToConditionalBranch(il, false, else_label, false); this.operand1.TranslateToIL(il, rtype); il.Emit(OpCodes.Br, endif_label); il.MarkLabel(else_label); this.operand2.TranslateToIL(il, rtype); il.MarkLabel(endif_label); }
public override void GenerateIL(ILGenerator il, SymbolTable st) { Label beginLoop = il.DefineLabel(); Label endLoop = il.DefineLabel(); il.MarkLabel(beginLoop); var newTable = new SymbolTable(st, endLoop); Block.GenerateIL(il, newTable); il.Emit(OpCodes.Br, beginLoop); il.MarkLabel(endLoop); }
public override void Generate (ILGenerator gen) { Label falseLabel = gen.DefineLabel (); Label endLabel = gen.DefineLabel (); GenerateCondition (gen, falseLabel); trueBlock.Generate (gen); gen.Emit (OpCodes.Br, endLabel); gen.MarkLabel(falseLabel); falseBlock.Generate (gen); gen.MarkLabel(endLabel); }
public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder) { Label thenLabel = codeGenerator.DefineLabel(); Label endLabel = codeGenerator.DefineLabel(); ConditionExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Brfalse, thenLabel); ThenExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Br, endLabel); codeGenerator.MarkLabel(thenLabel); ElseExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.MarkLabel(endLabel); }
public static void GenerateSerializerSwitch(CodeGenContext ctx, ILGenerator il, IDictionary<Type, TypeData> map) { // arg0: Stream, arg1: object var idLocal = il.DeclareLocal(typeof(ushort)); // get TypeID from object's Type var getTypeIDMethod = typeof(Serializer).GetMethod("GetTypeID", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(object) }, null); il.Emit(OpCodes.Ldarg_1); il.EmitCall(OpCodes.Call, getTypeIDMethod, null); il.Emit(OpCodes.Stloc_S, idLocal); // write typeID il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc_S, idLocal); il.EmitCall(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(ushort)), null); // +1 for 0 (null) var jumpTable = new Label[map.Count + 1]; jumpTable[0] = il.DefineLabel(); foreach (var kvp in map) jumpTable[kvp.Value.TypeID] = il.DefineLabel(); il.Emit(OpCodes.Ldloc_S, idLocal); il.Emit(OpCodes.Switch, jumpTable); ConstructorInfo exceptionCtor = typeof(Exception).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null); il.Emit(OpCodes.Newobj, exceptionCtor); il.Emit(OpCodes.Throw); /* null case */ il.MarkLabel(jumpTable[0]); il.Emit(OpCodes.Ret); /* cases for types */ foreach (var kvp in map) { var type = kvp.Key; var data = kvp.Value; il.MarkLabel(jumpTable[data.TypeID]); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); il.EmitCall(OpCodes.Call, data.WriterMethodInfo, null); il.Emit(OpCodes.Ret); } }
static void WriteDeserializerArray(TypeBuilder typeBuilder, ILGenerator il, Type type, int tag, MethodInfo setMethod, int? itemLocalIndex = null) { var itemType = type.GetElementType(); var lengthLocal = il.DeclareLocal(typeof(int)); var arrayLocal = il.DeclareLocal(type); var itemLocal = il.DeclareLocal(itemType); var indexLocal = il.DeclareLocal(typeof(int)); var startLabel = il.DefineLabel(); var endLabel = il.DefineLabel(); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Ldc_I4, tag); il.Emit(OpCodes.Call, GetCollectionLengthMethod); il.Emit(OpCodes.Stloc, lengthLocal); il.Emit(OpCodes.Ldloc, lengthLocal.LocalIndex); il.Emit(OpCodes.Newarr, itemType); il.Emit(OpCodes.Stloc, arrayLocal.LocalIndex); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc, indexLocal.LocalIndex); il.Emit(OpCodes.Br, startLabel); il.MarkLabel(endLabel); WriteDeserializerReadValue(typeBuilder, il, itemType, 1, itemLocal.LocalIndex); il.Emit(OpCodes.Ldloc, arrayLocal.LocalIndex); il.Emit(OpCodes.Ldloc, indexLocal.LocalIndex); il.Emit(OpCodes.Ldloc, itemLocal.LocalIndex); il.Emit(OpCodes.Stelem, itemType); il.Emit(OpCodes.Ldloc, indexLocal.LocalIndex); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc, indexLocal.LocalIndex); il.MarkLabel(startLabel); il.Emit(OpCodes.Ldloc, indexLocal.LocalIndex); il.Emit(OpCodes.Ldloc, lengthLocal.LocalIndex); il.Emit(OpCodes.Blt, endLabel); if (itemLocalIndex == null) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc, arrayLocal.LocalIndex); il.Emit(OpCodes.Callvirt, setMethod); } else { il.Emit(OpCodes.Ldloc, arrayLocal.LocalIndex); il.Emit(OpCodes.Stloc, itemLocalIndex.Value); } }
public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder) { Label trueLabel = codeGenerator.DefineLabel(); Label endLabel = codeGenerator.DefineLabel(); LeftOperand.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Brtrue, trueLabel); RightOperand.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Brtrue, trueLabel); codeGenerator.Emit(OpCodes.Ldc_I4_0); codeGenerator.Emit(OpCodes.Br, endLabel); codeGenerator.MarkLabel(trueLabel); codeGenerator.Emit(OpCodes.Ldc_I4_1); codeGenerator.MarkLabel(endLabel); }
public void IfNull(ILGenerator il, Emitter isTrue, Emitter isFalse) { Label nope = il.DefineLabel(); Label done = il.DefineLabel(); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); // Has 1 if NULL il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); // Has 1 if NOT NULL il.Emit(OpCodes.Brtrue, nope); isTrue(); il.Emit(OpCodes.Br, done); il.MarkLabel(nope); isFalse(); il.MarkLabel(done); }
public override void GenerateCode(ILGenerator generator, TypeBuilder typeBuilder) { // Declarando la etiqueta. Label end = generator.DefineLabel(); //Generamos el codigo de la izquierda Left.GenerateCode(generator, typeBuilder); //Devuelve '1' en la pila si el valor de Left es distinto de cero. CheckIfEqualToZero(generator); //Guardamos el resultado en una variable, por si se salta no perderlo var result = generator.DeclareLocal(typeof (int)); GetValueFromStack(generator, result); //Si fue igual a 1 (true), saltamos hacia el final generator.Emit(OpCodes.Brtrue, end); //Sino, Generamos el codigo de la derecha Right.GenerateCode(generator, typeBuilder); //Si llegamos aqui, entonces el resultado sera el del operador derecho (si es 1 => 1) CheckIfEqualToZero(generator); //Guardamos el resultado en la variable GetValueFromStack(generator, result); //Haciendo 'backpatch' generator.MarkLabel(end); //Guardamos el resultado en la pila generator.Emit(OpCodes.Ldloc, result); }
public void GenerateWriterMethod(Serializer serializer, Type type, ILGenerator il) { var valueType = type.GetGenericArguments()[0]; var noValueLabel = il.DefineLabel(); MethodInfo getHasValue = type.GetProperty("HasValue").GetGetMethod(); MethodInfo getValue = type.GetProperty("Value").GetGetMethod(); var data = serializer.GetIndirectData(valueType); il.Emit(OpCodes.Ldarg_1); // Stream il.Emit(OpCodes.Ldarga_S, 2); // &value il.Emit(OpCodes.Call, getHasValue); il.Emit(OpCodes.Call, serializer.GetDirectWriter(typeof(bool))); il.Emit(OpCodes.Ldarga_S, 2); // &value il.Emit(OpCodes.Call, getHasValue); il.Emit(OpCodes.Brfalse_S, noValueLabel); if (data.WriterNeedsInstance) il.Emit(OpCodes.Ldarg_0); // Serializer il.Emit(OpCodes.Ldarg_1); // Stream il.Emit(OpCodes.Ldarga_S, 2); // &value il.Emit(OpCodes.Call, getValue); // XXX for some reason Tailcall causes huge slowdown, at least with "decimal?" //il.Emit(OpCodes.Tailcall); il.Emit(OpCodes.Call, data.WriterMethodInfo); il.MarkLabel(noValueLabel); il.Emit(OpCodes.Ret); }
void CopyLabels(ILGenerator Gen, int i, Dictionary<int, Label> LateLabels) { if(!LateLabels.ContainsKey(i)) return; Gen.MarkLabel(LateLabels[i]); LateLabels.Remove(i); }
public void EmitMethodBody(ILGenerator IL, MethodInfo method, FieldInfo field) { bool isStatic = false; ParameterInfo[] parameters = method.GetParameters(); IL.DeclareLocal(typeof (object[])); IL.DeclareLocal(typeof (InvocationInfo)); IL.DeclareLocal(typeof (Type[])); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Callvirt, getInterceptor); // if (interceptor == null) // throw new NullReferenceException(); Label skipThrow = IL.DefineLabel(); IL.Emit(OpCodes.Dup); IL.Emit(OpCodes.Ldnull); IL.Emit(OpCodes.Bne_Un, skipThrow); IL.Emit(OpCodes.Newobj, notImplementedConstructor); IL.Emit(OpCodes.Throw); IL.MarkLabel(skipThrow); // Push the 'this' pointer onto the stack IL.Emit(OpCodes.Ldarg_0); // Push the MethodInfo onto the stack Type declaringType = method.DeclaringType; IL.Emit(OpCodes.Ldtoken, method); if (declaringType.IsGenericType) { IL.Emit(OpCodes.Ldtoken, declaringType); IL.Emit(OpCodes.Call, getGenericMethodFromHandle); } else { IL.Emit(OpCodes.Call, getMethodFromHandle); } IL.Emit(OpCodes.Castclass, typeof (MethodInfo)); PushStackTrace(IL); PushGenericArguments(method, IL); _argumentHandler.PushArguments(parameters, IL, isStatic); // InvocationInfo info = new InvocationInfo(...); IL.Emit(OpCodes.Newobj, infoConstructor); IL.Emit(OpCodes.Stloc_1); IL.Emit(OpCodes.Ldloc_1); IL.Emit(OpCodes.Callvirt, handlerMethod); SaveRefArguments(IL, parameters); PackageReturnType(method, IL); IL.Emit(OpCodes.Ret); }
public virtual void GenerateMethod(PropertyInfo pi, MethodInfo mi, ILGenerator gen) { gen.DeclareLocal(typeof(Type)); gen.EmitLdType(mi.GetGenericArguments()[0]); gen.Emit(OpCodes.Stloc_0); foreach (var scc in _pcb.ProxyCoderContext.MixinCoderContexts.SelectMany(a => a.SubjectCoderContexts)) { var smes = scc.GetPerSubjectCoder<ISubjectMethodExistsPerSubjectCoder>(); if (smes==null) continue; var falseTarget = gen.DefineLabel(); gen.Emit(OpCodes.Ldloc_0); gen.EmitLdType(scc.SubjectType); gen.EmitOpEqualityCall(typeof(Type)); gen.Emit(OpCodes.Brfalse, falseTarget); smes.PutSubjectMethodExistsOnStack(gen); // Required for PE Verification gen.Emit(OpCodes.Castclass, mi.ReturnType); gen.Emit(OpCodes.Ret); gen.MarkLabel(falseTarget); } gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Ret); }
protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il) { var convention = config.Conventions.OfType <TransactionProxyConvention>().First(); var stringEqual = typeof(string).GetMethod("op_Equality", new Type[] { typeof(string), typeof(string) }); var getValueEntriesMethod = typeof(TransactionProxyHelper).GetMethod("GetValueEntries"); var propertyLabels = new Dictionary <TransactionProxyConvention.TransactionProxyProperty, Label>(); var returnLabel = il.DefineLabel(); var notFoundLabel = il.DefineLabel(); foreach (var item in convention.TransactionProxyProperties) { var label = il.DefineLabel(); propertyLabels.Add(item, label); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldstr, item.Property.Name); il.Emit(OpCodes.Call, stringEqual); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, label); il.Emit(OpCodes.Nop); } il.Emit(OpCodes.Br, notFoundLabel); foreach (var item in propertyLabels) { var method = getValueEntriesMethod.MakeGenericMethod(item.Key.Property.PropertyType, convention.ItemType); il.MarkLabel(item.Value); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.Key.ValuesProperty.BackingField); il.EmitCall(OpCodes.Call, method, null); il.Emit(OpCodes.Br, returnLabel); } var exceptionType = typeof(ArgumentOutOfRangeException); il.MarkLabel(notFoundLabel); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Newobj, exceptionType.GetConstructor(new Type[] { typeof(string) })); il.ThrowException(exceptionType); il.MarkLabel(returnLabel); il.Emit(OpCodes.Ret); }
public override void GenCode(TypeBuilder tb, MethodBuilder mb, ILGenerator cg) { //// Label inicio = cg.DefineLabel(); cg.MarkLabel(inicio); ExprWhile.GenCode(tb,mb,cg); cg.Emit(OpCodes.Ldc_I4_0); Label end = cg.DefineLabel(); Compiler.ends.Push(end); cg.Emit(OpCodes.Beq, end); ////aqui es donde va expr.gencode ExprDo.GenCode(tb,mb,cg); //// cg.Emit(OpCodes.Br, inicio); cg.MarkLabel(end); Compiler.ends.Pop(); }
public override void Generate (ILGenerator gen) { Label startLabel = gen.DefineLabel (); Label checkLabel = gen.DefineLabel (); gen.Emit (OpCodes.Br, checkLabel); gen.MarkLabel(startLabel); whileBlock.Generate (gen); gen.MarkLabel(checkLabel); if (condition is CodeConditionExpression) ((CodeConditionExpression)condition).GenerateForBranch (gen, startLabel, true); else { condition.Generate (gen); gen.Emit (OpCodes.Brtrue, startLabel); } }
internal static void EmitReturnIfNull( ILGenerator il ) { Label label = il.DefineLabel(); il.Emit( OpCodes.Brtrue, label ); il.Emit( OpCodes.Pop ); EmitReturn( il ); il.MarkLabel( label ); }
public void Weave(ILGenerator ilGenerator) { var typeofException = typeof(Exception); LocalBuilder exceptionLocalBuilder = null; var typeofFlowBehavior = typeof(FlowBehavior); LocalBuilder flowBehavoiurLocalBuilder = null; var afterRethrowLabel = ilGenerator.DefineLabel(); var throwFlowBehaviorLabel = ilGenerator.DefineLabel(); var rethrowFlowBehaviorLabel = ilGenerator.DefineLabel(); var argsImplLocalBuilder = localBuilderRepository.Get(aspectArgumentType); var jumpTable = new[] { throwFlowBehaviorLabel, rethrowFlowBehaviorLabel }; var setExceptionMethodInfo = aspectArgumentType.GetProperty("Exception").GetSetMethod(); var flowBehaviorMethodInfo = aspectArgumentType.GetProperty("FlowBehavior").GetGetMethod(); exceptionLocalBuilder = localBuilderRepository.GetOrDeclare(typeofException, () => { return ilGenerator.DeclareLocal(typeofException); }); flowBehavoiurLocalBuilder = localBuilderRepository.GetOrDeclare(typeofFlowBehavior, () => { return ilGenerator.DeclareLocal(typeofFlowBehavior); }); ilGenerator.BeginCatchBlock(typeofException); ilGenerator.EmitStoreLocal(exceptionLocalBuilder); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, setExceptionMethodInfo); catchWeavers.ForEach(weaver => weaver.Weave(ilGenerator)); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, flowBehaviorMethodInfo); ilGenerator.EmitStoreLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitLoadLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitPushInteger(1); ilGenerator.Emit(OpCodes.Sub); ilGenerator.Emit(OpCodes.Switch, jumpTable); ilGenerator.Emit(OpCodes.Br_S, afterRethrowLabel); ilGenerator.MarkLabel(throwFlowBehaviorLabel); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Throw); ilGenerator.MarkLabel(rethrowFlowBehaviorLabel); ilGenerator.Emit(OpCodes.Rethrow); ilGenerator.MarkLabel(afterRethrowLabel); }
public override void GenerateCode(ILGenerator codeGenerator, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder) { Label whileStart = codeGenerator.DefineLabel(); Label whileEnd = codeGenerator.DefineLabel(); EndLabel = whileEnd; codeGenerator.MarkLabel(whileStart); ConditionExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Ldc_I4_0); codeGenerator.Emit(OpCodes.Beq, whileEnd); BodyExp.GenerateCode(codeGenerator, typeBuilder, moduleBuilder); codeGenerator.Emit(OpCodes.Br, whileStart); codeGenerator.MarkLabel(whileEnd); }
public override void Generate (ILGenerator gen) { Label falseLabel = gen.DefineLabel (); Label endLabel = gen.DefineLabel (); if (exp1 is CodeConditionExpression) ((CodeConditionExpression)exp1).GenerateForBranch (gen, falseLabel, false); else { exp1.Generate (gen); gen.Emit (OpCodes.Brfalse, falseLabel); } exp2.Generate (gen); gen.Emit (OpCodes.Br, endLabel); gen.MarkLabel(falseLabel); gen.Emit (OpCodes.Ldc_I4_0); gen.MarkLabel(endLabel); }
internal override void TranslateToIL(ILGenerator il, Type rtype){ //This assumes rtype == Void.class Label loop_start = il.DefineLabel(); Label loop_end = il.DefineLabel(); Label body = il.DefineLabel(); compilerGlobals.BreakLabelStack.Push(loop_end); compilerGlobals.ContinueLabelStack.Push(loop_start); il.Emit(OpCodes.Br, loop_start); il.MarkLabel(body); this.body.TranslateToIL(il, Typeob.Void); il.MarkLabel(loop_start); this.context.EmitLineInfo(il); this.condition.TranslateToConditionalBranch(il, true, body, false); il.MarkLabel(loop_end); compilerGlobals.BreakLabelStack.Pop(); compilerGlobals.ContinueLabelStack.Pop(); }
public override void Emit(IMemberEmitter member, ILGenerator gen) { ArgumentsUtil.EmitLoadOwnerAndReference(reference, gen); var notNull = gen.DefineLabel(); gen.Emit(OpCodes.Brtrue_S, notNull); ifNull.Emit(member, gen); gen.MarkLabel(notNull); ifNotNull.Emit(member, gen); }
public static void EmitPackCode(Type type, MethodInfo mi, ILGenerator il, Func<Type,MemberInfo[]> targetMemberSelector, Func<MemberInfo,string> memberNameFormatter, Func<Type, MethodInfo> lookupPackMethod) { if ((type.IsPrimitive || type.IsInterface) && !type.IsMap()) throw new NotSupportedException (); Variable arg_writer = Variable.CreateArg (0); Variable arg_obj = Variable.CreateArg (1); if (!type.IsValueType) { // null check Label notNullLabel = il.DefineLabel (); il.EmitLd (arg_obj); il.Emit (OpCodes.Brtrue_S, notNullLabel); il.EmitLd (arg_writer); il.Emit (OpCodes.Call, typeof(MsgPackWriter).GetMethod("WriteNil", new Type[0])); il.Emit (OpCodes.Ret); il.MarkLabel (notNullLabel); } if (type.IsArray) { EmitPackArrayCode(mi, il, type, arg_writer, arg_obj, Variable.CreateLocal(il.DeclareLocal(typeof(int))), lookupPackMethod); goto FinallyProcess; } if (type.IsMap()) { //EmitPackDictCode(mi, il, type, arg_writer, arg_obj, lookupPackMethod); Compiler.DictionaryILGenerator.EmitPackIL(mi, il, type, arg_writer, arg_obj, lookupPackMethod); goto FinallyProcess; } // MsgPackWriter.WriteMapHeader MemberInfo[] members = targetMemberSelector(type); il.EmitLd(arg_writer); il.EmitLdc(members.Length); il.Emit(OpCodes.Callvirt, typeof(MsgPackWriter).GetMethod("WriteMapHeader", new Type[] { typeof(int) })); for (int i = 0; i < members.Length; i++) { MemberInfo m = members[i]; Type mt = m.GetMemberType(); // write field-name il.EmitLd(arg_writer); il.EmitLdstr(memberNameFormatter(m)); il.EmitLd_True(); il.Emit(OpCodes.Call, typeof(MsgPackWriter).GetMethod("Write", new Type[] { typeof(string), typeof(bool) })); // write value EmitPackMemberValueCode(mt, il, arg_writer, arg_obj, m, null, type, mi, lookupPackMethod); } FinallyProcess: il.Emit (OpCodes.Ret); }
public override void AppendRead(ILGenerator il, MessageField field) { var count = il.DeclareLocal(typeof(uint)); var top = il.DefineLabel(); var next = il.DefineLabel(); il.Emit(OpCodes.Br_S, next); il.Emit(OpCodes.Nop); il.MarkLabel(top); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, property.GetGetMethod()); il.Emit(OpCodes.Ldarg_1); field.AppendReadField(il); il.Emit(OpCodes.Callvirt, addItem); il.MarkLabel(next); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, typeof(MessageReader).GetProperty("EndOfStream").GetGetMethod()); il.Emit(OpCodes.Brfalse_S, top); }
public void EmitIL(ILGenerator body, FieldInfo tape, FieldInfo ptr) { var l1 = body.DefineLabel(); var l2 = body.DefineLabel(); body.MarkLabel(l1); body.Emit(OpCodes.Ldsfld, tape); body.Emit(OpCodes.Ldsfld, ptr); body.Emit(OpCodes.Ldelem_I4); body.Emit(OpCodes.Brfalse, l2); Tokens.ToList().ForEach(t => t.EmitIL(body, tape, ptr)); body.Emit(OpCodes.Br, l1); body.MarkLabel(l2); body.Emit(OpCodes.Nop); }
public override void Emit(IMemberEmitter member, ILGenerator gen) { expression.Emit(member, gen); gen.Emit(OpCodes.Dup); var label = gen.DefineLabel(); gen.Emit(OpCodes.Brtrue_S, label); gen.Emit(OpCodes.Pop); @default.Emit(member, gen); gen.MarkLabel(label); }
public override void generar(Emit.ILGenerator il) { Emit.LocalBuilder tmpCondicion; tmpCondicion = il.DeclareLocal(typeof(bool)); Emit.Label sentenciasRepita = il.DefineLabel(); il.MarkLabel(sentenciasRepita); il.Emit(Emit.OpCodes.Nop); //emito primera sentencia vacia Sentencias.generar(il); Condicion.generar(il); il.Emit(Emit.OpCodes.Stloc, tmpCondicion); //almaceno resultado de condicion del mientras il.Emit(Emit.OpCodes.Ldloc, tmpCondicion); //cargo resultado de condicion del mientras il.Emit(Emit.OpCodes.Brfalse, sentenciasRepita); }
public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary <string, string> filterValues, PropertyInfo property) { MethodInfo StringToLower = typeof(string).GetMethod("ToLower", new Type[] { }); MethodInfo StringStartsWith = typeof(String).GetMethod("StartsWith", new Type[] { typeof(string) }); MethodInfo StringContains = typeof(String).GetMethod("Contains", new Type[] { typeof(string) }); MethodInfo StringIsNullOrWhiteSpace = typeof(string).GetMethod("IsNullOrWhiteSpace", new Type[] { typeof(string) }); Label lblNextProperty = generator.DefineLabel(); Label lblNotNull = generator.DefineLabel(); string filterText = filterValues["filterText"]; string filterMode = filterValues["filterMode"]; // Do nothing for this property is the filterText is blank and the filterMode is "Starts With", "Doesn't Start With", "Contains", or " Doesn't Contain" if (string.IsNullOrWhiteSpace(filterText) && new string[] { "Starts With", "Doesn't Start With", "Contains", "Doesn't Contain" }.Contains(filterMode)) { return; } switch (filterMode) { case "Starts With": case "Contains": // Check that the property is not null. If it is null, return false; otherwise, continue. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Brtrue, lblNotNull); generator.EmitReturnFalse(); generator.MarkLabel(lblNotNull); // Load the property of the argument and make it lower-case. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Callvirt, StringToLower); // Load the lower-cased search key and see if the lower-cased property starts with it. generator.Emit(OpCodes.Ldstr, filterText.ToLower()); // We use either String.StartsWith or String.Contains according to what the user specified. generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains); // If the search key doesn't match, then return false; otherwise, go on to the next property generator.Emit(OpCodes.Brtrue, lblNextProperty); generator.EmitReturnFalse(); break; case "Doesn't Start With": case "Doesn't Contain": // Check that the property is not null. If it is null, then go on to the next property. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Brfalse, lblNextProperty); // Load the property of the argument and make it lower-case. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Callvirt, StringToLower); // Load the lower-cased search key and see if the lower-cased property starts with it. generator.Emit(OpCodes.Ldstr, filterText.ToLower()); // We use either String.StartsWith or String.Contains according to what the user specified. generator.Emit(OpCodes.Callvirt, filterMode == "Starts With" ? StringStartsWith : StringContains); // Since we're doing the opposite of the "Starts With" and "Contains" cases, go to the next property // if the search key doesn't match, and return false otherwise. generator.Emit(OpCodes.Brfalse, lblNextProperty); generator.EmitReturnFalse(); break; case "Is Blank": // Load the property of the argument and see if it's null or whitespace generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace); // If we didn't get back true, then return false; otherwise, go on to the next property. generator.Emit(OpCodes.Brtrue, lblNextProperty); generator.EmitReturnFalse(); break; case "Isn't Blank": // Load the property of the argument and see if it's null or whitespace generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Call, StringIsNullOrWhiteSpace); // If we didn't get back false, then return false; otherwise, go on to the next property. generator.Emit(OpCodes.Brfalse, lblNextProperty); generator.EmitReturnFalse(); break; } generator.MarkLabel(lblNextProperty); }
public override void GenerateFilterIl(System.Reflection.Emit.ILGenerator generator, Dictionary <string, string> filterValues, PropertyInfo property) { string minDateString = filterValues["minDate"]; string maxDateString = filterValues["maxDate"]; bool isNullable = property.PropertyType.Name == "Nullable`1"; Label lblNextProperty = generator.DefineLabel(); Label lblReturnFalse = generator.DefineLabel(); // First, get the value loaded, but if it is null, then return false unless both minDate and maxDate are blank. if (isNullable) { // This block of code is so-far UNTESTED!!! MethodInfo GetNullableHasValue = typeof(DateTime?).GetProperty("HasValue").GetGetMethod(); MethodInfo GetNullableValue = typeof(DateTime?).GetProperty("Value").GetGetMethod(); bool minAndMaxBothBlank = string.IsNullOrWhiteSpace(minDateString) && string.IsNullOrWhiteSpace(maxDateString); Label whereToGoIfNull = minAndMaxBothBlank ? lblNextProperty : lblReturnFalse; // If the property is null and both min and max date are blank, then go to the next property. // If the property is null and either min or max date has a value, return false. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Stloc, nullableDateTimeStorage); generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage); generator.Emit(OpCodes.Call, GetNullableHasValue); generator.Emit(OpCodes.Brfalse_S, whereToGoIfNull); // If we haven't jumped, then the datetime is not null, so just save it. generator.Emit(OpCodes.Ldloca_S, nullableDateTimeStorage); generator.Emit(OpCodes.Call, GetNullableValue); generator.Emit(OpCodes.Stloc, dateTimeStorage); } else // not nullable { // The property is not nullable, so just save the value. generator.EmitGetPropertyValueFromArgument(property); generator.Emit(OpCodes.Stloc, dateTimeStorage); } // At this point, the record's datetime should be saved in memory. MethodInfo DateTimeParse = typeof(DateTime).GetMethod("Parse", new Type[] { typeof(string) }); MethodInfo DateTimeLessThanOrEqual = typeof(DateTime).GetMethod("op_LessThanOrEqual"); MethodInfo DateTimeGreaterThanOrEqual = typeof(DateTime).GetMethod("op_GreaterThanOrEqual"); if (!string.IsNullOrWhiteSpace(minDateString)) { generator.Emit(OpCodes.Ldstr, minDateString); generator.Emit(OpCodes.Call, DateTimeParse); // Get the mindate DateTime. generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory generator.Emit(OpCodes.Call, DateTimeLessThanOrEqual); generator.Emit(OpCodes.Brfalse, lblReturnFalse); } if (!string.IsNullOrWhiteSpace(maxDateString)) { generator.Emit(OpCodes.Ldstr, maxDateString); generator.Emit(OpCodes.Call, DateTimeParse); // Get the maxdate DateTime. generator.Emit(OpCodes.Ldloc, dateTimeStorage); // Get the record's DateTime from memory generator.Emit(OpCodes.Call, DateTimeGreaterThanOrEqual); generator.Emit(OpCodes.Brfalse, lblReturnFalse); } generator.Emit(OpCodes.Br, lblNextProperty); generator.MarkLabel(lblReturnFalse); generator.EmitReturnFalse(); generator.MarkLabel(lblNextProperty); }
public void GenerateStatement(Statement _statement) { if (_statement is StatementSequence) { StatementSequence _StatementSequence = (StatementSequence)_statement; GenerateStatement(_StatementSequence.Left); GenerateStatement(_StatementSequence.Right); } else if (_statement is DeclareVariable) { // declare a variable in symbol table DeclareVariable declare = (DeclareVariable)_statement; tblIdentifier[declare.Identifier] = _ILGenerator.DeclareLocal(GetExpressionType(declare.Expression)); // set the initial value Assignment assign = new Assignment(); assign.Identifier = declare.Identifier; assign.Expression = declare.Expression; GenerateStatement(assign); } else if (_statement is Assignment) { Assignment assign = (Assignment)_statement; GenerateExpression(assign.Expression, GetExpressionType(assign.Expression)); if (GetExpressionType(assign.Expression) == typeof(ArithmaticExpression)) { SaveIdentifier(assign.Identifier, typeof(Int32)); } else { SaveIdentifier(assign.Identifier, GetExpressionType(assign.Expression)); } } else if (_statement is DeclareFunction) { GenerateStatementMethod(_statement); } else if (_statement is Write) { // for print keyword, call .net method for printscreen GenerateExpression(((Write)_statement).Expression, typeof(string)); _ILGenerator.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (_statement is ReadInput) { // call the readline method and parse input method _ILGenerator.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { }, null)); _ILGenerator.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); // store the input value in local builder SaveIdentifier(((ReadInput)_statement).Identifier, typeof(int)); } else if (_statement is IfThenElse) { //IfThenElse ifThenElse = (IfThenElse)stmt; //RelationalExpression relExpr = (RelationalExpression)ifThenElse.If; //// if, left side only //il.Emit(OpCodes.Stloc, symbolTable[relExpr.Left.ToString()]); //Label lblIf = il.DefineLabel(); //il.Emit(OpCodes.Br, lblIf); //// then //Label lblThen = il.DefineLabel(); //il.MarkLabel(lblThen); } else if (_statement is While) { While _while = (While)_statement; Label lblTest = _ILGenerator.DefineLabel(); Label lblEnd = _ILGenerator.DefineLabel(); if (_while.Operand == RelationalOperands.GreaterThan) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Cgt); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.EqualTo) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Ceq); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.LessThan) { _ILGenerator.MarkLabel(lblTest); GenerateExpression(_while.LeftExpression, typeof(int)); GenerateExpression(_while.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Clt); _ILGenerator.Emit(OpCodes.Brfalse, lblEnd); GenerateStatement(_while.Body); _ILGenerator.Emit(OpCodes.Br, lblTest); _ILGenerator.MarkLabel(lblEnd); } } else if (_statement is IfThen) { #region //////Label body = il.DefineLabel(); //////il.Emit(OpCodes.Ldc_I4, 1000); /* * // var x = 0; * // if x < 5 then * // print "less than 5"; * // endif; * * IfThen ifThen = (IfThen)stmt; * // jump to test * * * // **test** if x LessThan 5? (do the test) * il.MarkLabel(test); * GenExpr(ifThen.LeftExpression, typeof(int)); * */ //Label greaterThan = il.DefineLabel(); //IfThen ifThen = (IfThen)stmt; //GenExpr(ifThen.LeftExpression, typeof(int)); //GenExpr(ifThen.RightExpression, typeof(int)); //if (ifThen.Operand == RelationalOperands.GreaterThan) //{ // //} #endregion IfThen ifThen = (IfThen)_statement; Label lblElse = _ILGenerator.DefineLabel(); Label lblEnd = _ILGenerator.DefineLabel(); #region GreaterThan if (ifThen.Operand == RelationalOperands.GreaterThan) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Cgt); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region EqualTo else if (ifThen.Operand == RelationalOperands.EqualTo) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Ceq); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region LessThan else if (ifThen.Operand == RelationalOperands.LessThan) { GenerateExpression(ifThen.LeftExpression, typeof(int)); GenerateExpression(ifThen.RightExpression, typeof(int)); _ILGenerator.Emit(OpCodes.Clt); _ILGenerator.Emit(OpCodes.Brfalse, lblElse); GenerateStatement(ifThen.ThenBody); _ILGenerator.Emit(OpCodes.Br, lblEnd); _ILGenerator.MarkLabel(lblElse); GenerateStatement(ifThen.ElseBody); _ILGenerator.MarkLabel(lblEnd); } #endregion #region /* * Label gtTrue = il.DefineLabel(); * Label gtFalse = il.DefineLabel(); * * */ #endregion } else if (_statement is For) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 For forLoop = (For)_statement; Assignment assign = new Assignment(); assign.Identifier = forLoop.Identifier; assign.Expression = forLoop.From; GenerateStatement(assign); // jump to the test Label test = _ILGenerator.DefineLabel(); _ILGenerator.Emit(OpCodes.Br, test); // body statement Label body = _ILGenerator.DefineLabel(); _ILGenerator.MarkLabel(body); GenerateStatement(forLoop.Body); // increase x _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); _ILGenerator.Emit(OpCodes.Ldc_I4, 1); _ILGenerator.Emit(OpCodes.Add); SaveIdentifier(forLoop.Identifier, typeof(int)); // check if x is equal to 100 _ILGenerator.MarkLabel(test); _ILGenerator.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); GenerateExpression(forLoop.To, typeof(int)); _ILGenerator.Emit(OpCodes.Blt, body); } else { ExceptionHandler("unable to generate " + _statement.GetType().Name); } }
public void GenerateStatementMethod(Statement _statement) { #region Statement if (_statement is StatementSequence) { StatementSequence _StatementSequence = (StatementSequence)_statement; GenerateStatementMethod(_StatementSequence.Left); GenerateStatementMethod(_StatementSequence.Right); } #endregion #region Declare Variable else if (_statement is DeclareVariable) { // declare a variable in symbol table DeclareVariable declare = (DeclareVariable)_statement; tblIdentifier[declare.Identifier] = _ILMethod.DeclareLocal(GetExpressionTypeMethod(declare.Expression)); // set the initial value Assignment assign = new Assignment(); assign.Identifier = declare.Identifier; assign.Expression = declare.Expression; GenerateStatementMethod(assign); } #endregion #region Assignment else if (_statement is Assignment) { Assignment assign = (Assignment)_statement; GenerateExpressionMethod(assign.Expression, GetExpressionTypeMethod(assign.Expression)); if (GetExpressionTypeMethod(assign.Expression) == typeof(ArithmaticExpression)) { SaveIdentifierMethod(assign.Identifier, typeof(Int32)); } else { SaveIdentifierMethod(assign.Identifier, GetExpressionTypeMethod(assign.Expression)); } } #endregion else if (_statement is DeclareFunction) { DeclareFunction _DeclareFunction = (DeclareFunction)_statement; string strFunctionName = _DeclareFunction.FunctionName; Type ParameterType1 = GetExpressionTypeMethod(_DeclareFunction.Parameter1.Expression); Type ParameterType2 = GetExpressionTypeMethod(_DeclareFunction.Parameter2.Expression); Type ParameterType3 = GetExpressionTypeMethod(_DeclareFunction.Parameter3.Expression); Type[] InputParameters = { ParameterType1, ParameterType2, ParameterType3 }; Type ReturnType = typeof(void); if (_DeclareFunction.ReturnType == "void") { ReturnType = typeof(void); } else if (_DeclareFunction.ReturnType == "string") { ReturnType = typeof(string); } else if (_DeclareFunction.ReturnType == "numeric") { ReturnType = typeof(int); } //FieldBuilder Parameter1 = _typeBuilder.DefineField(_DeclareFunction.Parameter1.Identifier, ParameterType1, FieldAttributes.Private); //FieldBuilder Parameter2 = _typeBuilder.DefineField(_DeclareFunction.Parameter2.Identifier, ParameterType2, FieldAttributes.Private); //FieldBuilder Parameter3 = _typeBuilder.DefineField(_DeclareFunction.Parameter3.Identifier, ParameterType3, FieldAttributes.Private); MethodBuilder NewMethod = _typeBuilder.DefineMethod (strFunctionName, MethodAttributes.Static, ReturnType, InputParameters); //ParameterBuilder poolRefBuilder = NewMethod.DefineParameter(1, ParameterAttributes.In, _DeclareFunction.Parameter1.Identifier); _ILMethod = NewMethod.GetILGenerator(); //tblArguments[_DeclareFunction.Parameter0.Identifier] = _ILMethod. tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType1); GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType1); //_ILMethod.Emit(OpCodes.Starg, 0); tblArguments[_DeclareFunction.Parameter1.Identifier] = _ILMethod.DeclareLocal(ParameterType2); GenerateExpressionMethod(_DeclareFunction.Parameter1.Expression, ParameterType2); //_ILMethod.Emit(OpCodes.Starg, 1); tblArguments[_DeclareFunction.Parameter2.Identifier] = _ILMethod.DeclareLocal(ParameterType3); GenerateExpressionMethod(_DeclareFunction.Parameter2.Expression, ParameterType3); //_ILMethod.Emit(OpCodes.Starg, 2); //GenerateStatementMethod(_DeclareFunction.Body); //_ILMethod.Emit(OpCodes.Ret); } #region write-read else if (_statement is Write) { // for print keyword, call .net method for printscreen GenerateExpressionMethod(((Write)_statement).Expression, typeof(string)); _ILMethod.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (_statement is ReadInput) { // call the readline method and parse input method _ILMethod.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { }, null)); _ILMethod.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); // store the input value in local builder SaveIdentifierMethod(((ReadInput)_statement).Identifier, typeof(int)); } #endregion #region While else if (_statement is While) { While _while = (While)_statement; Label lblTest = _ILMethod.DefineLabel(); Label lblEnd = _ILMethod.DefineLabel(); if (_while.Operand == RelationalOperands.GreaterThan) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Cgt); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.EqualTo) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Ceq); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } else if (_while.Operand == RelationalOperands.LessThan) { _ILMethod.MarkLabel(lblTest); GenerateExpressionMethod(_while.LeftExpression, typeof(int)); GenerateExpressionMethod(_while.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Clt); _ILMethod.Emit(OpCodes.Brfalse, lblEnd); GenerateStatementMethod(_while.Body); _ILMethod.Emit(OpCodes.Br, lblTest); _ILMethod.MarkLabel(lblEnd); } } #endregion #region If-Then else if (_statement is IfThen) { IfThen ifThen = (IfThen)_statement; Label lblElse = _ILMethod.DefineLabel(); Label lblEnd = _ILMethod.DefineLabel(); #region GreaterThan if (ifThen.Operand == RelationalOperands.GreaterThan) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Cgt); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion #region EqualTo else if (ifThen.Operand == RelationalOperands.EqualTo) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Ceq); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion #region LessThan else if (ifThen.Operand == RelationalOperands.LessThan) { GenerateExpressionMethod(ifThen.LeftExpression, typeof(int)); GenerateExpressionMethod(ifThen.RightExpression, typeof(int)); _ILMethod.Emit(OpCodes.Clt); _ILMethod.Emit(OpCodes.Brfalse, lblElse); GenerateStatementMethod(ifThen.ThenBody); _ILMethod.Emit(OpCodes.Br, lblEnd); _ILMethod.MarkLabel(lblElse); GenerateStatementMethod(ifThen.ElseBody); _ILMethod.MarkLabel(lblEnd); } #endregion } #endregion #region for else if (_statement is For) { For forLoop = (For)_statement; Assignment assign = new Assignment(); assign.Identifier = forLoop.Identifier; assign.Expression = forLoop.From; GenerateStatementMethod(assign); Label test = _ILMethod.DefineLabel(); _ILMethod.Emit(OpCodes.Br, test); Label body = _ILMethod.DefineLabel(); _ILMethod.MarkLabel(body); GenerateStatementMethod(forLoop.Body); _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); _ILMethod.Emit(OpCodes.Ldc_I4, 1); _ILMethod.Emit(OpCodes.Add); SaveIdentifierMethod(forLoop.Identifier, typeof(int)); _ILMethod.MarkLabel(test); _ILMethod.Emit(OpCodes.Ldloc, tblIdentifier[forLoop.Identifier]); GenerateExpressionMethod(forLoop.To, typeof(int)); _ILMethod.Emit(OpCodes.Blt, body); } #endregion else { ExceptionHandler("unable to generate " + _statement.GetType().Name); } }
private void GenerateStatement(Tree.Node node) { if (node is Tree.ValueNode) { Tree.ValueNode valueNode = node as Tree.ValueNode; if (valueNode.Value == 0) { il.Emit(OpCodes.Ldc_I4_0); } else if (valueNode.Value == 1) { il.Emit(OpCodes.Ldc_I4_1); } else if (valueNode.Value == 2) { il.Emit(OpCodes.Ldc_I4_2); } else if (valueNode.Value == 3) { il.Emit(OpCodes.Ldc_I4_3); } else if (valueNode.Value == 4) { il.Emit(OpCodes.Ldc_I4_4); } else { il.Emit(OpCodes.Ldc_I4, valueNode.Value); } } else if (node is Tree.VariableNode) { Tree.VariableNode variableNode = node as Tree.VariableNode; if (m_ArgTable[variableNode.Variable.Name] == 0) { il.Emit(OpCodes.Ldarg_0); } else if (m_ArgTable[variableNode.Variable.Name] == 1) { il.Emit(OpCodes.Ldarg_1); } else if (m_ArgTable[variableNode.Variable.Name] == 2) { il.Emit(OpCodes.Ldarg_2); } else if (m_ArgTable[variableNode.Variable.Name] == 3) { il.Emit(OpCodes.Ldarg_3); } else if (m_ArgTable[variableNode.Variable.Name] == 4) { il.Emit(OpCodes.Ldc_I4_4); il.Emit(OpCodes.Ldarg_S); } else { throw new ApplicationException("Unknown argument"); } } else if (node is Tree.FuncNode) { Tree.FuncNode funcNode = node as Tree.FuncNode; Tree.Func func = funcNode.Function; // For these simple maths functions, first emit the arguments if (func is Tree.FuncAdd || func is Tree.FuncSubtract || func is Tree.FuncMultiply || func is Tree.FuncModulo) { GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); } if (func is Tree.FuncAdd) { il.Emit(OpCodes.Add); } else if (func is Tree.FuncMultiply) { il.Emit(OpCodes.Mul); } else if (func is Tree.FuncSubtract) { il.Emit(OpCodes.Sub); } else if (func is Tree.FuncModulo) { il.Emit(OpCodes.Rem); } else if (func is Tree.FuncIf) { Tree.FuncIf funcIf = func as Tree.FuncIf; // Output the first two statements - which we will be comparing GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); Label equalLabel = il.DefineLabel(); Label afterLabel = il.DefineLabel(); OpCode conditionOpcode = OpCodes.Beq_S; if (funcIf.Comparator == Tree.Comparator.Equal) { conditionOpcode = OpCodes.Beq_S; } else if (funcIf.Comparator == Tree.Comparator.GreaterThanOrEqual) { conditionOpcode = OpCodes.Bge_S; } else if (funcIf.Comparator == Tree.Comparator.GreaterThan) { conditionOpcode = OpCodes.Bgt_S; } else { throw new ApplicationException(); } // If [condition], go to next bit. Otherwise do instruction 3, then go to end il.Emit(conditionOpcode, equalLabel); GenerateStatement(funcNode.Children[3]); il.Emit(OpCodes.Br_S, afterLabel); il.MarkLabel(equalLabel); GenerateStatement(funcNode.Children[2]); il.MarkLabel(afterLabel); //LocalBuilder aLocal = il.DeclareLocal(typeof(Int32)); //il.Emit(OpCodes.Stloc, aLocal); //il.Emit(OpCodes.Ldloc, aLocal); } else if (func is Tree.FuncOr) { Tree.FuncOr funcOr = func as Tree.FuncOr; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.Or); } else if (func is Tree.FuncAnd) { Tree.FuncAnd funcAnd = func as Tree.FuncAnd; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.And); } else if (func is Tree.FuncMax) { Tree.FuncMax funcMax = func as Tree.FuncMax; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.Call, typeof(Math).GetMethod("Max", new Type[] { typeof(int), typeof(int) })); } else { throw new ApplicationException("Unknown function"); } } else { throw new ApplicationException("Unknown node"); } }
private void CompileStatement(Node ActiveNode) { if (ActiveNode.Nodes[0].TypeToken == TokenType.KW_IF) { Emit.Label ElseLabel = this.AssemblerGenerator.DefineLabel(); Emit.Label EndIfElseLabel = this.AssemblerGenerator.DefineLabel(); // Вычисляем логическое значение CreateCode(ActiveNode.Nodes[2]); // Если false - переход на метку "ИНАЧЕ" this.AssemblerGenerator.Emit(Emit.OpCodes.Brfalse, ElseLabel); // Разбираем блок "ЕСЛИ" CreateCode(ActiveNode.Nodes[4]); // Переход на метку "Конец блока иначе" this.AssemblerGenerator.Emit(Emit.OpCodes.Br, EndIfElseLabel); // Ставим метку "ИНАЧЕ" this.AssemblerGenerator.MarkLabel(ElseLabel); // Разбираем блок "Иначе" CreateCode(ActiveNode.Nodes[6]); // Ставим метку "Конец блока иначе" this.AssemblerGenerator.MarkLabel(EndIfElseLabel); } if (ActiveNode.Nodes[0].TypeToken == TokenType.KW_WHILE) { Emit.Label TestCycleLabel = this.AssemblerGenerator.DefineLabel(); Emit.Label EndCycleLabel = this.AssemblerGenerator.DefineLabel(); // Начало цикла AssemblerGenerator.MarkLabel(TestCycleLabel); // Вычисляем логическое выражение CreateCode(ActiveNode.Nodes[2]); // Если false переходим на конец цикла this.AssemblerGenerator.Emit(Emit.OpCodes.Brfalse, EndCycleLabel); // Тело цикла CreateCode(ActiveNode.Nodes[4]); // Переход на начало цикла this.AssemblerGenerator.Emit(Emit.OpCodes.Br, TestCycleLabel); // Метка конца цикла this.AssemblerGenerator.MarkLabel(EndCycleLabel); } if (ActiveNode.Nodes[0].TypeToken == TokenType.KW_SYSTEM) { CreateCode(ActiveNode.Nodes[6]); this.AssemblerGenerator.Emit(Emit.OpCodes.Call, typeof(System.Convert).GetMethod("ToString", new System.Type[] { typeof(int) })); this.AssemblerGenerator.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } if (ActiveNode.Nodes[0].TypeToken == TokenType.O_P_BRACKET) { OpenBlockVariables(); CreateCode(ActiveNode.Nodes[1]); CloseBlockVariables(); } if ((ActiveNode.Nodes[0].TypeToken == TokenType.ID) && (ActiveNode.Nodes[1].TypeToken == TokenType.OP_EQUAL)) { CreateCode(ActiveNode.Nodes[2]); Store(ActiveNode.Nodes[0].Value); } if ((ActiveNode.Nodes[0].TypeToken == TokenType.ID) && (ActiveNode.Nodes[1].TypeToken == TokenType.O_S_BRACKET)) { Load(ActiveNode.Nodes[0].Value); CreateCode(ActiveNode.Nodes[2]); CreateCode(ActiveNode.Nodes[5]); AssemblerGenerator.Emit(Emit.OpCodes.Stelem_I4); } }
protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il) { var convention = config.Conventions.OfType <TransactionProxyConvention>().First(); var addValueMethod = typeof(TransactionProxyHelper).GetMethod("AddValue", BindingFlags.Static | BindingFlags.Public); var getValueMethod = typeof(TransactionProxyHelper).GetMethod("GetValue", BindingFlags.Static | BindingFlags.Public); var setCollectionValueMethod = typeof(TransactionProxyHelper).GetMethod("SetCollectionValue", BindingFlags.Static | BindingFlags.Public); var listType = typeof(IEnumerable <>).MakeGenericType(config.BaseType); var enumeratorType = typeof(IEnumerator <>).MakeGenericType(config.BaseType); var enumeratorVariable = il.DeclareLocal(enumeratorType); var currentVariable = il.DeclareLocal(config.BaseType); foreach (var item in convention.TransactionProxyProperties) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, item.ValuesProperty.MemberType.GetConstructor(new Type[] { })); il.Emit(OpCodes.Stfld, item.ValuesProperty.BackingField); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, convention.TargetsField.Field); il.EmitCall(OpCodes.Callvirt, listType.GetMethod("GetEnumerator"), null); il.Emit(OpCodes.Stloc, enumeratorVariable); var loopLabel = il.DefineLabel(); var nextLabel = il.DefineLabel(); var tryBlock = il.BeginExceptionBlock(); il.MarkLabel(loopLabel); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext"), null); il.Emit(OpCodes.Brfalse, nextLabel); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, enumeratorType.GetProperty("Current").GetGetMethod(), null); il.Emit(OpCodes.Stloc, currentVariable); foreach (var item in convention.TransactionProxyProperties) { il.Emit(OpCodes.Ldloc, currentVariable); il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null); il.Emit(OpCodes.Ldloc, currentVariable); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField); il.EmitCall(OpCodes.Call, addValueMethod.MakeGenericMethod(item.Property.PropertyType, config.BaseType), null); } il.Emit(OpCodes.Br, loopLabel); var endFinally = il.DefineLabel(); il.BeginFinallyBlock(); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, endFinally); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"), null); il.MarkLabel(endFinally); il.EndExceptionBlock(); il.MarkLabel(nextLabel); foreach (var item in convention.TransactionProxyProperties) { Type itemType; if (IsCollectionType(item.Property.PropertyType, out itemType)) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null); il.EmitCall(OpCodes.Call, setCollectionValueMethod.MakeGenericMethod(itemType, item.Property.PropertyType, config.BaseType), null); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField); il.EmitCall(OpCodes.Call, getValueMethod.MakeGenericMethod(item.Property.PropertyType, config.BaseType), null); il.EmitCall(OpCodes.Callvirt, item.Property.GetSetMethod(true), null); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField); il.EmitCall(OpCodes.Callvirt, item.ValuesProperty.BackingField.FieldType.GetProperty("Count").GetGetMethod(), null); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); il.EmitCall(OpCodes.Callvirt, item.HasMultipleValuesProperty.PropertySetMethod, null); } il.Emit(OpCodes.Ret); }
public void Intercept(DynamicMember parent, System.Reflection.Emit.MethodBuilder builder, System.Reflection.Emit.ILGenerator generator, ref Label returnLabel) { var prop = parent as DynamicProperty; var originalReturn = returnLabel; bool valueType = false; var compareMethod = prop.MemberType.GetMethod("op_Equality", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public); if (compareMethod == null) { compareMethod = typeof(object).GetMethod("Equals", BindingFlags.Static | BindingFlags.Public); valueType = true; } generator.Emit(OpCodes.Nop); generator.Emit(OpCodes.Ldarg_1); if (valueType) { generator.Emit(OpCodes.Box, prop.MemberType); } if (!prop.IsOverride) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, prop.BackingField); } else { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Call, prop.PropertyGetMethod); } if (valueType) { generator.Emit(OpCodes.Box, prop.MemberType); } var endlabel = generator.DefineLabel(); generator.Emit(OpCodes.Call, compareMethod); generator.Emit(OpCodes.Ldc_I4_0); generator.Emit(OpCodes.Ceq); generator.Emit(OpCodes.Brfalse_S, returnLabel); generator.Emit(OpCodes.Br_S, endlabel); returnLabel = generator.DefineLabel(); generator.MarkLabel(returnLabel); var raiseMethod = prop.DynamicTypeBuilder.DynamicMembers .OfType <RaisePropertyChangedMethod>() .Select(p => p.Method) .OfType <MethodInfo>() .FirstOrDefault(); if (raiseMethod == null) { raiseMethod = prop.DynamicTypeBuilder.BaseType.GetMethod("OnPropertyChanged", BindingFlags.NonPublic | BindingFlags.Instance); } if (raiseMethod == null) { #if (SILVERLIGHT) throw new MissingMemberException(string.Format("Missing Member {1} on type {0}", builder.DeclaringType.Name, "PropertyChanged")); #else throw new MissingMemberException(builder.DeclaringType.Name, "PropertyChanged"); #endif } generator.Emit(OpCodes.Nop); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldstr, prop.MemberName); generator.Emit(OpCodes.Callvirt, raiseMethod); generator.Emit(OpCodes.Br_S, originalReturn); generator.MarkLabel(endlabel); }
protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il) { var convention = config.Conventions.OfType <TransactionProxyConvention>().First(); var listType = typeof(IEnumerable <>).MakeGenericType(config.BaseType); var enumeratorType = typeof(IEnumerator <>).MakeGenericType(config.BaseType); var enumeratorVariable = il.DeclareLocal(enumeratorType); var currentVariable = il.DeclareLocal(config.BaseType); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, convention.TargetsField.Field); il.EmitCall(OpCodes.Callvirt, listType.GetMethod("GetEnumerator"), null); il.Emit(OpCodes.Stloc, enumeratorVariable); var loopLabel = il.DefineLabel(); var nextLabel = il.DefineLabel(); var tryBlock = il.BeginExceptionBlock(); il.MarkLabel(loopLabel); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext"), null); il.Emit(OpCodes.Brfalse, nextLabel); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, enumeratorType.GetProperty("Current").GetGetMethod(), null); il.Emit(OpCodes.Stloc, currentVariable); foreach (var item in convention.TransactionProxyProperties) { var done = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, item.HasMultipleValuesProperty.BackingField); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, done); il.Emit(OpCodes.Ldloc, currentVariable); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null); il.EmitCall(OpCodes.Callvirt, item.Property.GetSetMethod(true), null); il.MarkLabel(done); } il.Emit(OpCodes.Br, loopLabel); var endFinally = il.DefineLabel(); il.BeginFinallyBlock(); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brtrue_S, endFinally); il.Emit(OpCodes.Ldloc, enumeratorVariable); il.EmitCall(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"), null); il.MarkLabel(endFinally); il.EndExceptionBlock(); il.MarkLabel(nextLabel); il.Emit(OpCodes.Ret); }
private void GenerateStatement(Expression pStatement, Type pExpectedType) { if (pStatement is DeclareVar) { DeclareVar curStmnt = (DeclareVar)pStatement; DeclareSymbolInTable(curStmnt.Identifier, curStmnt.GetSystemType()); } else if (pStatement is ReadInt) { ReadInt curStmnt = (ReadInt)pStatement; _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("ReadLine", typeof(String))); _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("Parse", typeof(Int32))); ValidateSymbolType(curStmnt._Identifier, typeof(Int32)); _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); } else if (pStatement is StringLiteral) { StringLiteral curStmnt = (StringLiteral)pStatement; _ilGenerator.Emit(Emit.OpCodes.Ldstr, curStmnt._Value); if (pExpectedType != typeof(String)) { throw new Exception("can't coerce a " + typeof(Int32).Name + " to a " + pExpectedType.Name); } } else if (pStatement is IntLiteral) { IntLiteral curStmnt = (IntLiteral)pStatement; //Sample ASM: IL_0001: ldc.i4.3 (pushes 3 onto stack) _ilGenerator.Emit(Emit.OpCodes.Ldc_I4, curStmnt._Value); //Casting Possibility if (pExpectedType != typeof(Int32)) { if (pExpectedType == typeof(String)) { _ilGenerator.Emit(Emit.OpCodes.Box, typeof(Int32)); _ilGenerator.Emit(Emit.OpCodes.Callvirt, GetMSILMethod("toString", null)); } else { throw new Exception("can't coerce a " + typeof(Int32).Name + " to a " + pExpectedType.Name); } } } else if (pStatement is Variable) { Variable curStmnt = (Variable)pStatement; _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); if (pExpectedType != TypeOfExpression(pStatement)) { if (TypeOfExpression(pStatement) == typeof(Int32) && pExpectedType == typeof(String)) { _ilGenerator.Emit(Emit.OpCodes.Box, typeof(Int32)); _ilGenerator.Emit(Emit.OpCodes.Callvirt, GetMSILMethod("toString", null)); } else { throw new Exception("can't coerce a " + TypeOfExpression(pStatement).Name + " to a " + pExpectedType.Name); } } } else if (pStatement is LinkedList) { LinkedList seq = (LinkedList)pStatement; GenerateStatement(seq.First, null); GenerateStatement(seq.Second, null); } else if (pStatement is Assign) { //retrieve info about variable, including address, type //LHS addrs <--addr; //LHS type <-- type; //getToken(); //match(TK_ASSIGN); //a = b+c; //push b //push c //add //pop a Assign curStmnt = (Assign)pStatement; GenerateStatement(curStmnt._Expression, TypeOfExpression(curStmnt._Expression)); //ValidateSymbolType(curStmnt._Identifier, TypeOfExpression(curStmnt._Expression)); //Pops the current value from the top of the evaluation stack and stores it in a the local variable list at index 0. _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); } else if (pStatement is Print) { Print curStmnt = (Print)pStatement; GenerateStatement(curStmnt._Expr, TypeOfExpression(curStmnt._Expr)); _ilGenerator.Emit(Emit.OpCodes.Call, GetMSILMethod("Print", TypeOfExpression(curStmnt._Expr))); } else if (pStatement is ForLoop) { ForLoop curStmnt = (ForLoop)pStatement; Assign assign = new Assign(curStmnt._Identifier, curStmnt._From, -1); GenerateStatement(assign, null); // jump to the test Emit.Label test = _ilGenerator.DefineLabel(); Emit.Label body = _ilGenerator.DefineLabel(); _ilGenerator.Emit(Emit.OpCodes.Br, test); _ilGenerator.MarkLabel(body); GenerateStatement(curStmnt._Body, null); // to (increment the value of x) _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); _ilGenerator.Emit(Emit.OpCodes.Ldc_I4, 1); _ilGenerator.Emit(Emit.OpCodes.Add); ValidateSymbolType(curStmnt._Identifier, typeof(Int32)); _ilGenerator.Emit(Emit.OpCodes.Stloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); _ilGenerator.MarkLabel(test); _ilGenerator.Emit(Emit.OpCodes.Ldloc, GetValueFromSymbolTable(curStmnt._Identifier, -1)); GenerateStatement(curStmnt._To, typeof(Int32)); _ilGenerator.Emit(Emit.OpCodes.Blt, body); } else { throw new Exception("don't know how to generate a " + pStatement.GetType().Name); } }
///<inheritdoc/> public override void DefineLabelPosition(ILLabel label) { Generator.MarkLabel(label.UnderlyingLabel); }