예제 #1
0
        internal static void Import(Executable exe, ContentLoader loader, string packageName, string sourceName, ImportMode mode)
        {
            var pkg = new Package(packageName, false);

            var parser = new Parser(exe, loader, pkg.ScopeMgr);

            loader.Load(pkg, parser, sourceName, mode);

            exe.AddPackage(pkg);

            var initPos = TokenPos.Init;

            initPos.SourceName = sourceName;

            // 全局入口( 不进入函数列表, 只在Package上保存 )
            var cs = new ValuePhoFunc(new ObjectName(pkg.Name, "@init"), initPos, pkg.PackageScope.RegCount, pkg.PackageScope);

            pkg.InitEntry = cs;

            var param = new CompileParameter();

            param.Pkg       = pkg;
            param.CS        = cs;
            param.Exe       = exe;
            param.Constants = exe.Constants;

            pkg.Compile(param);

            cs.Add(new Command(Opcode.EXIT).SetCodePos(parser.CurrTokenPos));
        }
예제 #2
0
        internal override void Compile(CompileParameter param)
        {
            var newset = new ValuePhoFunc(new ObjectName("fakepkg", "constcalc"), ConstPos, 0, null);


            var funcParam = param.SetCmdSet(newset);

            // 用空的常量表
            funcParam.Constants = new ConstantSet();

            // 生成表达式计算指令
            Value.Compile(funcParam);

            try
            {
                var eval = VMachine.MiniExec(newset, funcParam.Constants);

                var ci = param.Constants.Add(eval);
                Name.Symbol.RegIndex = ci;
            }
            catch (RuntimeException)
            {
                throw new CompileException("Expect constant value to caculate value", ConstPos);
            }
        }
예제 #3
0
        internal void EnterFrame(ValuePhoFunc func)
        {
            CallHook(DebugHook.Call);

            var newFrame = new RuntimeFrame(func);

            _currFrame = newFrame;

            _callStack.Push(_currFrame);

            LocalReg.SetCount(newFrame.Func.RegCount);

            LocalReg.AttachScope(func.Scope);
        }
예제 #4
0
        internal static Value MiniExec(ValuePhoFunc func, ConstantSet consts)
        {
            var vm = new VMachine();

            vm.Constants = consts;

            foreach (var cmd in func.Commands)
            {
                if (!_insset.ExecCode(vm, cmd))
                {
                    break;
                }
            }

            return(vm.DataStack.Get(-1));
        }
예제 #5
0
        internal override void Compile(CompileParameter param)
        {
            ObjectName on = new ObjectName(param.Pkg.Name, Name.Name);

            if (ClassName != null)
            {
                // 成员函数必须有至少1个参数(self)
                if (TypeInfo.Params.Count < 1)
                {
                    throw new CompileException("Expect 'self' in method", TypeInfo.FuncPos);
                }

                on.ClassName = ClassName.Name;
            }

            var newset = new ValuePhoFunc(on, TypeInfo.FuncPos, TypeInfo.ScopeInfo.CalcUsedReg(), TypeInfo.ScopeInfo);

            bodyCS = newset;

            _proc = param.Exe.AddFunc(newset);

            if (ClassName != null)
            {
                param.NextPassToResolve(this);
            }

            var funcParam = param.SetLHS(false).SetCmdSet(newset);

            Body.Compile(funcParam);

            TypeInfo.GenDefaultRet(Body.Child(), funcParam);

            newset.InputValueCount = TypeInfo.Params.Count;

            newset.OutputValueCount = FuncType.CalcReturnValueCount(Body.Child());
        }
예제 #6
0
 internal RuntimeFrame(ValuePhoFunc cs)
 {
     Func = cs;
 }
예제 #7
0
        internal void ExecuteFunc(Executable exe, RuntimePackage rtpkg, ValuePhoFunc func, int argCount, int retValueCount)
        {
            if (func.Commands.Count == 0)
            {
                return;
            }

            if (ShowDebugInfo)
            {
                Logger.DebugLine(string.Format("============ Run '{0}' ============", func.Name));
            }

            rtpkg.Reg.SetCount(func.RegCount);

            EnterFrame(func);

            CurrFrame.ReceiverCount = retValueCount;

            // 数据栈转寄存器
            if (argCount > 0)
            {
                MoveArgStack2Local(argCount);
                _dataStack.Clear();
            }

            int currSrcLine = 0;

            _state = State.Running;

            while (true)
            {
                var cmd = CurrFrame.GetCurrCommand();
                if (cmd == null)
                {
                    break;
                }

                if (ShowDebugInfo)
                {
                    Logger.DebugLine("{0}|{1}", cmd.CodePos, exe.QuerySourceLine(cmd.CodePos));
                    Logger.DebugLine("---------------------");
                    Logger.DebugLine("{0,5} {1,2}| {2} {3}", _currFrame.Func.Name, _currFrame.PC, cmd.Op.ToString(), _insset.InstructToString(cmd));
                }

                // 源码行有变化时
                if (currSrcLine == 0 || currSrcLine != cmd.CodePos.Line)
                {
                    if (currSrcLine != 0)
                    {
                        CallHook(DebugHook.SourceLine);
                    }

                    currSrcLine = cmd.CodePos.Line;
                }


                // 每条指令执行前
                CallHook(DebugHook.AssemblyLine);

                if (_insset.ExecCode(this, cmd))
                {
                    if (_currFrame == null)
                    {
                        break;
                    }

                    _currFrame.PC++;
                }

                // 打印执行完后的信息
                if (ShowDebugInfo)
                {
                    rtpkg.Reg.DebugPrint();

                    // 寄存器信息
                    LocalReg.DebugPrint();


                    // 数据栈信息
                    DataStack.DebugPrint();

                    Logger.DebugLine("");
                }
            }


            if (ShowDebugInfo)
            {
                Logger.DebugLine("============ VM End ============");
            }
        }
예제 #8
0
        // foo  var a
        // closure var b   间接UpValue a
        // closure2 var c  直接UpValue a, b

        // LINKU和LOADU对应
        // 引用模式分为2种
        // 1. 引用最近的上一层作用域,  LINKU第一个参数=0(当前执行体不是闭包时)
        // 1. 引用上N层作用域,  LINKU第一个参数=1 (当前执行体为闭包时)
        //
        // UpValue索引计算
        // 不使用被引用的变量在它归属作用域分配的寄存器索引
        // 直接引用并使用的UpValue

        internal override void Compile(CompileParameter param)
        {
            var newset = new ValuePhoFunc(param.Pkg.GenClosureName(), TypeInfo.FuncPos, TypeInfo.ScopeInfo.CalcUsedReg(), TypeInfo.ScopeInfo);

            var proc = param.Exe.AddFunc(newset);

            var closureCmd = new Command(Opcode.CLOSURE).SetCodePos(TypeInfo.FuncPos);

            closureCmd.EntryName = newset.Name;

            param.CS.Add(closureCmd);

            var funcParam = param.SetLHS(false).SetCmdSet(newset);

            // 深度遍历, 所以最终引用层会先被遍历到
            Body.Compile(funcParam);

            // 找到这一层闭包用的upvalues集合(引用上面函数作用域的)
            FindUsedUpvalue(Body);

            // 给每一个upvalue添加引用的upvalue
            foreach (var uv in UpValues)
            {
                AddRefUpvalueInNode(TypeInfo.ScopeInfo, uv.Symbol.RegBelong, uv);
            }

            int ThisLevelIndex = 0;

            foreach (var uv in UpValues)
            {
                var cmd = param.CS.Add(new Command(Opcode.LINKU, -1, -1))
                          .SetComment(uv.ToString())
                          .SetCodePos(TypeInfo.FuncPos);


                // 引用的上一层的upvalue的索引, 对应指令引用LocalReg的Index
                int UplevelIndex = GetRegIndex(TypeInfo.ScopeInfo, uv.Name);
                if (UplevelIndex != -1)
                {
                    cmd.DataA = 0;
                    cmd.DataB = UplevelIndex;
                }
                else
                {
                    // 引用上层自己的Upvalue(间接引用)
                    UplevelIndex = GetUpvalueIndex(TypeInfo.ScopeInfo, uv.Name);

                    cmd.DataA = 1;
                    cmd.DataB = UplevelIndex;
                }


                // LOADU的对应的Upvalue的索引, 修改下
                uv.CmdGen.DataA = ThisLevelIndex;

                ThisLevelIndex++;
            }

            TypeInfo.GenDefaultRet(Body.Child(), funcParam);

            newset.InputValueCount = TypeInfo.Params.Count;

            newset.OutputValueCount = FuncType.CalcReturnValueCount(Body.Child());
        }