Ejemplo n.º 1
0
        /// <summary>
        /// Emit a mixin router from a class to the mixin body methods.
        /// </summary>
        public void emitMixinRouter(Method m)
        {
            string parent = FanUtil.toDotnetTypeName(m.parent());
            string name   = FanUtil.toDotnetMethodName(m.name());
            string ret    = FanUtil.toDotnetTypeName(m.inheritedReturns());

            string[] parTypes   = new string[] { parent };
            List     pars       = m.@params();
            int      paramCount = pars.sz();

            // find first param with default value
            int firstDefault = paramCount;

            for (int i = 0; i < paramCount; i++)
            {
                if (((Param)pars.get(i)).hasDefault())
                {
                    firstDefault = i; break;
                }
            }

            // generate routers
            for (int i = firstDefault; i <= paramCount; i++)
            {
                string[] myParams     = new string[i];
                string[] myParamNames = new string[i];
                string[] implParams   = new string[i + 1];
                implParams[0] = parent;

                for (int j = 0; j < i; j++)
                {
                    Param  param = (Param)m.@params().get(j);
                    Type   pt    = param.type();
                    string s     = FanUtil.toDotnetTypeName(pt);
                    myParams[j]       = s;
                    myParamNames[j]   = param.name();
                    implParams[j + 1] = s;
                }

                // CLR requires public virtual
                PERWAPI.MethAttr attr = PERWAPI.MethAttr.Public | PERWAPI.MethAttr.Virtual;

                PERWAPI.CILInstructions code = emitter.emitMethod(name, ret, myParamNames, myParams,
                                                                  attr, new string[0], new string[0]);
                code.Inst(PERWAPI.Op.ldarg_0); // push this
                for (int p = 0; p < i; p++)
                {
                    // push args
                    Param param = (Param)m.@params().get(p);
                    FCodeEmit.loadVar(code, FanUtil.toDotnetStackType(param.type()), p + 1);
                }
                PERWAPI.Method meth = emitter.findMethod(parent + "_", name, implParams, ret);
                code.MethInst(PERWAPI.MethodOp.call, meth);
                code.Inst(PERWAPI.Op.ret);
            }
        }
Ejemplo n.º 2
0
        private PERWAPI.CILInstructions doEmit(string[] localNames, string[] localTypes)
        {
            int paramCount = paramLen;

            if (self)
            {
                paramCount++;
            }

            string[] parNames = new string[paramCount];
            string[] parTypes = new string[paramCount];
            for (int i = 0; i < paramCount; i++)
            {
                int z = i;
                if (self)
                {
                    z--;
                }

                if (self && i == 0)
                {
                    parNames[0] = "self";
                    parTypes[0] = selfName;
                }
                else
                {
                    parNames[i] = method.m_vars[z].name;
                    parTypes[i] = emit.nname(method.m_vars[z].type);
                }
            }

            if (localNames == null)
            {
                localNames = new string[method.m_localCount];
                localTypes = new string[method.m_localCount];
                for (int i = 0; i < method.m_localCount; i++)
                {
                    int z = i + paramCount;
                    if (self)
                    {
                        z--;
                    }

                    localNames[i] = method.m_vars[z].name;
                    localTypes[i] = emit.nname(method.m_vars[z].type);
                }
            }

            /*
             * PERWAPI.MethAttr attr;
             * if (isPrivate) attr = PERWAPI.MethAttr.Public; //PERWAPI.MethAttr.Private;
             * else if (isInternal) attr = PERWAPI.MethAttr.Assembly;
             * else attr = PERWAPI.MethAttr.Public;
             */
            PERWAPI.MethAttr attr = isInternal
        ? PERWAPI.MethAttr.Assembly
        : PERWAPI.MethAttr.Public;

            if (isStatic)
            {
                attr |= PERWAPI.MethAttr.Static;
            }
            if (isAbstract)
            {
                attr |= PERWAPI.MethAttr.Abstract;
            }
            if (isVirtual)
            {
                attr |= PERWAPI.MethAttr.Virtual;
            }
            if (isOverride)
            {
                attr |= PERWAPI.MethAttr.Virtual;
            }
            if (isHide)
            {
                attr |= PERWAPI.MethAttr.HideBySig;
            }

            PERWAPI.CILInstructions code = emitter.emitMethod(name, ret.nname(), parNames, parTypes, attr,
                                                              localNames, localTypes);
            if (this.code != null)
            {
                new FCodeEmit(emit, method, code).emit();
            }

            return(code);
        }