/// <summary> /// Loads a value of type�native int�as a�native int�onto the evaluation stack indirectly. /// </summary> public FluentIlGenerator Ldind_I() { IlGenerator.Emit(OpCodes.Ldind_I); return(this); }
/// <summary> /// Generate code for the entrypoint function /// </summary> public void GenerateCode(ASTNode node) { #region Early testing //MethodInfo stringtoint = typeof(Convert).GetMethod("ToInt32", new[] { typeof(string) }); //ILGenerator generator = EntryPoint.GetILGenerator(); #region Testing built in functions #region testing print //generator.Emit(OpCodes.Ldstr, "Hello World"); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["print"]); #endregion #region testing printi //generator.Emit(OpCodes.Ldc_I4, 255); //generator.Emit(OpCodes.Call,BuiltInFunctiontoBuilder["printi"]); #endregion #region testing printline //generator.Emit(OpCodes.Ldstr, "Hello World"); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region testing flush //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["flush"]); #endregion #region testing getchar //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getchar"]); //generator.DeclareLocal(typeof (string)); //generator.Emit(OpCodes.Stloc_0); //generator.Emit(OpCodes.Ldloc_0); //generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)},null)); #endregion #region testing getline //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region testing ord //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["ord"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]); #endregion #region testing chr //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, stringtoint); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["chr"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region testing size //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["size"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]); #endregion #region testing substring //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Ldc_I4_0); //generator.Emit(OpCodes.Ldc_I4_2); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["substring"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region testing concat //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["getline"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["concat"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region testing not //generator.Emit(OpCodes.Ldc_I4_0); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["not"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]); //generator.Emit(OpCodes.Ldc_I4_2); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["not"]); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printi"]); #endregion #region testing exit //generator.Emit(OpCodes.Ldc_I4_0); //generator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["exit"]); #endregion #endregion #region Testing Type and Array Creation //TypeBuilder builder = ILModule.DefineType("Person"); //FieldBuilder fieldBuilder0 = builder.DefineField("Name", typeof(string), FieldAttributes.Public); //FieldBuilder fieldBuilder1 = builder.DefineField("Age", typeof(int), FieldAttributes.Public); //ConstructorBuilder ctor = builder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, // new Type[] { typeof(string), typeof(int) }); //ILGenerator ctorIlgen = ctor.GetILGenerator(); //ctorIlgen.Emit(OpCodes.Ldarg_0); //ctorIlgen.Emit(OpCodes.Ldarg_1); //ctorIlgen.Emit(OpCodes.Stfld, fieldBuilder0); //ctorIlgen.Emit(OpCodes.Ldarg_0); //ctorIlgen.Emit(OpCodes.Ldarg_2); //ctorIlgen.Emit(OpCodes.Stfld, fieldBuilder1); //ctorIlgen.Emit(OpCodes.Ret); //builder.CreateType(); //LocalBuilder person = IlGenerator.DeclareLocal(builder); //LocalBuilder arrayofperson = IlGenerator.DeclareLocal(builder.MakeArrayType()); //IlGenerator.Emit(OpCodes.Ldstr, "Frank"); //IlGenerator.Emit(OpCodes.Ldc_I4, 22); //IlGenerator.Emit(OpCodes.Newobj, ctor); //IlGenerator.Emit(OpCodes.Stloc_0); //IlGenerator.Emit(OpCodes.Ldloc_0); //IlGenerator.Emit(OpCodes.Ldfld, fieldBuilder0); //IlGenerator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); //IlGenerator.Emit(OpCodes.Ldc_I4_1); //IlGenerator.Emit(OpCodes.Newarr, builder); //IlGenerator.Emit(OpCodes.Stloc_1); //IlGenerator.Emit(OpCodes.Ldloc_1); //IlGenerator.Emit(OpCodes.Ldc_I4_0); //IlGenerator.Emit(OpCodes.Ldloc_0); //IlGenerator.Emit(OpCodes.Stelem, builder); //IlGenerator.Emit(OpCodes.Ldloc_1); //IlGenerator.Emit(OpCodes.Ldc_I4_0); //IlGenerator.Emit(OpCodes.Ldelem, builder); //IlGenerator.Emit(OpCodes.Ldfld, fieldBuilder0); //IlGenerator.Emit(OpCodes.Call, BuiltInFunctiontoBuilder["printline"]); #endregion #region Testing Field Acces an Store #endregion #endregion //All the needed resources to handle exceptions Type exception = typeof(Exception); MethodInfo geterroroutput = typeof(Console).GetProperty("Error").GetGetMethod(); MethodInfo writeline = typeof(TextWriter).GetMethod("WriteLine", new [] { typeof(string), typeof(object) }); MethodInfo readline = typeof(Console).GetMethod("ReadLine"); MethodInfo gettype = typeof(Exception).GetMethod("GetType"); MethodInfo exit = typeof(Environment).GetMethod("Exit", new [] { typeof(int) }); LocalBuilder exceptioninstance = IlGenerator.DeclareLocal(exception); //To enclose all the generated code in an enormous try IlGenerator.BeginExceptionBlock(); node.GenerateCode(this); // To handle exceptions thrown by IL execution code IlGenerator.BeginCatchBlock(exception); //the launched exception will be in the top of the stack so we must store it IlGenerator.Emit(OpCodes.Stloc, exceptioninstance); //Getting the std error output IlGenerator.Emit(OpCodes.Call, geterroroutput); //Get the parameters to report to the error output IlGenerator.Emit(OpCodes.Ldstr, "\nException of type '{0}' was thrown"); IlGenerator.Emit(OpCodes.Ldloc, exceptioninstance); IlGenerator.Emit(OpCodes.Call, gettype); //Calling the writeline method of the error output IlGenerator.Emit(OpCodes.Call, writeline); // Set a readline son the user can see the exception thrown, comment this line if there is any problem //IlGenerator.EmitCall(OpCodes.Call, readline, null); //Exiting with code 1 IlGenerator.Emit(OpCodes.Ldc_I4_1); IlGenerator.Emit(OpCodes.Call, exit); //Exception management is done IlGenerator.EndExceptionBlock(); // No exception was thrown finish with exit code 0 IlGenerator.Emit(OpCodes.Ldc_I4_0); IlGenerator.Emit(OpCodes.Call, exit); // Don't forget the ret IlGenerator.Emit(OpCodes.Ret); Program.CreateType(); }
/// <summary> /// Replaces the value of a static field with a value from the evaluation stack. /// </summary> public FluentIlGenerator Stsfld(FieldInfo fieldInfo) { IlGenerator.Emit(OpCodes.Stsfld, fieldInfo); return(this); }
/// <summary> /// Computes the bitwise NAND of two values and pushes the result onto the evaluation stack. /// </summary> public FluentIlGenerator Nand() { IlGenerator.Emit(OpCodes.And); IlGenerator.Emit(OpCodes.Not); return(this); }
/// <summary> /// Computes the bitwise OR of two values and pushes the result onto the evaluation stack. /// </summary> public FluentIlGenerator Or() { IlGenerator.Emit(OpCodes.Or); return(this); }
/// <summary> /// Loads the local variable at index 3 onto the evaluation stack. /// </summary> public FluentIlGenerator Ldloc_3() { IlGenerator.Emit(OpCodes.Ldloc_3); return(this); }
/// <summary> /// Loads the address of the local variable at a specific index onto the evaluation stack. /// </summary> public FluentIlGenerator Ldloca(short index) { IlGenerator.Emit(OpCodes.Ldloca, index); return(this); }
/// <summary> /// Transfers control from the�filter�clause of an exception back to the Common Language Infrastructure (CLI) /// exception handler. /// </summary> public FluentIlGenerator Endfilter() { IlGenerator.Emit(OpCodes.Endfilter); return(this); }
/// <summary> /// Transfers control from the�fault�or�finally�clause of an exception block back to the Common Language /// Infrastructure (CLI) exception handler. /// </summary> public FluentIlGenerator Endfinally() { IlGenerator.Emit(OpCodes.Endfinally); return(this); }
/// <summary> /// Signals the Common Language Infrastructure (CLI) to inform the debugger that a break point has been tripped. /// </summary> public FluentIlGenerator Break() { IlGenerator.Emit(OpCodes.Break); return(this); }
/// <summary> /// Transfers control to a target instruction (short form) if�value�is�true, not null, or non-zero. /// </summary> public FluentIlGenerator Brtrue_S(Label label) { IlGenerator.Emit(OpCodes.Brtrue_S, label); return(this); }
/// <summary> /// Implements a jump table. /// </summary> public FluentIlGenerator Switch(params Label[] labels) { IlGenerator.Emit(OpCodes.Switch, labels); return(this); }
/// <summary> /// Transfers control to a target instruction when two unsigned integer values or unordered float values are not /// equal. /// </summary> public FluentIlGenerator Bne_Un(Label label) { IlGenerator.Emit(OpCodes.Bne_Un, label); return(this); }
/// <summary> /// Exits current method and jumps to specified method. /// </summary> public FluentIlGenerator Jmp(MethodInfo methodInfo) { IlGenerator.Emit(OpCodes.Jmp, methodInfo); return(this); }
/// <summary> /// Pops the current value from the top of the evaluation stack and stores it in a the local variable list at /// index 2. /// </summary> public FluentIlGenerator Stloc_2() { IlGenerator.Emit(OpCodes.Stloc_2); return(this); }
/// <summary> /// Exits a protected region of code, unconditionally transferring control to a target instruction (short form). /// </summary> public FluentIlGenerator Leave_S(Label label) { IlGenerator.Emit(OpCodes.Leave_S, label); return(this); }
/// <summary> /// Pops the current value from the top of the evaluation stack and stores it in a the local variable list at /// index�(short form). /// </summary> public FluentIlGenerator Stloc_S(LocalBuilder localBuilder) { IlGenerator.Emit(OpCodes.Stloc_S, localBuilder); return(this); }
/// <summary> /// Transfers control to a target instruction if the first value is greater than or equal to the second value. /// </summary> public FluentIlGenerator Bge(Label label) { IlGenerator.Emit(OpCodes.Bge, label); return(this); }
/// <summary> /// Loads the local variable at a specific index onto the evaluation stack, short form. /// </summary> public FluentIlGenerator Ldloc_S(byte index) { IlGenerator.Emit(OpCodes.Ldloc_S, index); return(this); }
/// <summary> /// Pushes an object reference to a new zero-based, one-dimensional array whose elements are of a specific type /// onto the evaluation stack. /// </summary> public FluentIlGenerator Newarr(Type elementType) { IlGenerator.Emit(OpCodes.Newarr); return(this); }
/// <summary> /// Loads the address of the local variable at a specific index onto the evaluation stack. /// </summary> public FluentIlGenerator Ldloca(LocalBuilder localBuilder) { IlGenerator.Emit(OpCodes.Ldloca, localBuilder); return(this); }
/// <summary> /// Replaces the array element at a given index with the object ref value (type�O) on the evaluation stack. /// </summary> public FluentIlGenerator Stelem_Ref() { IlGenerator.Emit(OpCodes.Stelem_Ref); return(this); }
/// <summary> /// Computes the bitwise XNOR of the top two values on the evaluation stack, pushing the result onto the evaluation /// stack. /// </summary> public FluentIlGenerator Xnor() { IlGenerator.Emit(OpCodes.Xor); IlGenerator.Emit(OpCodes.Not); return(this); }
/// <summary> /// Loads the element at a specified array index onto the top of the evaluation stack as the type specified in the /// instruction. /// </summary> public FluentIlGenerator Ldelem(Type type) { IlGenerator.Emit(OpCodes.Ldelem, type); return(this); }
/// <summary> /// Inverts the top value on the evaluation stack, pushing the result onto the evaluation /// stack. /// </summary> public FluentIlGenerator Not() { IlGenerator.Emit(OpCodes.Not); return(this); }
/// <summary> /// Loads the element with type�float32�at a specified array index onto the top of the evaluation stack as type /// F(float). /// </summary> public FluentIlGenerator Ldelem_R4() { IlGenerator.Emit(OpCodes.Ldelem_R4); return(this); }
/// <summary> /// Pushes the address of a static field onto the evaluation stack. /// </summary> public FluentIlGenerator Ldsflda(FieldInfo fieldInfo) { IlGenerator.Emit(OpCodes.Ldsflda, fieldInfo); return(this); }
/// <summary> /// Pops the current value from the top of the evaluation stack and stores it in a the local variable list at a /// specified index. /// </summary> public FluentIlGenerator Stloc(short index) { IlGenerator.Emit(OpCodes.Stloc, index); return(this); }
/// <summary> /// Converts the signed value on top of the evaluation stack to�unsigned native int, throwing�OverflowExceptionon /// overflow. /// </summary> public FluentIlGenerator Conv_Ovf_U() { IlGenerator.Emit(OpCodes.Conv_Ovf_U); return(this); }
/// <summary> /// Stores a value of type�float64�at a supplied address. /// </summary> public FluentIlGenerator Stind_R8() { IlGenerator.Emit(OpCodes.Stind_R8); return(this); }