protected override void emitType() { PERWAPI.TypeAttr classAttr = PERWAPI.TypeAttr.Public; if (isAbstract) { classAttr |= PERWAPI.TypeAttr.Abstract; } emitter.emitClass(baseClassName, className, interfaces, classAttr); // generate private static Type $Type; set in clinit typeField = emitter.classDef.AddField( PERWAPI.FieldAttr.Public | PERWAPI.FieldAttr.Static, "$type", emitter.findType("Fan.Sys.Type")); // generate type() instance method PERWAPI.MethodDef m = emitter.classDef.AddMethod( PERWAPI.MethAttr.Public | PERWAPI.MethAttr.Virtual, PERWAPI.ImplAttr.IL, "typeof", emitter.findType("Fan.Sys.Type"), new PERWAPI.Param[0]); m.AddCallConv(PERWAPI.CallConv.Instance); emitter.addToMethodMap(className, "typeof", new string[0], m); PERWAPI.CILInstructions code = m.CreateCodeBuffer(); code.FieldInst(PERWAPI.FieldOp.ldsfld, typeField); code.Inst(PERWAPI.Op.ret); // generate peer field if native if (isNative) { peerField = emitter.classDef.AddField(PERWAPI.FieldAttr.Public, "m_peer", emitter.findType(className + "Peer")); } // Create ctor emit objects first so we can reference them // .ctor ctor = emitter.findMethod(selfName, ".ctor", new string[0], "System.Void") as PERWAPI.MethodDef; ctor.SetMethAttributes( PERWAPI.MethAttr.Public | PERWAPI.MethAttr.HideBySig | PERWAPI.MethAttr.SpecialRTSpecialName); ctor.AddCallConv(PERWAPI.CallConv.Instance); // .cctor cctor = emitter.findMethod(selfName, ".cctor", new string[0], "System.Void") as PERWAPI.MethodDef; cctor.SetMethAttributes( PERWAPI.MethAttr.Private | PERWAPI.MethAttr.Static | PERWAPI.MethAttr.HideBySig | PERWAPI.MethAttr.SpecialRTSpecialName); }
////////////////////////////////////////////////////////////////////////// // Overrides ////////////////////////////////////////////////////////////////////////// protected override void emitInstanceInit(FMethod m) { hasInstanceInit = true; // make peer if (isNative) { throw new System.Exception("No native support for Err subclasses"); } // stub ctor2 PERWAPI.MethodDef ctor2 = emitter.findMethod(selfName, ".ctor", new string[] { "Fan.Sys.Err/Val" }, "System.Void") as PERWAPI.MethodDef; ctor2.SetMethAttributes( PERWAPI.MethAttr.Public | PERWAPI.MethAttr.HideBySig | PERWAPI.MethAttr.SpecialRTSpecialName); ctor2.AddCallConv(PERWAPI.CallConv.Instance); // no arg constructor -> calls this(Err/Val) PERWAPI.CILInstructions code = ctor.CreateCodeBuffer(); code.Inst(PERWAPI.Op.ldarg_0); PERWAPI.Method valctor = emitter.findMethod(className + "/Val", ".ctor", new string[0], "System.Void"); code.MethInst(PERWAPI.MethodOp.newobj, valctor); code.MethInst(PERWAPI.MethodOp.call, ctor2); code.Inst(PERWAPI.Op.ret); // arg constructor with Err$Val (and init implementation) code = ctor2.CreateCodeBuffer(); code.Inst(PERWAPI.Op.ldarg_0); code.Inst(PERWAPI.Op.ldarg_1); PERWAPI.Method baseCtor = emitter.findMethod(baseClassName, ".ctor", new string[] { "Fan.Sys.Err/Val" }, "System.Void"); baseCtor.AddCallConv(PERWAPI.CallConv.Instance); // if stub, make sure instance callconv code.MethInst(PERWAPI.MethodOp.call, baseCtor); if (m == null) { //code.maxLocals = 2; //code.maxStack = 2; code.Inst(PERWAPI.Op.ret); } else { // e.code.maxLocals++; // alloc room for Val extra argument new FCodeEmit(this, m, code).emit(); } }