diff --git a/src/lbi.lua b/src/lbi.lua index cc012a2..5aedac2 100644 --- a/src/lbi.lua +++ b/src/lbi.lua @@ -260,11 +260,26 @@ local function create_wrapper(cache, upvalues) local constants = cache.constants; local prototypes = cache.prototypes; + local current_uvs = {} local stack, top local environment local IP = 1; -- instruction pointer local vararg, vararg_size + local function close_uv(index) + index = index or 0 + + for i, uv in pairs(current_uvs) do + if uv.offset >= index then + uv.value = uv.segment[uv.offset] + uv.segment = uv + uv.offset = 'value' + + current_uvs[i] = nil + end + end + end + local opcode_funcs = { [0] = function(instruction) -- MOVE stack[instruction.A] = stack[instruction.B]; @@ -534,6 +549,8 @@ local function create_wrapper(cache, upvalues) results = {stack[A]()}; end + close_uv() + return true, results end, [30] = function(instruction) -- RETURN @@ -559,6 +576,9 @@ local function create_wrapper(cache, upvalues) loop = loop + 1 output[loop] = stack[i]; end + + close_uv() + return true, output; end, [31] = function(instruction) -- FORLOOP @@ -627,8 +647,7 @@ local function create_wrapper(cache, upvalues) end end, [35] = function(instruction) -- CLOSE - io.stderr:write("NYI: CLOSE") - io.stderr:flush() + close_uv(instruction.A) end, [36] = function(instruction) -- CLOSURE local proto = prototypes[instruction.Bx] @@ -650,8 +669,17 @@ local function create_wrapper(cache, upvalues) ) for i = 1, proto.upvalues do local movement = instructions[IP] + if movement.opcode == 0 then -- MOVE - indices[i-1] = {segment = stack, offset = movement.B} + local index = movement.B + local last_uv = current_uvs[index] + + if not prev then + last_uv = {offset = index, segment = stack} + current_uvs[index] = last_uv + end + + indices[i-1] = last_uv elseif instructions[IP].opcode == 4 then -- GETUPVAL indices[i-1] = {segment = upvalues, offset = movement.B} end