private void AddInteropConstructor(CodeGenContext context) { List<Param> args = new List<Param>(); if (formals.arity < 0) { Param param = new Param(ParamAttr.Default, "args", new PERWAPI.ZeroBasedArray(PERWAPI.PrimitiveType.Object)); param.AddCustomAttribute(Runtime.ParamArrayAttribute.ctor, new byte[0]); args.Add(param); } else for (int i = 1; i <= this.formals.arity; i++) args.Add(new Param(ParamAttr.Default, "p" + i, PrimitiveType.Object)); // public .ctor(...) { try { // remove existing zero-arg constructor if it exists if (formals.arity == 0 && CLASS_OR_MODULE.CurrentInteropClass().GetMethodDesc(".ctor", new Type[0]) != null) CLASS_OR_MODULE.CurrentInteropClass().RemoveMethod(".ctor", new Type[0]); CodeGenContext method = context.CreateConstructor(CLASS_OR_MODULE.CurrentInteropClass(), args.ToArray()); method.startMethod(this.location); // call base class constructor PERWAPI.Method superClassConstructor0 = null; PERWAPI.Method superClassConstructor1 = null; PERWAPI.Class superClass = null; ClassSkeleton superClassSkeleton = context.currentSkeleton.FindClass(CLASS_OR_MODULE.CurrentInteropClass().SuperType.Name()); if (superClassSkeleton != null) { superClass = superClassSkeleton.perwapiClass; superClassConstructor0 = superClass.GetMethodDesc(".ctor", new Type[0]); if (superClassConstructor0 is MethodDef) superClassConstructor0 = ((MethodDef)superClassConstructor0).MakeRefOf(); superClassConstructor1 = superClass.GetMethodDesc(".ctor", new Type[] { Runtime.ClassRef }); if (superClassConstructor1 is MethodDef) superClassConstructor1 = ((MethodDef)superClassConstructor1).MakeRefOf(); } if (superClassConstructor1 != null) { method.ldarg(0); method.ldsfld(((CLASS_OR_MODULE)this.parent_scope).singletonField); method.call(superClassConstructor1); } else if (superClassConstructor0 != null) { method.ldarg(0); method.call(superClassConstructor0); } // return Eval.CallPrivateN(recv, null, "methodId", null, ...); method.ldarg(0); method.ldnull(); method.ldstr(method_id); method.ldnull(); if (formals.arity < 0) { method.ldarg(1); method.call(Runtime.Eval.Call("Private")); } else { for (int i = 1; i <= args.Count; i++) method.ldarg(i); method.call(Runtime.Eval.Call("Private", args.Count)); } method.pop(); method.ret(); method.Close(); } catch (PERWAPI.DescriptorException) { } }
/// <summary> /// Add a method to this class /// </summary> /// <param name="mAtts">attributes for this method</param> /// <param name="iAtts">implementation attributes for this method</param> /// <param name="name">method name</param> /// <param name="genPars">generic parameters</param> /// <param name="retType">return type</param> /// <param name="pars">parameters</param> /// <returns>a descriptor for this new method</returns> public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, GenericParam[] genPars, Type retType, Param[] pars) { MethodDef meth = AddMethod(name,genPars,retType,pars); meth.AddMethAttribute(mAtts); meth.AddImplAttribute(iAtts); return meth; }
private void AddInteropMethod(CodeGenContext context) { List<Param> args = new List<Param>(); if (formals.arity < 0) { Param param = new Param(ParamAttr.Default, "args", new PERWAPI.ZeroBasedArray(PERWAPI.PrimitiveType.Object)); param.AddCustomAttribute(Runtime.ParamArrayAttribute.ctor, new byte[0]); args.Add(param); } else for (int i = 1; i <= this.formals.arity; i++) args.Add(new Param(ParamAttr.Default, "p" + i, PrimitiveType.Object)); // public object method_id(...) { try { CodeGenContext method = context.CreateMethod(CLASS_OR_MODULE.CurrentInteropClass(), MethAttr.PublicVirtual, Translate(this.method_id), PERWAPI.PrimitiveType.Object, args.ToArray()); method.startMethod(this.location); // return Eval.Calln(this, "method_id", ...); method.ldarg(0); method.ldstr(method_id); if (formals.arity < 0) { method.ldarg(1); method.call(Runtime.Eval.Calln); } else { for (int i = 1; i <= args.Count; i++) method.ldarg(i); method.call(Runtime.Eval.Call(args.Count)); } method.ret(); method.Close(); } catch (PERWAPI.DescriptorException e) { Compiler.LogWarning(e.Message); } }
/// <summary> /// Add a method to this class /// </summary> /// <param name="name">method name</param> /// <param name="retType">return type</param> /// <param name="pars">parameters</param> /// <returns>a descriptor for this new method</returns> public MethodDef AddMethod(string name, Type retType, Param[] pars) { System.Diagnostics.Debug.Assert(retType != null); MethSig mSig = new MethSig(name); mSig.SetParTypes(pars); MethodDef meth = (MethodDef)GetMethod(mSig); if (meth != null) throw new DescriptorException("Method " + meth.NameString()); mSig.retType = retType; meth = new MethodDef(this,mSig,pars); methods.Add(meth); return meth; }
/// <summary> /// Add a method to this class /// </summary> /// <param name="name">method name</param> /// <param name="genPars">generic parameters</param> /// <param name="retType">return type</param> /// <param name="pars">parameters</param> /// <returns>a descriptor for this new method</returns> public MethodDef AddMethod(string name, GenericParam[] genPars, Type retType, Param[] pars) { MethodDef meth = AddMethod(name,retType,pars); if ((genPars != null) && (genPars.Length > 0)) { for (int i=0; i < genPars.Length; i++) { genPars[i].SetMethParam(meth,i); } meth.SetGenericParams(genPars); } return meth; }
/// <summary> /// Add a "global" method to this module /// </summary> /// <param name="mAtts">method attributes</param> /// <param name="iAtts">method implementation attributes</param> /// <param name="name">method name</param> /// <param name="genPars">generic parameters</param> /// <param name="retType">return type</param> /// <param name="pars">method parameters</param> /// <returns>a descriptor for this new "global" method</returns> public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, GenericParam[] genPars, Type retType, Param[] pars) { MethodDef newMeth = defaultClass.AddMethod(mAtts,iAtts,name,genPars,retType,pars); return newMeth; }
internal static void Read(PEReader buff, TableRow[] pars) { for (int i=0; i < pars.Length; i++) pars[i] = new Param(buff); }
internal void SetParTypes(Param[] parList) { if (parList == null) { numPars = 0; return; } numPars = (uint)parList.Length; parTypes = new Type[numPars]; for (int i=0; i < numPars; i++) { parTypes[i] = parList[i].GetParType(); } }
/// <summary> /// Add a "global" method to this module /// </summary> /// <param name="name">method name</param> /// <param name="genPars">generic parameters</param> /// <param name="retType">return type</param> /// <param name="pars">method parameters</param> /// <returns>a descriptor for this new "global" method</returns> public MethodDef AddMethod(string name, GenericParam[] genPars, Type retType, Param[] pars) { MethodDef newMeth = defaultClass.AddMethod(name,genPars,retType,pars); return newMeth; }
/// <summary> /// Set the parameters for this method /// </summary> /// <param name="pars">Descriptors of the parameters for this method</param> public void SetParams(Param[] pars) { parList = pars; sig.SetParTypes(pars); }
internal MethodDef(ClassSpec paren, MethSig mSig, Param[] pars) : base(mSig.name) { parent = paren; parList = pars; sig = mSig; tabIx = MDTable.Method; }
/*-------------------- Constructors ---------------------------------*/ internal MethodDef(string name, Type retType, Param[] pars, ClassDef paren) : base(name,retType,paren) { sig.SetParTypes(pars); parList = pars; parent = paren; tabIx = MDTable.Method; }
/// <summary> /// Find the Method for this method on the given type. /// </summary> internal Method findMethod(string qname, string methodName, string[] paramTypes, string returnType) { string key = getMethodKey(qname, methodName, paramTypes); Method method = (Method)methods[key]; if (method == null) { // this stuff should be the same for both cases PERWAPI.Type rtype = findType(returnType); PERWAPI.Type[] pars = new PERWAPI.Type[paramTypes.Length]; for (int i=0; i<paramTypes.Length; i++) pars[i] = findType(paramTypes[i]); // check for stubs object obj = findType(qname); if (obj is ClassDef) { // class is an internal stub, so we need to stub this // method out too, which should get flushed out later ClassDef cdef = obj as ClassDef; // TODO - need to fix attrs Param[] mpars = new Param[pars.Length]; for (int i=0; i<mpars.Length; i++) mpars[i] = new Param(ParamAttr.Default, "v"+i, pars[i]); // TODO - fix param names // Use Public here for stub - real MethAttr will be set // when method is flushed out method = cdef.AddMethod(MethAttr.Public, ImplAttr.IL, methodName, rtype, mpars); } else if (obj is ClassRef) { // class is external, just get or add ref ClassRef cref = obj as ClassRef; method = cref.GetMethod(methodName, pars, new PERWAPI.Type[0]); if (method == null) method = cref.AddMethod(methodName, rtype, pars); } else throw new System.Exception("Don't know how to handle: " + obj.GetType()); // make sure we add method to hashtable methods[key] = method; } return method; }
/// <summary> /// Define a new method to emit for the current class. /// </summary> public CILInstructions emitMethod( string name, string retType, string[] paramNames, string[] paramTypes, MethAttr attr, string[] localNames, string[] localTypes) { Param[] pars = new Param[paramNames.Length]; for (int i=0; i<pars.Length; i++) pars[i] = new Param(ParamAttr.Default, paramNames[i], findType(paramTypes[i])); // first check if this method was already stubbed out methodDef = (MethodDef)methods[getMethodKey(className, name, paramTypes)]; if (methodDef == null) { // if not, we need to create it methodDef = classDef.AddMethod(attr, ImplAttr.IL, name, findType(retType), pars); } else { // if stubbed out, make sure we define the method correctly methodDef.SetMethAttributes(attr); } if ((attr & MethAttr.Static) != MethAttr.Static) methodDef.AddCallConv(CallConv.Instance); if (localNames.Length > 0) { Local[] locals = new Local[localNames.Length]; for (int i=0; i<locals.Length; i++) locals[i] = new Local(localNames[i], findType(localTypes[i])); methodDef.AddLocals(locals, true); } // TODO - what the f**k should this be? methodDef.SetMaxStack(16 + pars.Length + localNames.Length); // add to lookup table addToMethodMap(className, name, paramTypes, methodDef); // don't create code buffer if abstract if ((attr & MethAttr.Abstract) == MethAttr.Abstract) return null; return methodDef.CreateCodeBuffer(); }