/// <summary> /// 将函数参数压栈,准备调用函数 /// </summary> /// <param name="parameter"></param> internal void PushFuncParameter(ScriptObject parameter) { Contract.Assert(parameter != null); int funcIndex = _funcPushStack.Peek(); FuncPart func = stack[funcIndex].Value.RefPartHandle.ConverToFuncPart(); //当前栈中的函数参数小于函数参数大小 if (Top - (funcIndex + 1) < func.ArgsCount) { Push(parameter); } else if (func.IsUncertainParameters == true) //是不定参数 { if (Top - (funcIndex + 1) == func.ArgsCount) { ScriptObject s = ScriptObject.CreateTable(); stack.Add(s); } ScriptObject args = stack[Top - 1]; args.AddInArray(parameter); } //否则,则省略掉传入参数 }
/// <summary> /// 调用指定位置的函数 /// </summary> private ScriptObject InvokeFuncAtIndex(int at) { Contract.Assert(stack[at].Type == ValueType.FUNCTION); FuncPart invokeFunc = stack[at].Value.RefPartHandle.ConverToFuncPart(); //如果函数的参数大于压入的参数,则不足部分补Nil while (invokeFunc.ArgsCount > Top - (at + 1)) { Push(RunEnvironment.Nil); } _contextStartStack.Push(contextStart); contextStart = at; //设置当前上下文,很重要 invokeFunc.Value(); //委托调用 stack.RemoveRange(at, Top - at); contextStart = _contextStartStack.Pop(); //恢复当前上下文 Instructor.AssignVar(This, RunEnvironment.Nil); // this 指针清空 return(returnValue); }
/// <summary> /// 设置每一个UpValue /// </summary> public static void SetUpvalue(ScriptObject function, int at, int stackIndex) { Contract.Assert(function.Type == ValueType.FUNCTION); FuncPart func = function.Value.RefPartHandle.ConverToFuncPart(); func.UpVals[at] = RunEnvironment.Instance.LocalStack.GetVarFromBase(stackIndex); }
/// <summary> /// 设置Upvalues的长度 /// </summary> public static void SetUpvaluesLength(ScriptObject function, int length) { Contract.Assert(function.Type == ValueType.FUNCTION); FuncPart func = function.Value.RefPartHandle.ConverToFuncPart(); func.UpVals = new ScriptObject[length]; }