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)); }
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); } }
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); }
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)); }
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()); }
internal RuntimeFrame(ValuePhoFunc cs) { Func = cs; }
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 ============"); } }
// 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()); }