////////////////////////////////////////////////////////////////////////// // Write ////////////////////////////////////////////////////////////////////////// public void code(FBuf code) { try { this.m_code = code; this.m_input = new DataReader(new MemoryStream(m_code.m_buf, 0, m_code.m_len)); /* * if (false) * { * int c; * while ((c = m_input.Read()) >= 0) * WriteLine(" 0x" + c); * return; * } */ int op; while ((op = m_input.Read()) >= 0) { m_n++; this.op(op); } } catch (IOException e) { Err.dumpStack(e); } Flush(); this.m_code = null; this.m_input = null; }
public void code(FBuf code) { if (!m_showCode) { return; } Flush(); //new FCodePrinter(pod, out).code(code); WriteLine(" CODE - TODO"); }
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 FMethod read(FStore.Input input) { base.readCommon(input); m_ret = input.u2(); m_inheritedRet = input.u2(); m_maxStack = input.u1(); m_paramCount = input.u1(); m_localCount = input.u1(); m_vars = new FMethodVar[m_paramCount+m_localCount]; for (int i=0; i<m_vars.Length; i++) m_vars[i] = new FMethodVar().read(input); m_code = FBuf.read(input); base.readAttrs(input); return this; }
////////////////////////////////////////////////////////////////////////// // IO ////////////////////////////////////////////////////////////////////////// public FMethodVar read(FStore.Input input) { name = input.name(); type = input.u2(); flags = input.u1(); int attrCount = input.u2(); for (int i=0; i<attrCount; ++i) { string attrName = input.fpod.name(input.u2()); FBuf attrBuf = FBuf.read(input); if (attrName == FConst.ParamDefaultAttr) def = attrBuf; } return this; }
public FMethod read(FStore.Input input) { base.readCommon(input); m_ret = input.u2(); m_inheritedRet = input.u2(); m_maxStack = input.u1(); m_paramCount = input.u1(); m_localCount = input.u1(); m_vars = new FMethodVar[m_paramCount + m_localCount]; for (int i = 0; i < m_vars.Length; i++) { m_vars[i] = new FMethodVar().read(input); } m_code = FBuf.read(input); base.readAttrs(input); return(this); }
////////////////////////////////////////////////////////////////////////// // IO ////////////////////////////////////////////////////////////////////////// public FMethodVar read(FStore.Input input) { name = input.name(); type = input.u2(); flags = input.u1(); int attrCount = input.u2(); for (int i = 0; i < attrCount; ++i) { string attrName = input.fpod.name(input.u2()); FBuf attrBuf = FBuf.read(input); if (attrName == FConst.ParamDefaultAttr) { def = attrBuf; } } 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 wrapper. /// </summary> private void emitWrapper(PERWAPI.MethodDef main, int paramLen) { // use explicit param count, and clear code this.paramLen = paramLen; this.code = null; int numArgs = isStatic && !self ? paramLen : paramLen+1; // TODO - this code probably isn't quite right, since it looks // like we generate local variables even when they might not be // used. Doesn't hurt anything, but is probably more efficient // if we could determine that from the fcode. // define our locals int numLocals = method.m_paramCount - paramLen; string[] localNames = new string[numLocals]; string[] localTypes = new string[numLocals]; for (int i=paramLen; i<method.m_paramCount; i++) { localNames[i-paramLen] = method.m_vars[i].name; localTypes[i-paramLen] = emit.nname(method.m_vars[i].type); } // emit code PERWAPI.CILInstructions code = doEmit(localNames, localTypes); // push arguments passed thru pushArgs(code, !(isStatic && !self), paramLen); // emit default arguments FCodeEmit.Reg[] regs = FCodeEmit.initRegs(emit.pod, isStatic, method.m_vars); int maxLocals = method.maxLocals(); int maxStack = 16; // TODO - add additional default expr stack height for (int i=paramLen; i<method.m_paramCount; i++) { FCodeEmit ce = new FCodeEmit(emit, method.m_vars[i].def, code, regs, emit.pod.typeRef(method.m_ret)); ce.paramCount = numArgs; ce.vars = method.m_vars; ce.isStatic = isStatic; // TODO - is this correct? ce.emit(false); // don't emit debug s cope for wrappers maxStack = System.Math.Max(maxStack, 2+i+8); } // TODO //code.maxLocals = maxLocals; //code.maxStack = maxStack; // call master implementation if (isStatic) code.MethInst(PERWAPI.MethodOp.call, main); else code.MethInst(PERWAPI.MethodOp.callvirt, main); // return code.Inst(PERWAPI.Op.ret); }
/// <summary> /// Emit a native method /// <summary> public void emitNative() { // emit an empty method this.code = null; // emit code which calls the peer PERWAPI.CILInstructions code = doEmit(); if (!emitter.stub) { if (isStatic) { string[] parTypes = new string[paramLen]; for (int i=0; i<paramLen; i++) parTypes[i] = emit.nname(method.m_vars[i].type); PERWAPI.Method peerMeth = emitter.findMethod(selfName + "Peer", name, parTypes, ret.nname()); pushArgs(code, false, paramLen); code.MethInst(PERWAPI.MethodOp.call, peerMeth); } else { string[] parTypes = new string[paramLen+1]; parTypes[0] = selfName; for (int i=0; i<paramLen; i++) parTypes[i+1] = emit.nname(method.m_vars[i].type); PERWAPI.Method peerMeth = emitter.findMethod(selfName + "Peer", name, parTypes, ret.nname()); peerMeth.AddCallConv(PERWAPI.CallConv.Instance); code.Inst(PERWAPI.Op.ldarg_0); code.FieldInst(PERWAPI.FieldOp.ldfld, emit.peerField); pushArgs(code, true, paramLen); code.MethInst(PERWAPI.MethodOp.call, peerMeth); } } code.Inst(PERWAPI.Op.ret); // emit default parameter wrappers emitWrappers(); }
/// <summary> /// Emit the method as a mixin interface /// </summary> public void emitMixinInterface() { // we only emit instance methods in the interface if (isStatic || isCtor) return; // set abstract flag and clear code code = null; // force public isInternal = false; isPrivate = false; // force abstract virtual isAbstract = true; isVirtual = true; // emit main doEmit(); // emit a signature for each overload based on param defaults for (int i=0; i<method.m_paramCount; i++) { if (method.m_vars[i].def != null) { paramLen = i; doEmit(); } } }
/// <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(); }
public void code(FBuf code) { if (!m_showCode) return; Flush(); //new FCodePrinter(pod, out).code(code); WriteLine(" CODE - TODO"); }
private void lineNumbers(FStore.Input input) { m_lineNums = FBuf.read(input); }
private void errTable(FStore.Input input) { m_errTable = FBuf.read(input); }
////////////////////////////////////////////////////////////////////////// // Write ////////////////////////////////////////////////////////////////////////// public void code(FBuf code) { try { this.m_code = code; this.m_input = new DataReader(new MemoryStream(m_code.m_buf, 0, m_code.m_len)); /* if (false) { int c; while ((c = m_input.Read()) >= 0) WriteLine(" 0x" + c); return; } */ int op; while ((op = m_input.Read()) >= 0) { m_n++; this.op(op); } } catch (IOException e) { Err.dumpStack(e); } Flush(); this.m_code = null; this.m_input = null; }