A slightly better job could be done by checking whether there are upvalues in the block, and if not, save a register copy, but I don't have time to test this thoroughly yet so I stick to the safer version.function expr.Stat (fs, ast, v) local save_nactvar = fs.nactvar local dest_reg = fs.freereg local save_actvar = { } local last_unreg_var = #fs.actvar if last_unreg_var > 0 or fs.actvar[0] then for i = fs.nactvar, last_unreg_var do save_actvar[i] = fs.actvar[i] end end fs.nactvar = fs.freereg enterblock (fs, { }, false) chunk (fs, ast[1]) expr.expr (fs, ast[2], v) luaK:exp2nextreg (fs, v) leaveblock (fs) luaK:exp2reg (fs, v, dest_reg) fs.freereg = fs.freereg+1 fs.nactvar = save_nactvar for i, j in pairs(save_actvar) do fs.actvar[i] = j end end
Sunday, May 13, 2007
Bug again
Found a new bug, in the compiler, for the `Stat{ b, e } expression AST. This node's purpose is to include a block of statements b where an expression was expected. The node's value is the value of expression e, evaluated as if it were in the block's context, So that `Stat{ +{block: local x=3}, +{expr: x} } evaluates to 3.
If the block declares local variables holding upvalues (i.e. values used by closures), they might be overridden before being saved out of the stack (so that they would survive the block's scope).
Quick fix: replace function expr.Stat in compile.lua with the following code:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment