@@ -33,7 +33,7 @@ function Compiler:new()
3333 registerVars = {};
3434
3535 VAR_REGISTER = newproxy (false );
36- RETURN_ALL = newproxy (false );
36+ RETURN_ALL = newproxy (false );
3737 POS_REGISTER = newproxy (false );
3838 RETURN_REGISTER = newproxy (false );
3939 UPVALUE = newproxy (false );
@@ -86,7 +86,7 @@ function Compiler:setActiveBlock(block)
8686end
8787
8888function Compiler :addStatement (statement , writes , reads , usesUpvals )
89- if (self .activeBlock .advanceToNextBlock ) then
89+ if (self .activeBlock .advanceToNextBlock ) then
9090 table.insert (self .activeBlock .statements , {
9191 statement = statement ,
9292 writes = lookupify (writes ),
@@ -123,7 +123,7 @@ function Compiler:compile(ast)
123123 local _ , setmetatableVar = newGlobalScope :resolve (" setmetatable" );
124124 local _ , getmetatableVar = newGlobalScope :resolve (" getmetatable" );
125125 local _ , selectVar = newGlobalScope :resolve (" select" );
126-
126+
127127 psc :addReferenceToHigherScope (newGlobalScope , getfenvVar , 2 );
128128 psc :addReferenceToHigherScope (newGlobalScope , tableVar );
129129 psc :addReferenceToHigherScope (newGlobalScope , unpackVar );
@@ -331,7 +331,7 @@ function Compiler:getCreateClosureVar(argCount)
331331 local var = Ast .AssignmentVariable (self .scope , self .scope :addVariable ());
332332 local createClosureScope = Scope :new (self .scope );
333333 local createClosureSubScope = Scope :new (createClosureScope );
334-
334+
335335 local createClosurePosArg = createClosureScope :addVariable ();
336336 local createClosureUpvalsArg = createClosureScope :addVariable ();
337337 local createClosureProxyObject = createClosureScope :addVariable ();
@@ -384,7 +384,7 @@ function Compiler:getCreateClosureVar(argCount)
384384 }
385385 end
386386
387-
387+
388388 local var = self .createClosureVars [argCount ].var ;
389389 return var .scope , var .id ;
390390end
@@ -419,7 +419,7 @@ function Compiler:createUpvaluesGcFunc()
419419 local ifScope = Scope :new (whileScope );
420420 ifScope :addReferenceToHigherScope (self .scope , self .upvaluesReferenceCountsTable , 1 );
421421 ifScope :addReferenceToHigherScope (self .scope , self .upvaluesTable , 1 );
422-
422+
423423
424424 return Ast .FunctionLiteralExpression ({Ast .VariableExpression (scope , selfVar )}, Ast .Block ({
425425 Ast .LocalVariableDeclaration (scope , {iteratorVar , valueVar }, {Ast .NumberExpression (1 ), Ast .IndexExpression (Ast .VariableExpression (scope , selfVar ), Ast .NumberExpression (1 ))}),
@@ -674,7 +674,7 @@ function Compiler:emitContainerFuncBody()
674674
675675 self .whileScope :addReferenceToHigherScope (self .containerFuncScope , self .returnVar , 1 );
676676 self .whileScope :addReferenceToHigherScope (self .containerFuncScope , self .posVar );
677-
677+
678678 self .containerFuncScope :addReferenceToHigherScope (self .scope , self .unpackVar );
679679
680680 local declarations = {
@@ -736,7 +736,7 @@ function Compiler:allocRegister(isVar)
736736 return self .RETURN_REGISTER ;
737737 end
738738 end
739-
739+
740740
741741 local id = 0 ;
742742 if self .usedRegisters < MAX_REGS * MAX_REGS_MUL then
921921
922922function Compiler :setPos (scope , val )
923923 if not val then
924-
924+
925925 local v = Ast .IndexExpression (self :env (scope ), randomStrings .randomStringNode (math.random (12 , 14 ))); -- Ast.NilExpression();
926926 scope :addReferenceToHigherScope (self .containerFuncScope , self .posVar );
927927 return Ast .AssignmentStatement ({Ast .AssignmentVariable (self .containerFuncScope , self .posVar )}, {v });
@@ -979,7 +979,7 @@ function Compiler:compileTopNode(node)
979979 AstKind .TopNode ,
980980 }
981981 -- Collect Upvalues
982- visitast (node , function (node , data )
982+ visitast (node , function (node , data )
983983 if node .kind == AstKind .Block then
984984 node .scope .__depth = data .functionData .depth ;
985985 end
@@ -1100,7 +1100,7 @@ function Compiler:compileFunction(node, funcDepth)
11001100 self :setActiveBlock (oldActiveBlock );
11011101
11021102 local scope = self .activeBlock .scope ;
1103-
1103+
11041104 local retReg = self :allocRegister (false );
11051105
11061106 local isVarargFunction = # node .args > 0 and node .args [# node .args ].kind == AstKind .VarargExpression ;
@@ -1250,7 +1250,7 @@ function Compiler:compileStatement(statement, funcDepth)
12501250 for i , reg in ipairs (regs ) do
12511251 self :freeRegister (reg , false );
12521252 end
1253-
1253+
12541254 return ;
12551255 end
12561256
@@ -1283,13 +1283,13 @@ function Compiler:compileStatement(statement, funcDepth)
12831283 for i , reg in ipairs (regs ) do
12841284 self :freeRegister (reg , false );
12851285 end
1286-
1286+
12871287 return ;
12881288 end
12891289
12901290 -- Local Function Declaration
12911291 if (statement .kind == AstKind .LocalFunctionDeclaration ) then
1292-
1292+
12931293 if (self :isUpvalue (statement .scope , statement .id )) then
12941294 local varReg = self :getVarRegister (statement .scope , statement .id , funcDepth , nil );
12951295 scope :addReferenceToHigherScope (self .scope , self .allocUpvalFunction );
@@ -1478,7 +1478,7 @@ function Compiler:compileStatement(statement, funcDepth)
14781478 local innerBlock = self :createBlock ();
14791479
14801480 self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (nextBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
1481-
1481+
14821482 self :freeRegister (conditionReg , false );
14831483
14841484 self :setActiveBlock (innerBlock );
@@ -1497,7 +1497,7 @@ function Compiler:compileStatement(statement, funcDepth)
14971497 end
14981498 local scope = self .activeBlock .scope ;
14991499 self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (innerBlock .id )), Ast .NumberExpression (nextBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
1500-
1500+
15011501 self :freeRegister (conditionReg , false );
15021502
15031503 self :setActiveBlock (innerBlock );
@@ -1552,28 +1552,39 @@ function Compiler:compileStatement(statement, funcDepth)
15521552 if (statement .kind == AstKind .RepeatStatement ) then
15531553 local innerBlock = self :createBlock ();
15541554 local finalBlock = self :createBlock ();
1555- local checkBlock = self :createBlock ();
1556- statement .__start_block = checkBlock ;
1555+ statement .__start_block = innerBlock ;
15571556 statement .__final_block = finalBlock ;
15581557
1559- local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
15601558 self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (innerBlock .id )), {self .POS_REGISTER }, {}, false );
1561- self :freeRegister (conditionReg , false );
1562-
15631559 self :setActiveBlock (innerBlock );
1564- self :compileBlock (statement .body , funcDepth );
1565- local scope = self .activeBlock .scope
1566- self :addStatement (self :setPos (scope , checkBlock .id ), {self .POS_REGISTER }, {}, false );
1567- self :setActiveBlock (checkBlock );
1560+
1561+ -- Compile body statements without automatic variable cleanup
1562+ -- self:compileBlock(statement.body, funcDepth);
1563+ for i , stat in ipairs (statement .body .statements ) do
1564+ self :compileStatement (stat , funcDepth );
1565+ end ;
1566+
15681567 local scope = self .activeBlock .scope ;
1569- local conditionReg = self :compileExpression (statement .condition , funcDepth , 1 )[1 ];
1570- self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (finalBlock .id )), Ast .NumberExpression (innerBlock .id ))), {self .POS_REGISTER }, {conditionReg }, false );
1568+ -- Evaluate condition (can access body's local variables)
1569+ local conditionReg = (self :compileExpression (statement .condition , funcDepth , 1 ))[1 ];
1570+ self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .OrExpression (Ast .AndExpression (self :register (scope , conditionReg ), Ast .NumberExpression (finalBlock .id )), Ast .NumberExpression (innerBlock .id ))), { self .POS_REGISTER }, { conditionReg }, false );
15711571 self :freeRegister (conditionReg , false );
15721572
1573- self :setActiveBlock (finalBlock );
1573+ -- Clean up body's local variables
1574+ for id , name in ipairs (statement .body .scope .variables ) do
1575+ local varReg = self :getVarRegister (statement .body .scope , id , funcDepth , nil );
1576+ if self :isUpvalue (statement .body .scope , id ) then
1577+ scope :addReferenceToHigherScope (self .scope , self .freeUpvalueFunc );
1578+ self :addStatement (self :setRegister (scope , varReg , Ast .FunctionCallExpression (Ast .VariableExpression (self .scope , self .freeUpvalueFunc ), { self :register (scope , varReg ) })), { varReg }, { varReg }, false );
1579+ else
1580+ self :addStatement (self :setRegister (scope , varReg , Ast .NilExpression ()), { varReg }, {}, false );
1581+ end ;
1582+ self :freeRegister (varReg , true );
1583+ end ;
15741584
1585+ self :setActiveBlock (finalBlock );
15751586 return ;
1576- end
1587+ end ;
15771588
15781589 -- For Statement
15791590 if (statement .kind == AstKind .ForStatement ) then
@@ -1602,7 +1613,7 @@ function Compiler:compileStatement(statement, funcDepth)
16021613 local tmpReg = self :allocRegister (false );
16031614 self :addStatement (self :setRegister (scope , tmpReg , Ast .NumberExpression (0 )), {tmpReg }, {}, false );
16041615 local incrementIsNegReg = self :allocRegister (false );
1605- self :addStatement (self :setRegister (scope , incrementIsNegReg , Ast .LessThanExpression (self :register (scope , incrementReg ), self :register (scope , tmpReg ))), {incrementIsNegReg }, {incrementReg , tmpReg }, false );
1616+ self :addStatement (self :setRegister (scope , incrementIsNegReg , Ast .LessThanExpression (self :register (scope , incrementReg ), self :register (scope , tmpReg ))), {incrementIsNegReg }, {incrementReg , tmpReg }, false );
16061617 self :freeRegister (tmpReg );
16071618
16081619 local currentReg = self :allocRegister (true );
@@ -1646,10 +1657,10 @@ function Compiler:compileStatement(statement, funcDepth)
16461657 self :addStatement (self :setRegister (scope , varReg , self :register (scope , currentReg )), {varReg }, {currentReg }, false );
16471658 end
16481659
1649-
1660+
16501661 self :compileBlock (statement .body , funcDepth );
16511662 self :addStatement (self :setRegister (scope , self .POS_REGISTER , Ast .NumberExpression (checkBlock .id )), {self .POS_REGISTER }, {}, false );
1652-
1663+
16531664 self .registers [self .POS_REGISTER ] = self .VAR_REGISTER ;
16541665 self :freeRegister (finalReg );
16551666 self :freeRegister (incrementIsNegReg );
@@ -1983,7 +1994,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
19831994 retRegs [i ] = self :allocRegister (false );
19841995 end
19851996 end
1986-
1997+
19871998 local regs = {};
19881999 local args = {};
19892000 for i , expr in ipairs (expression .args ) do
@@ -2005,13 +2016,13 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
20052016 else
20062017 if (numReturns > 1 ) then
20072018 local tmpReg = self :allocRegister (false );
2008-
2019+
20092020 self :addStatement (self :setRegister (scope , tmpReg , Ast .TableConstructorExpression {Ast .TableEntry (Ast .FunctionCallExpression (self :register (scope , baseReg ), args ))}), {tmpReg }, {baseReg , unpack (regs )}, true );
2010-
2021+
20112022 for i , reg in ipairs (retRegs ) do
20122023 self :addStatement (self :setRegister (scope , reg , Ast .IndexExpression (self :register (scope , tmpReg ), Ast .NumberExpression (i ))), {reg }, {tmpReg }, false );
20132024 end
2014-
2025+
20152026 self :freeRegister (tmpReg , false );
20162027 else
20172028 self :addStatement (self :setRegister (scope , retRegs [1 ], Ast .FunctionCallExpression (self :register (scope , baseReg ), args )), {retRegs [1 ]}, {baseReg , unpack (regs )}, true );
@@ -2022,7 +2033,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
20222033 for i , reg in ipairs (regs ) do
20232034 self :freeRegister (reg , false );
20242035 end
2025-
2036+
20262037 return retRegs ;
20272038 end
20282039
@@ -2085,7 +2096,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
20852096 for i , reg in ipairs (regs ) do
20862097 self :freeRegister (reg , false );
20872098 end
2088-
2099+
20892100 return retRegs ;
20902101 end
20912102
@@ -2175,7 +2186,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
21752186 return regs ;
21762187 end
21772188
2178- if (expression .kind == AstKind .OrExpression ) then
2189+ if (expression .kind == AstKind .OrExpression ) then
21792190 local posState = self .registers [self .POS_REGISTER ];
21802191 self .registers [self .POS_REGISTER ] = self .VAR_REGISTER ;
21812192
@@ -2234,7 +2245,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
22342245 return regs ;
22352246 end
22362247
2237- if (expression .kind == AstKind .AndExpression ) then
2248+ if (expression .kind == AstKind .AndExpression ) then
22382249 local posState = self .registers [self .POS_REGISTER ];
22392250 self .registers [self .POS_REGISTER ] = self .VAR_REGISTER ;
22402251
@@ -2254,7 +2265,7 @@ function Compiler:compileExpression(expression, funcDepth, numReturns)
22542265 self :addStatement (self :copyRegisters (scope , {tmpReg }, {self .POS_REGISTER }), {tmpReg }, {self .POS_REGISTER }, false );
22552266 end
22562267
2257-
2268+
22582269 local lhsReg = self :compileExpression (expression .lhs , funcDepth , 1 )[1 ];
22592270 if (expression .rhs .isConstant ) then
22602271 local rhsReg = self :compileExpression (expression .rhs , funcDepth , 1 )[1 ];
0 commit comments