public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Get .ctor method from operand and get the class associated with it MethodReference ctor = instruction.Operand as MethodReference; TypeReference type = ctor.DeclaringType; // If the object type is native, we ignore the IL object and don't emit a NEWOBJ // After that, we call the .CTOR which will be in runtime // The .CTOR in runtime will also initialize this object if(Util.IsNativeType(type)) { // Create call to .CTOR Instruction call = Instruction.Create(OpCodes.Call, ctor); compiler.HandleInstruction(call, methodData); return; } // Write opcode and class ID int classID = compiler.GetTypeDataFromType(type.Resolve()).Id; methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(classID); // Write CALL to .ctor // Count one extra parameter for the "this" object MethodDefinition methodDef = ctor.Resolve(); int ctorID = compiler.GetMethodID(methodDef); if (ctorID == -1) ctorID = compiler.ProcessMethod(methodDef); methodData.AddInstruction(ctorID); methodData.AddInstruction(ctor.Parameters.Count); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Add instruction with reference to the long index methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(methodData.LongOffset); // Append to longs methodData.AddLong(Convert.ToInt64(instruction.Operand)); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Get field and class data FieldDefinition field = instruction.Operand as FieldDefinition; TypeData classData = compiler.GetTypeDataFromType(field.DeclaringType); // Output opcode followed by field ID methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(classData.GetMemberFieldId(field)); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Get type ID TypeReference type = instruction.Operand as TypeReference; int id = compiler.GetTypeDataFromType(type.Resolve()).Id; // Write opcode and type ID methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(id); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { ParameterDefinition param = instruction.Operand as ParameterDefinition; // Try to write short instruction to save space if (instruction.OpCode.Value == Ops.IL_LDARG || instruction.OpCode.Value == Ops.IL_LDARG_S) methodData.AddInstruction(Ops.IL_LDARG_S); else methodData.AddInstruction(Ops.IL_STARG_S); methodData.AddInstruction(param.Index); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Get field and class data FieldDefinition field = (instruction.Operand as FieldReference).Resolve(); TypeData classData = compiler.GetTypeDataFromType(field.DeclaringType); // Output opcode followed by class ID followed by field ID methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(classData.Id); methodData.AddInstruction(classData.GetStaticFieldId(field)); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { methodData.AddInstruction(instruction.OpCode.Value); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { VariableDefinition varDef = instruction.Operand as VariableDefinition; methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(varDef.Index); }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { // Get destination MethodReference destinationRef = instruction.Operand as MethodReference; string methodName = Util.GetFriendlyMethodName(destinationRef); // Check if it's a special method that should be caught here if (methodName == "ILVM_Asm_Execute2") { // IL code at this point will look like this // LOAD STRING "<assembly code>" // LOAD REGS // CALL ASM.EXECUTE // So we must check if two instructions before this the assembly code is loaded // else we need to throw an error Instruction ldstr = instruction.Previous.Previous; if (ldstr.OpCode != OpCodes.Ldstr) { throw new Exception("Assembly code needs to be directly in the call"); } else { // Prepare assembler string code = ldstr.Operand as string; Assembler asm = compiler.Assembler; int offset = asm.GetOffset(); // Since this is used as a "method" we need to place a return at the end asm.HandleCode(code); asm.HandleInstruction("ret"); int codeSize = asm.GetOffset() - offset; // Write instruction followed by asm offset and asm size methodData.AddInstruction(Ops.OP_RUNTIME_ASM); methodData.AddInstruction(offset); methodData.AddInstruction(codeSize); } return; } // If it's implemented in runtime, emit a special seperate instruction for this if (compiler.IsRuntimeMethod(methodName)) { // Write instruction followed by the runtime method ID methodData.AddInstruction(Ops.OP_RUNTIME_CALL); methodData.AddInstruction(compiler.GetRuntimeMethodID(methodName)); } else { // Get definition from reference MethodDefinition destination = destinationRef.Resolve(); // Lookup the method, if it isn't processed yet, process it int methodId = compiler.GetMethodID(destination); if (methodId == -1) methodId = compiler.ProcessMethod(destination); // If the method is not static, we pass "this" as argument, so we count 1 parameter extra int paramCount = destinationRef.Parameters.Count; if (!destination.IsStatic) paramCount++; // Write instruction followed by the method ID methodData.AddInstruction(instruction.OpCode.Value); methodData.AddInstruction(methodId); methodData.AddInstruction(paramCount); } }
public override void Process(Compiler compiler, MethodData methodData, Instruction instruction) { VariableDefinition param = instruction.Operand as VariableDefinition; methodData.AddInstruction(Ops.IL_LDLOCA_S); methodData.AddInstruction(param.Index); }