void OpGenerateClosure(int a, Function func) { CallInfo call = _calls.Last(); Closure closure = call.closure; Closure new_closure = _vm.NewClosure(); new_closure.func = func; new_closure.env_table = closure.env_table; _stack[a] = new_closure; // prepare upvalues int count = func.GetUpValueCount(); for (int i = 0; i < count; ++i) { var upvalue_info = func.GetUpValueInfo(i); if (upvalue_info.is_parent_local) { UpValue upvalue = null; int reg = call.register_idx + upvalue_info.register; // find upvalue var iter = _upvalues.Last; while (iter != null) { if (iter.Value.idx <= reg) { break; } else { iter = iter.Previous; } } if (iter == null) { upvalue = NewUpValue(reg); _upvalues.AddFirst(upvalue); } else if (iter.Value.idx < reg) { upvalue = NewUpValue(reg); _upvalues.AddAfter(iter, upvalue); } else { upvalue = iter.Value; } new_closure.AddUpvalue(upvalue); } else { var upvalue = closure.GetUpvalue(upvalue_info.register); new_closure.AddUpvalue(upvalue); } } }
void OpCloseUpvalueTo(int a) { while (_upvalues.Count > 0) { UpValue upvalue = _upvalues.Last.Value; if (upvalue.idx >= a) { upvalue.Close(); _upvalues.RemoveLast(); } else { break; } } }
internal void AddUpvalue(UpValue upvalue_) { _upvalues.Add(upvalue_); }