Skip to content

Commit

Permalink
Fix compilation of named variables in loop headers
Browse files Browse the repository at this point in the history
We must open new scopes for loop headers. Otherwise we might try to
reuse a named variable created in the loop header in its body, which
is invalid. See the added tests for examples.

Change-Id: Ib2df5df6b28ba28432706c69630eef22452fb858
Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/7934191
Reviewed-by: Carl Smith <[email protected]>
Commit-Queue: Carl Smith <[email protected]>
Auto-Submit: Samuel Groß <[email protected]>
  • Loading branch information
Samuel Groß authored and V8-internal LUCI CQ committed Jan 7, 2025
1 parent 78e6dc7 commit 50d2fcc
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
14 changes: 8 additions & 6 deletions Sources/Fuzzilli/Compiler/Compiler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,10 @@ public class JavaScriptCompiler {
case .whileLoop(let whileLoop):
emit(BeginWhileLoopHeader())

let cond = try compileExpression(whileLoop.test)

emit(BeginWhileLoopBody(), withInputs: [cond])
try enterNewScope {
let cond = try compileExpression(whileLoop.test)
emit(BeginWhileLoopBody(), withInputs: [cond])
}

try enterNewScope {
try compileBody(whileLoop.body)
Expand All @@ -357,9 +358,10 @@ public class JavaScriptCompiler {

emit(BeginDoWhileLoopHeader())

let cond = try compileExpression(doWhileLoop.test)

emit(EndDoWhileLoop(), withInputs: [cond])
try enterNewScope {
let cond = try compileExpression(doWhileLoop.test)
emit(EndDoWhileLoop(), withInputs: [cond])
}

case .forLoop(let forLoop):
var loopVariables = [String]()
Expand Down
9 changes: 0 additions & 9 deletions Tests/FuzzilliTests/CompilerTests/advanced_loops.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,3 @@ for (output("inside for loop initializer"); output("inside for loop condition"),
if (!countdown()) break;
}
resetCounter();

// Test scoping in the different parts of a for loop.
{
global = { start: 0, end: 3, step: 1, value: 42 };
}
for (let i = global.start; i < global.end; i += global.step) {
output("inside for loop body with global value", global.value);
}

38 changes: 38 additions & 0 deletions Tests/FuzzilliTests/CompilerTests/named_variables_scoping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
if (typeof output === 'undefined') output = console.log;

// Test to ensure that multiple uses of the same named variable compile correctly.

{
// This named variable will go out of scope, so subsequent uses require creating a new one (with the same name).
global = { start: 0, end: 3, step: 1, value: 42 };
}

{
if (global.value) {
output("inside if with global value", global.value);
} else {
output("inside else with global value", global.value);
}
}

{
for (let i = global.start; i < global.end; i += global.step) {
output("inside for loop body with global value", global.value);
}
}

{
let i = 0;
while (i < global.end) {
i += global.step;
output("inside while loop body with global value", global.value);
}
}

{
let i = 0;
do {
i += global.step;
output("inside do-while loop body with global value", global.value);
} while (i < global.end);
}

0 comments on commit 50d2fcc

Please sign in to comment.