From 50d2fcc1fc282885921e53015a468f58abe572bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Gro=C3=9F?= Date: Tue, 7 Jan 2025 13:14:27 +0100 Subject: [PATCH] Fix compilation of named variables in loop headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Commit-Queue: Carl Smith Auto-Submit: Samuel Groß --- Sources/Fuzzilli/Compiler/Compiler.swift | 14 ++++--- .../CompilerTests/advanced_loops.js | 9 ----- .../CompilerTests/named_variables_scoping.js | 38 +++++++++++++++++++ 3 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 Tests/FuzzilliTests/CompilerTests/named_variables_scoping.js diff --git a/Sources/Fuzzilli/Compiler/Compiler.swift b/Sources/Fuzzilli/Compiler/Compiler.swift index d9a7af043..5acd67492 100644 --- a/Sources/Fuzzilli/Compiler/Compiler.swift +++ b/Sources/Fuzzilli/Compiler/Compiler.swift @@ -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) @@ -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]() diff --git a/Tests/FuzzilliTests/CompilerTests/advanced_loops.js b/Tests/FuzzilliTests/CompilerTests/advanced_loops.js index 998ee415e..7f40a8bff 100644 --- a/Tests/FuzzilliTests/CompilerTests/advanced_loops.js +++ b/Tests/FuzzilliTests/CompilerTests/advanced_loops.js @@ -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); -} - diff --git a/Tests/FuzzilliTests/CompilerTests/named_variables_scoping.js b/Tests/FuzzilliTests/CompilerTests/named_variables_scoping.js new file mode 100644 index 000000000..4e56d435b --- /dev/null +++ b/Tests/FuzzilliTests/CompilerTests/named_variables_scoping.js @@ -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); +}