internal void PreCall(StoryInstance instance, StoryMessageHandler handler, BoxedValue iterator, BoxedValueList args) { //command的执行不像函数,它支持类似协程的机制,允许暂时挂起,稍后继续,这意味着并非每次调用ExecCommand都对应语义上的一次过程调用 //,因此栈的创建不能在ExecCommand里进行(事实上,在ExecCommand里无法区分本次执行是一次新的过程调用还是一次挂起后的继续执行)。 var stackInfo = StoryLocalInfo.New(); //调用实参部分需要在栈建立之前运算,结果需要记录在栈上 for (int i = 0; i < m_LoadedArgs.Count; ++i) { stackInfo.Args.Add(m_LoadedArgs[i].Clone()); } foreach (var pair in m_LoadedOptArgs) { stackInfo.OptArgs.Add(pair.Key, pair.Value.Clone()); } for (int i = 0; i < stackInfo.Args.Count; i++) { stackInfo.Args[i].Evaluate(instance, handler, iterator, args); } foreach (var pair in stackInfo.OptArgs) { pair.Value.Evaluate(instance, handler, iterator, args); } //实参处理完,进入函数体执行,创建新的栈 PushStack(instance, handler, stackInfo); }
public void Evaluate(StoryInstance instance, StoryMessageHandler handler, BoxedValue iterator, BoxedValueList args) { var stackInfo = StoryLocalInfo.New(); var runtime = StoryRuntime.New(); //调用实参部分需要在栈建立之前运算,结果需要记录在栈上 for (int i = 0; i < m_LoadedArgs.Count; ++i) { stackInfo.Args.Add(m_LoadedArgs[i].Clone()); } foreach (var pair in m_LoadedOptArgs) { stackInfo.OptArgs.Add(pair.Key, pair.Value.Clone()); } runtime.Arguments = instance.NewBoxedValueList(); runtime.Arguments.Capacity = stackInfo.Args.Count; for (int i = 0; i < stackInfo.Args.Count; i++) { stackInfo.Args[i].Evaluate(instance, handler, iterator, args); runtime.Arguments.Add(stackInfo.Args[i].Value); } runtime.Iterator = stackInfo.Args.Count; foreach (var pair in stackInfo.OptArgs) { pair.Value.Evaluate(instance, handler, iterator, args); } //实参处理完,进入函数体执行,创建新的栈 PushStack(instance, handler, stackInfo, runtime); try { for (int i = 0; i < m_ArgNames.Count; ++i) { if (i < stackInfo.Args.Count) { instance.SetVariable(m_ArgNames[i], stackInfo.Args[i].Value); } else { instance.SetVariable(m_ArgNames[i], BoxedValue.NullObject); } } foreach (var pair in stackInfo.OptArgs) { instance.SetVariable(pair.Key, pair.Value.Value); } Prepare(runtime); stackInfo.HaveValue = true; runtime.Tick(instance, handler, long.MaxValue); BoxedValue val; instance.TryGetVariable(m_ReturnName, out val); stackInfo.Value = val; } finally { instance.RecycleBoxedValueList(runtime.Arguments); PopStack(instance, handler); } }