public FCodeEmit(FTypeEmit parent, FBuf fcode, CILInstructions code, Reg[] regs, FTypeRef ret) { this.pod = parent.pod; this.emitter = parent.emitter; this.parent = parent; this.buf = fcode.m_buf; this.len = fcode.m_len; this.code = code; this.podClass = FanUtil.toDotnetTypeName(pod.m_podName, "$Pod", false); this.jumps = new Jumps(code); this.regs = regs; this.ret = ret; }
public override FTable read(FStore.Input input) { if (input == null) { m_size = 0; return(this); } m_size = input.u2(); m_table = new object[m_size]; for (int i = 0; i < m_size; i++) { m_table[i] = FTypeRef.read(input); } return(this); }
internal string selfName; // class name for self if self is true #endregion Fields #region Constructors ////////////////////////////////////////////////////////////////////////// // Constructor ////////////////////////////////////////////////////////////////////////// /// <summary> /// Constructor. /// </summary> public FMethodEmit(FTypeEmit emit, FMethod method) { this.emitter = emit.emitter; this.emit = emit; this.method = method; this.code = method.m_code; this.name = FanUtil.toDotnetMethodName(method.m_name); this.paramLen = method.m_paramCount; this.isStatic = (method.m_flags & FConst.Static) != 0; this.isInternal = false; //(method.m_flags & FConst.Internal) != 0; this.isPrivate = (method.m_flags & FConst.Private) != 0; this.isAbstract = (method.m_flags & FConst.Abstract) != 0; this.isVirtual = (method.m_flags & FConst.Virtual) != 0; this.isOverride = (method.m_flags & FConst.Override) != 0; this.isCtor = (method.m_flags & FConst.Ctor) != 0; this.isNative = (method.m_flags & FConst.Native) != 0; this.isHide = false; // only used for make/make_ this.ret = emit.pod.typeRef(method.m_inheritedRet); this.selfName = emit.selfName; }
/// <summary> /// Emit a constructor - constructors get created as a static /// factory methods, so that that CallNew can just push args /// and invoke them /// /// fan: /// class Foo { new make(Long a) { ... } } /// .net: /// static Foo make(Long a) { return make_(new Foo(), a) } /// static Foo make_(Foo self, Long a) { ... return self } /// /// We call the first method "make" the "factory" and the /// second method "make_" the "body". CallNew opcodes are /// routed to the ctor factory, and CallCtor opcodes are routed /// to the ctor body. /// </summary> public void emitCtor() { string ctorName = this.name; // both factory and body are static from CLR's perspective this.isStatic = true; this.isHide = true; // first emit the body with implicit self this.name = ctorName + "_"; this.self = true; doEmit(); PERWAPI.MethodDef make = emitter.methodDef; // emit body default parameter wrappers emitWrappers(); // then emit the factory this.name = ctorName; this.self = false; this.ret = emit.pod.typeRef(emit.type.m_self); this.code = null; PERWAPI.CILInstructions code = doEmit(); PERWAPI.Method ctor = emitter.findMethod(selfName, ".ctor", new string[0], "System.Void"); code.MethInst(PERWAPI.MethodOp.newobj, ctor); code.Inst(PERWAPI.Op.dup); pushArgs(code, false, method.m_paramCount); code.MethInst(PERWAPI.MethodOp.call, make); code.Inst(PERWAPI.Op.ret); // emit factory default parameter wrappers emitWrappers(); }
private void loadType(FTypeRef tref) { string podName = tref.podName; string typeName = tref.typeName; // if pod is "sys", then we can perform a shortcut and use // one of the predefined fields in Sys if (!tref.isGenericInstance() && podName == "sys") { PERWAPI.Field field = emitter.findField("Fan.Sys.Sys", typeName + "Type", "Fan.Sys.Type"); code.FieldInst(FieldOp.ldsfld, field); if (tref.isNullable()) typeToNullable(); return; } // lazy allocate my parent's type literal map: sig -> fieldName if (parent.typeLiteralFields == null) parent.typeLiteralFields = new Hashtable(); Hashtable map = parent.typeLiteralFields; // types are lazy loaded and then cached in a private static field called // type$count which will get generated by FTypeEmit (we keep track of signature // to fieldname in the typeConstFields map) string sig = tref.signature; string fieldName = (string)map[sig]; if (fieldName == null) { fieldName = "type$" + map.Count; map[sig] = fieldName; } //int fieldRef = emit.field(parent.className + "." + fieldName + ":Lfan/sys/Type;"); //code.op2(GETSTATIC, fieldRef); //code.op(DUP); //int nonNull = code.branch(IFNONNULL); //code.op(POP); //code.op2(LDC_W, emit.strConst(sig)); //code.op(ICONST_1); //code.op2(INVOKESTATIC, parent.sysFindType()); //code.op(DUP); //code.op2(PUTSTATIC, fieldRef); //code.mark(nonNull); //emitter.EmitField(string name, string type, FieldAttr attr) //PERWAPI.Field field = emitter.EmitField("Fan.Sys.Sys", typeName + "Type", "Fan.Sys.Type"); //code.FieldInst(FieldOp.ldsfld, field); // TODO - store in static field (all that crap above this) code.ldstr(sig); Method method = emitter.findMethod("Fan.Sys.Type", "find", new string[] { "System.String" }, "Fan.Sys.Type"); code.MethInst(MethodOp.call, method); }
private void doCompare(string suffix, FTypeRef lhs, FTypeRef rhs) { // get lhs and rhs types string[] args = new string[] { lhs.isRef() ? "System.Object" : lhs.nname(), rhs.isRef() ? "System.Object" : rhs.nname() }; string ret = (suffix == "") ? "System.Int64" : "System.Boolean"; PERWAPI.Method m = emitter.findMethod("Fanx.Util.OpUtil", "compare"+suffix, args, ret); code.MethInst(MethodOp.call, m); }