mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2026-04-19 10:20:22 +00:00
When a loop or switch body produces an abrupt completion (break or
continue) with an empty value, the ES spec requires UpdateEmpty to
replace the empty value with the last non-empty completion value V.
The bytecode compiler was failing to do this because it only updated
the completion register after body codegen, guarded by
!is_current_block_terminated(). When break/continue terminated the
block, the update was skipped.
Fix this with three changes:
1. Introduce a CompletionRegisterScope that tells
ScopeNode::generate_bytecode to eagerly emit Mov instructions
into the completion register after each value-producing
statement. This ensures the register is up to date before any
break or continue fires.
2. Give IfStatement its own CompletionRegisterScope (initialized
to undefined) during branch evaluation. This models the spec's
UpdateEmpty(stmtCompletion, undefined) for if-statements: when
break/continue fires inside an if-branch, the scoped jump
propagation sees that the if's completion register differs from
the loop's and emits a Mov, correctly replacing the eagerly
written value with undefined. Without this, code like
{ 3; if (true) { break; } else { } } would incorrectly carry
the value 3 instead of undefined through the break.
3. Capture loop body results and emit a fallback Mov for
non-ScopeNode bodies (e.g. bare expression statements like
do x=1; while(false)) that don't participate in the eager
CompletionRegisterScope update mechanism.
For labelled break/continue that cross loop boundaries, the jump
codegen now propagates the inner completion register to the target
scope's completion register before emitting the jump.
Also fix ForStatement to use a proper completion register
(previously it returned the body result directly, which was wrong
for empty bodies and break-with-no-value cases).
|
||
|---|---|---|
| .. | ||
| ASTCodegen.cpp | ||
| BasicBlock.cpp | ||
| BasicBlock.h | ||
| BuiltinAbstractOperationsEnabled.h | ||
| Builtins.cpp | ||
| Builtins.h | ||
| Bytecode.def | ||
| CodeGenerationError.cpp | ||
| CodeGenerationError.h | ||
| Executable.cpp | ||
| Executable.h | ||
| FormatOperand.h | ||
| Generator.cpp | ||
| Generator.h | ||
| IdentifierTable.cpp | ||
| IdentifierTable.h | ||
| Instruction.cpp | ||
| Instruction.h | ||
| Interpreter.cpp | ||
| Interpreter.h | ||
| Label.cpp | ||
| Label.h | ||
| Operand.h | ||
| PropertyAccess.h | ||
| PropertyKeyTable.cpp | ||
| PropertyKeyTable.h | ||
| PutKind.h | ||
| RegexTable.cpp | ||
| RegexTable.h | ||
| Register.h | ||
| ScopedOperand.cpp | ||
| ScopedOperand.h | ||
| StringTable.cpp | ||
| StringTable.h | ||