FBuf stores a byte buffer (such as executable fcode, or line numbers).
Beispiel #1
0
        //////////////////////////////////////////////////////////////////////////
        // 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;
        }
Beispiel #2
0
 public void code(FBuf code)
 {
     if (!m_showCode)
     {
         return;
     }
     Flush();
     //new FCodePrinter(pod, out).code(code);
     WriteLine("      CODE - TODO");
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 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;
 }
Beispiel #5
0
        //////////////////////////////////////////////////////////////////////////
        // 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;
        }
Beispiel #6
0
 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);
 }
Beispiel #7
0
        //////////////////////////////////////////////////////////////////////////
        // 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);
        }
Beispiel #8
0
        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;
        }
Beispiel #9
0
        /// <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);
        }
Beispiel #10
0
        /// <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();
        }
Beispiel #11
0
        /// <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();
            }
              }
        }
Beispiel #12
0
        /// <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();
        }
Beispiel #13
0
 public void code(FBuf code)
 {
     if (!m_showCode) return;
       Flush();
       //new FCodePrinter(pod, out).code(code);
       WriteLine("      CODE - TODO");
 }
Beispiel #14
0
 private void lineNumbers(FStore.Input input)
 {
     m_lineNums = FBuf.read(input);
 }
Beispiel #15
0
 private void errTable(FStore.Input input)
 {
     m_errTable = FBuf.read(input);
 }
Beispiel #16
0
 private void lineNumbers(FStore.Input input)
 {
     m_lineNums = FBuf.read(input);
 }
Beispiel #17
0
 private void errTable(FStore.Input input)
 {
     m_errTable = FBuf.read(input);
 }
Beispiel #18
0
        //////////////////////////////////////////////////////////////////////////
        // 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;
        }