/// <summary> /// Code generation completed. /// </summary> protected virtual void EndGenerate() { CodeEmitter.ResolvePatches(); }
internal override void Emit(CodeEmitter ilgen, CodeEmitterLabel label) { ilgen.EmitBrfalse(label); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Ldloc, (CodeEmitterLocal)context[Name]); }
internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(opcode); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Castclass, context.ClassLoader.LoadClassByDottedName(Class).TypeAsBaseType); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { context.ClassLoader.LoadClassByDottedName(Class).EmitRunClassConstructor(ilgen); }
internal void Emit(ClassLoaderWrapper loader, CodeEmitter ilgen) { Generate(new CodeGenContext(loader), ilgen); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, StaticCompiler.GetFieldForMapXml(context.ClassLoader, Class, Name, Sig).GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.EmitLdc_I4(val); }
internal abstract void Generate(CodeGenContext context, CodeEmitter ilgen);
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Ldflda, StaticCompiler.GetFieldForMapXml(context.ClassLoader, Class, Name, Sig).GetField()); }
private NativeInvokerBytecodeGenerator(LambdaForm lambdaForm, MethodType invokerType) { if (invokerType != invokerType.basicType()) { throw new BailoutException(Bailout.NotBasicType, invokerType); } this.lambdaForm = lambdaForm; this.invokerType = invokerType; this.delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(invokerType); MethodInfo mi = MethodHandleUtil.GetDelegateInvokeMethod(delegateType); Type[] paramTypes = MethodHandleUtil.GetParameterTypes(typeof(object[]), mi); // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly) this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType, paramTypes, typeof(object).Module, true); this.ilgen = CodeEmitter.Create(this.dm); if (invokerType.parameterCount() > MethodHandleUtil.MaxArity) { this.packedArgType = paramTypes[paramTypes.Length - 1]; this.packedArgPos = paramTypes.Length - 1; } else { this.packedArgPos = Int32.MaxValue; } locals = new CodeEmitterLocal[lambdaForm.names.Length]; for (int i = lambdaForm._arity(); i < lambdaForm.names.Length; i++) { Name name = lambdaForm.names[i]; if (name.index() != i) { throw new BailoutException(Bailout.PreconditionViolated, "name.index() != i"); } switch (name.typeChar()) { case 'L': locals[i] = ilgen.DeclareLocal(Types.Object); break; case 'I': locals[i] = ilgen.DeclareLocal(Types.Int32); break; case 'J': locals[i] = ilgen.DeclareLocal(Types.Int64); break; case 'F': locals[i] = ilgen.DeclareLocal(Types.Single); break; case 'D': locals[i] = ilgen.DeclareLocal(Types.Double); break; case 'V': break; default: throw new BailoutException(Bailout.PreconditionViolated, "Unsupported typeChar(): " + name.typeChar()); } } }
public static EmitSerializer <TObject> Generate <TObject>() where TObject : class, new() { var propertiesWriter = new DynamicMethod( "WriteProperties", null, new Type[] { typeof(Stream), typeof(TObject) }, typeof(EmitSerializer <TObject>)); var writerIlGenerator = propertiesWriter.GetILGenerator(); var writerEmitter = new CodeEmitter(writerIlGenerator); var propertiesReader = new DynamicMethod( "ReadProperties", null, new Type[] { typeof(Stream), typeof(TObject) }, typeof(EmitSerializer <TObject>)); var readerIlGenerator = propertiesReader.GetILGenerator(); var readerEmitter = new CodeEmitter(readerIlGenerator); var properties = typeof(TObject).GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var property in properties) { if (property.PropertyType == typeof(byte)) { writerEmitter.EmitWriteBytePropertyCode(property); readerEmitter.EmitReadBytePropertyCode(property); } else if (TypesInfo.PrimitiveTypes.Contains(property.PropertyType)) { writerEmitter.EmitWritePrimitiveTypePropertyCode(property); readerEmitter.EmitReadPrimitiveTypePropertyCode(property); } else if (property.PropertyType == typeof(Guid)) { writerEmitter.EmitWriteGuidPropertyCode(property); readerEmitter.EmitReadGuidPropertyCode(property); } else if (property.PropertyType == typeof(DateTime)) { writerEmitter.EmitWriteDateTimePropertyCode(property); readerEmitter.EmitReadDateTimePropertyCode(property); } else if (property.PropertyType == typeof(DateTimeOffset)) { writerEmitter.EmitWriteDateTimeOffsetPropertyCode(property); readerEmitter.EmitReadDateTimeOffsetPropertyCode(property); } else if (property.PropertyType == typeof(string)) { writerEmitter.EmitWriteStringPropertyCode(property); readerEmitter.EmitReadStringPropertyCode(property); } else if (property.PropertyType.IsArray) { writerEmitter.EmitWriteArrayPropertyCode(property); readerEmitter.EmitReadArrayPropertyCode(property); } else if (GenericCollectionInfo.IsICollectionType(property.PropertyType)) { writerEmitter.EmitWriteCollectionPropertyCode(property); readerEmitter.EmitReadCollectionPropertyCode(property); } else if (TypesInfo.IsNullable(property.PropertyType)) { writerEmitter.EmitWriteNullablePropertyCode(property); readerEmitter.EmitReadNullablePropertyCode(property); } else { throw new NotImplementedException( "Not supported property: " + property.PropertyType.ToString() + " " + property.Name); } } writerEmitter.EmitMethodReturn(); readerEmitter.EmitMethodReturn(); var writePropertiesDelegate = (Action <Stream, TObject>)propertiesWriter.CreateDelegate(typeof(Action <Stream, TObject>)); var readPropertiesDelegate = (Action <Stream, TObject>)propertiesReader.CreateDelegate(typeof(Action <Stream, TObject>)); return(new EmitSerializer <TObject>(writePropertiesDelegate, readPropertiesDelegate)); }
public override void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter m) { switch (Architecture.Name) { case "mips-be-32": // MIPS ELF ABI: r25 is _always_ set to the address of a procedure on entry. m.Assign(proc.Frame.EnsureRegister(Architecture.GetRegister(25)), Constant.Word32((uint)addr.ToLinear())); break; } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Ldstr, Value); }
internal FastFieldReflector(java.io.ObjectStreamField[] fields) { this.fields = fields; TypeWrapper tw = null; foreach (java.io.ObjectStreamField field in fields) { FieldWrapper fw = GetFieldWrapper(field); if (fw != null) { if (tw == null) { tw = fw.DeclaringType; } else if (tw != fw.DeclaringType) { // pre-condition is that all fields are from the same Type! throw new java.lang.InternalError(); } } } if (tw == null) { objFieldGetter = objFieldSetter = objDummy; primFieldGetter = primFieldSetter = primDummy; } else { try { tw.Finish(); } catch (RetargetableJavaException x) { throw x.ToJava(); } DynamicMethod dmObjGetter = DynamicMethodUtils.Create("__<ObjFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); DynamicMethod dmPrimGetter = DynamicMethodUtils.Create("__<PrimFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); DynamicMethod dmObjSetter = DynamicMethodUtils.Create("__<ObjFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); DynamicMethod dmPrimSetter = DynamicMethodUtils.Create("__<PrimFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); CodeEmitter ilgenObjGetter = CodeEmitter.Create(dmObjGetter); CodeEmitter ilgenPrimGetter = CodeEmitter.Create(dmPrimGetter); CodeEmitter ilgenObjSetter = CodeEmitter.Create(dmObjSetter); CodeEmitter ilgenPrimSetter = CodeEmitter.Create(dmPrimSetter); // we want the getters to be verifiable (because writeObject can be used from partial trust), // so we create a local to hold the properly typed object reference CodeEmitterLocal objGetterThis = ilgenObjGetter.DeclareLocal(tw.TypeAsBaseType); CodeEmitterLocal primGetterThis = ilgenPrimGetter.DeclareLocal(tw.TypeAsBaseType); ilgenObjGetter.Emit(OpCodes.Ldarg_0); ilgenObjGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenObjGetter.Emit(OpCodes.Stloc, objGetterThis); ilgenPrimGetter.Emit(OpCodes.Ldarg_0); ilgenPrimGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenPrimGetter.Emit(OpCodes.Stloc, primGetterThis); foreach (java.io.ObjectStreamField field in fields) { FieldWrapper fw = GetFieldWrapper(field); if (fw == null) { continue; } fw.ResolveField(); TypeWrapper fieldType = fw.FieldTypeWrapper; try { fieldType = fieldType.EnsureLoadable(tw.GetClassLoader()); fieldType.Finish(); } catch (RetargetableJavaException x) { throw x.ToJava(); } if (fieldType.IsPrimitive) { // Getter ilgenPrimGetter.Emit(OpCodes.Ldarg_1); ilgenPrimGetter.EmitLdc_I4(field.getOffset()); ilgenPrimGetter.Emit(OpCodes.Ldloc, primGetterThis); fw.EmitGet(ilgenPrimGetter); if (fieldType == PrimitiveTypeWrapper.BYTE) { ilgenPrimGetter.Emit(OpCodes.Call, WriteByteMethod); } else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) { ilgenPrimGetter.Emit(OpCodes.Call, WriteBooleanMethod); } else if (fieldType == PrimitiveTypeWrapper.CHAR) { ilgenPrimGetter.Emit(OpCodes.Call, WriteCharMethod); } else if (fieldType == PrimitiveTypeWrapper.SHORT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteShortMethod); } else if (fieldType == PrimitiveTypeWrapper.INT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteIntMethod); } else if (fieldType == PrimitiveTypeWrapper.FLOAT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteFloatMethod); } else if (fieldType == PrimitiveTypeWrapper.LONG) { ilgenPrimGetter.Emit(OpCodes.Call, WriteLongMethod); } else if (fieldType == PrimitiveTypeWrapper.DOUBLE) { ilgenPrimGetter.Emit(OpCodes.Call, WriteDoubleMethod); } else { throw new java.lang.InternalError(); } // Setter ilgenPrimSetter.Emit(OpCodes.Ldarg_0); ilgenPrimSetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenPrimSetter.Emit(OpCodes.Ldarg_1); ilgenPrimSetter.EmitLdc_I4(field.getOffset()); if (fieldType == PrimitiveTypeWrapper.BYTE) { ilgenPrimSetter.Emit(OpCodes.Call, ReadByteMethod); } else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) { ilgenPrimSetter.Emit(OpCodes.Call, ReadBooleanMethod); } else if (fieldType == PrimitiveTypeWrapper.CHAR) { ilgenPrimSetter.Emit(OpCodes.Call, ReadCharMethod); } else if (fieldType == PrimitiveTypeWrapper.SHORT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadShortMethod); } else if (fieldType == PrimitiveTypeWrapper.INT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadIntMethod); } else if (fieldType == PrimitiveTypeWrapper.FLOAT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadFloatMethod); } else if (fieldType == PrimitiveTypeWrapper.LONG) { ilgenPrimSetter.Emit(OpCodes.Call, ReadLongMethod); } else if (fieldType == PrimitiveTypeWrapper.DOUBLE) { ilgenPrimSetter.Emit(OpCodes.Call, ReadDoubleMethod); } else { throw new java.lang.InternalError(); } fw.EmitSet(ilgenPrimSetter); } else { // Getter ilgenObjGetter.Emit(OpCodes.Ldarg_1); ilgenObjGetter.EmitLdc_I4(field.getOffset()); ilgenObjGetter.Emit(OpCodes.Ldloc, objGetterThis); fw.EmitGet(ilgenObjGetter); fieldType.EmitConvSignatureTypeToStackType(ilgenObjGetter); ilgenObjGetter.Emit(OpCodes.Stelem_Ref); // Setter ilgenObjSetter.Emit(OpCodes.Ldarg_0); ilgenObjSetter.Emit(OpCodes.Ldarg_1); ilgenObjSetter.EmitLdc_I4(field.getOffset()); ilgenObjSetter.Emit(OpCodes.Ldelem_Ref); fieldType.EmitCheckcast(ilgenObjSetter); fieldType.EmitConvStackTypeToSignatureType(ilgenObjSetter, null); fw.EmitSet(ilgenObjSetter); } } ilgenObjGetter.Emit(OpCodes.Ret); ilgenPrimGetter.Emit(OpCodes.Ret); ilgenObjSetter.Emit(OpCodes.Ret); ilgenPrimSetter.Emit(OpCodes.Ret); ilgenObjGetter.DoEmit(); ilgenPrimGetter.DoEmit(); ilgenObjSetter.DoEmit(); ilgenPrimSetter.DoEmit(); objFieldGetter = (ObjFieldGetterSetter)dmObjGetter.CreateDelegate(typeof(ObjFieldGetterSetter)); primFieldGetter = (PrimFieldGetterSetter)dmPrimGetter.CreateDelegate(typeof(PrimFieldGetterSetter)); objFieldSetter = (ObjFieldGetterSetter)dmObjSetter.CreateDelegate(typeof(ObjFieldGetterSetter)); primFieldSetter = (PrimFieldGetterSetter)dmPrimSetter.CreateDelegate(typeof(PrimFieldGetterSetter)); } }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Newarr, context.ClassLoader.FieldTypeWrapperFromSig(Sig).TypeAsArrayType); }
public override void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter m) { m.Assign(proc.Frame.EnsureRegister(Registers.Top), 0); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { CompilerClassLoader.ExceptionMapEmitter emitter = new CompilerClassLoader.ExceptionMapEmitter(mapping); emitter.Emit(context, ilgen); }
public override void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter m) { switch (Architecture.Name) { case "mips-be-32": case "mips-le-32": // MIPS ELF ABI: r25 is _always_ set to the address of a procedure on entry. m.Assign(proc.Frame.EnsureRegister(Architecture.GetRegister("r25") !), Constant.Word32((uint)addr.ToLinear())); break; case "mips-be-64": case "mips-le-64": // MIPS ELF ABI: r25 is _always_ set to the address of a procedure on entry. m.Assign(proc.Frame.EnsureRegister(Architecture.GetRegister("r25") !), Constant.Word64((uint)addr.ToLinear())); break; case "x86-protected-32": case "x86-protected-64": m.Assign( proc.Frame.EnsureRegister(Architecture.FpuStackRegister), 0); break; case "zSeries": // Stack parameters are passed in starting at offset +160 from the // stack; everything at lower addresses is local to the called procedure's // frame. m.Assign( proc.Frame.EnsureRegister(Architecture.GetRegister("r15") !), m.ISub( proc.Frame.FramePointer, Constant.Int(proc.Frame.FramePointer.DataType, 160))); break; } }
internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen) { Debug.Assert(Name != null); if (Name == ".ctor") { Debug.Assert(Class == null && type != null); Type[] argTypes = context.ClassLoader.ArgTypeListFromSig(Sig); ConstructorInfo ci = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null); if (ci == null) { throw new InvalidOperationException("Missing .ctor: " + type + "..ctor" + Sig); } ilgen.Emit(opcode, ci); } else { Debug.Assert(Class == null ^ type == null); if (Class != null) { Debug.Assert(Sig != null); MethodWrapper method = context.ClassLoader.LoadClassByDottedName(Class).GetMethodWrapper(Name, Sig, false); if (method == null) { throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig); } method.Link(); // TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does, // it would be nice if we could avoid this duplication... TypeWrapper[] argTypeWrappers = method.GetParameters(); for (int i = 0; i < argTypeWrappers.Length; i++) { if (argTypeWrappers[i].IsGhost) { CodeEmitterLocal[] temps = new CodeEmitterLocal[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)]; for (int j = temps.Length - 1; j >= 0; j--) { TypeWrapper tw; if (method.IsStatic) { tw = argTypeWrappers[j]; } else { if (j == 0) { tw = method.DeclaringType; } else { tw = argTypeWrappers[j - 1]; } } if (tw.IsGhost) { tw.EmitConvStackTypeToSignatureType(ilgen, null); } temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType); ilgen.Emit(OpCodes.Stloc, temps[j]); } for (int j = 0; j < temps.Length; j++) { ilgen.Emit(OpCodes.Ldloc, temps[j]); } break; } } if (opcode.Value == OpCodes.Call.Value) { method.EmitCall(ilgen); } else if (opcode.Value == OpCodes.Callvirt.Value) { method.EmitCallvirt(ilgen); } else if (opcode.Value == OpCodes.Newobj.Value) { method.EmitNewobj(ilgen); } else { // ldftn or ldvirtftn ilgen.Emit(opcode, (MethodInfo)method.GetMethod()); } } else { Type[] argTypes; if (Sig.StartsWith("(")) { argTypes = context.ClassLoader.ArgTypeListFromSig(Sig); } else if (Sig == "") { argTypes = Type.EmptyTypes; } else { string[] types = Sig.Split(';'); argTypes = new Type[types.Length]; for (int i = 0; i < types.Length; i++) { argTypes[i] = StaticCompiler.GetTypeForMapXml(context.ClassLoader, types[i]); } } MethodInfo mi = StaticCompiler.GetTypeForMapXml(context.ClassLoader, type).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null); if (mi == null) { throw new InvalidOperationException("Missing method: " + type + "." + Name + Sig); } ilgen.Emit(opcode, mi); } } }
public void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter emitter) { throw new NotImplementedException(); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.Emit(OpCodes.Pop); }
public void EmitStringInstruction(X86Instruction instr, CodeEmitter emitter) { this.emitter = emitter; bool incSi = false; bool incDi = false; this.instrCur = instr; switch (instrCur.code) { default: throw new ApplicationException("NYI"); case Mnemonic.cmps: case Mnemonic.cmpsb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi()))); incSi = true; incDi = true; break; case Mnemonic.lods: case Mnemonic.lodsb: emitter.Assign(RegAl, MemSi()); incSi = true; break; case Mnemonic.movs: case Mnemonic.movsb: { Identifier tmp = emitter.Frame.CreateTemporary(instrCur.dataWidth); emitter.Assign(tmp, MemSi()); emitter.Store(MemDi(), tmp); incSi = true; incDi = true; break; } case Mnemonic.ins: case Mnemonic.insb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.Store(MemDi(), host.PseudoProc("__in", instrCur.dataWidth, regDX)); incDi = true; break; } case Mnemonic.outs: case Mnemonic.outsb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl); incSi = true; break; } case Mnemonic.scas: case Mnemonic.scasb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, RegAl, MemDi()))); incDi = true; break; case Mnemonic.stos: case Mnemonic.stosb: emitter.Store(MemDi(), RegAl); incDi = true; break; } if (incSi) { emitter.Assign(RegSi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegSi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } if (incDi) { emitter.Assign(RegDi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegDi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } }
internal abstract void Emit(CodeEmitter ilgen, CodeEmitterLabel label);
public override void InjectProcedureEntryStatements(Procedure proc, Address addr, CodeEmitter m) { var ptrA5World = EnsureA5Pointer(); var a5 = proc.Frame.EnsureRegister(Registers.a5); m.Assign(a5, ptrA5World); }
internal override void Emit(CodeEmitter ilgen, CodeEmitterLabel label) { ilgen.EmitBlt_Un(label); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.EmitUnaligned((byte)Alignment); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { ilgen.EmitLdarga(ArgNum); }
/// <summary> /// Completion of code generation for a block. /// </summary> /// <param name="block">The completed block.</param> protected virtual void BlockEnd(BasicBlock block) { // TODO: Adjust BaseCodeEmitter interface to mark the end of label sections, rather than create this special label: CodeEmitter.Label(block.Label + 0x0F000000); }