/// <summary> /// Emit a method. /// </summary> protected virtual void emit(FMethod m) { string n = m.m_name; bool isNative = (m.m_flags & FConst.Native) != 0; bool isCtor = (m.m_flags & FConst.Ctor) != 0; // static$init -> .cctor // instance$init -> .ctor if (n == "static$init") { emitStaticInit(m); return; } if (n == "instance$init") { emitInstanceInit(m); return; } // handle native/constructor/normal method if (isNative) { new FMethodEmit(this, m).emitNative(); } else if (isCtor) { new FMethodEmit(this, m).emitCtor(); } else { new FMethodEmit(this, m).emitStandard(); } }
/** 读一个工厂类 */ public static FactoryClassInfo readFactory(string path) { string clsStr = FileUtils.readFileForUTF(path); FactoryClassInfo re = new FactoryClassInfo(); re.clsStr = clsStr; re.startIndex = clsStr.IndexOf('{') + 1; Regex reg1 = new Regex("public (virtual|override) (.*?) create(.*?)\\(\\)"); Regex reg2 = new Regex("return new (.*?)\\(\\);"); Match match1 = reg1.Match(clsStr); Match match2 = reg2.Match(clsStr); while (match1.Success) { FMethod method = new FMethod(); method.isOverride = match1.Groups[1].Value.Equals("override"); method.name = match1.Groups[3].Value; method.returnType = match1.Groups[2].Value; method.useClsName = match2.Groups[1].Value; re.toAddMethod(method); match1 = match1.NextMatch(); match2 = match2.NextMatch(); } return(re); }
protected override void emit(FMethod m) { string name = m.m_name; if (name == "static$init") { emitStaticInit(m); cctorEmit = true; return; } new FMethodEmit(this, m).emitMixinBody(); }
public void toAddMethod(FMethod method) { //有了 if (methodDic.contains(method.name)) { return; } methodList.add(method); methodDic.put(method.name, method); }
protected virtual void emitInstanceInit(FMethod m) { hasInstanceInit = true; PERWAPI.CILInstructions code = ctor.CreateCodeBuffer(); // initalize code to call super code.Inst(PERWAPI.Op.ldarg_0); // if closure, push FuncType static field if (funcType != null) { code.FieldInst(PERWAPI.FieldOp.ldsfld, typeField); PERWAPI.Method baseCtor = emitter.findMethod(baseClassName, ".ctor", new string[] { "Fan.Sys.FuncType" }, "System.Void"); baseCtor.AddCallConv(PERWAPI.CallConv.Instance); // if stub, make sure instance callconv code.MethInst(PERWAPI.MethodOp.call, baseCtor); } else { PERWAPI.Method baseCtor = emitter.findMethod(baseClassName, ".ctor", new string[0], "System.Void"); baseCtor.AddCallConv(PERWAPI.CallConv.Instance); // if stub, make sure instance callconv code.MethInst(PERWAPI.MethodOp.call, baseCtor); } // make peer if (isNative) { //code.op(ALOAD_0); // for putfield //code.op(DUP); // for arg to make //code.op2(INVOKESTATIC, method(selfName + "Peer.make(L" + className + ";)L" + className + "Peer;")); //code.op2(PUTFIELD, peerField.ref()); code.Inst(PERWAPI.Op.ldarg_0); code.Inst(PERWAPI.Op.dup); PERWAPI.Method peerMake = emitter.findMethod(className + "Peer", "make", new string[] { className }, className + "Peer"); code.MethInst(PERWAPI.MethodOp.call, peerMake); code.FieldInst(PERWAPI.FieldOp.stfld, peerField); } if (m == null) { code.Inst(PERWAPI.Op.ret); } else { new FCodeEmit(this, m, code).emit(); } }
////////////////////////////////////////////////////////////////////////// // Constructor ////////////////////////////////////////////////////////////////////////// public FCodeEmit(FTypeEmit parent, FMethod fmethod, CILInstructions code) : this(parent, fmethod.m_code, code, initRegs(parent.pod, fmethod.isStatic(), fmethod.m_vars), parent.pod.typeRef(fmethod.m_ret)) { this.fmethod = fmethod; this.vars = fmethod.m_vars; this.isStatic = (fmethod.m_flags & FConst.Static) != 0; this.paramCount = fmethod.m_paramCount; if (!isStatic) { paramCount++; } }
////////////////////////////////////////////////////////////////////////// // 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(); } }
/// <summary> /// Map fcode method to a sys::Method. /// </summary> private Method map(FPod fpod, FMethod m) { string name = String.Intern(m.m_name); Type returnType = m_pod.findType(m.m_ret); Type inheritedReturnType = m_pod.findType(m.m_inheritedRet); List pars = new List(Sys.ParamType, m.m_paramCount); for (int j = 0; j < m.m_paramCount; j++) { FMethodVar p = m.m_vars[j]; int pflags = (p.def == null) ? 0 : Param.HAS_DEFAULT; pars.add(new Param(String.Intern(p.name), m_pod.findType(p.type), pflags)); } Facets facets = Facets.mapFacets(m_pod, m.m_attrs.m_facets); return(new Method(this, name, m.m_flags, facets, m.m_attrs.m_lineNum, returnType, inheritedReturnType, pars)); }
internal void emitStaticInit(FMethod m) { // make sure we add local defs if (m != null && m.m_localCount > 0) { PERWAPI.Local[] locals = new PERWAPI.Local[m.m_vars.Length]; for (int i = 0; i < locals.Length; i++) { string name = m.m_vars[i].name; string type = nname(m.m_vars[i].type); locals[i] = new PERWAPI.Local(name, emitter.findType(type)); } cctor.AddLocals(locals, true); } hasStaticInit = true; PERWAPI.CILInstructions code = cctor.CreateCodeBuffer(); // set $Type field with type (if we this is a closure, // then the FuncType will be the type exposed) if (!parent.isMixin()) { Type t = parent; if (parent.@base() is FuncType) { t = parent.@base(); } code.ldstr(t.signature()); PERWAPI.Method findType = emitter.findMethod("Fan.Sys.Type", "find", new string[] { "System.String" }, "Fan.Sys.Type"); code.MethInst(PERWAPI.MethodOp.call, findType); code.FieldInst(PERWAPI.FieldOp.stsfld, typeField); } if (m == null) { code.Inst(PERWAPI.Op.ret); } else { new FCodeEmit(this, m, code).emit(); } }
////////////////////////////////////////////////////////////////////////// // 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; }
/** 添加方法 */ public FMethod addMethod(string type, string mark) { bool isOverride = false; string name = type; string rType = type; if (mark != "" && type.StartsWith(mark)) { string last = type.Substring(1); string first = last[0].ToString(); //首字母是大写的 if (first == first.ToUpper()) { name = last; FMethod pMethod = parentMethodDic.get(last); if (pMethod != null) { rType = pMethod.returnType; isOverride = true; } } } FMethod method = new FMethod(); method.name = name; method.returnType = rType; method.isOverride = isOverride; method.useClsName = type; toAddMethod(method); return(method); }
protected override void emit(FMethod m) { new FMethodEmit(this, m).emitMixinInterface(); }