mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:17:45 +00:00
LibJS/Bytecode: Reorder function compilation to ensure correct hoisting
Fixes 37 test262 tests. :^) Co-authored-by: Luke Wilde <lukew@serenityos.org>
This commit is contained in:
parent
9c568282dc
commit
743943a042
1 changed files with 32 additions and 21 deletions
|
@ -833,7 +833,6 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
|||
}
|
||||
|
||||
if (bytecode_interpreter) {
|
||||
if (!m_bytecode_executable) {
|
||||
auto compile = [&](auto& node, auto kind, auto name) -> ThrowCompletionOr<NonnullOwnPtr<Bytecode::Executable>> {
|
||||
auto executable_result = Bytecode::Generator::generate(node, kind);
|
||||
if (executable_result.is_error())
|
||||
|
@ -853,8 +852,14 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
|||
return bytecode_executable;
|
||||
};
|
||||
|
||||
m_bytecode_executable = TRY(compile(*m_ecmascript_code, m_kind, m_name));
|
||||
// NOTE: There's a subtle ordering issue here:
|
||||
// - We have to compile the default parameter values before instantiating the function.
|
||||
// - We have to instantiate the function before compiling the function body.
|
||||
// This is why FunctionDeclarationInstantiation is invoked in the middle.
|
||||
// The issue is that FunctionDeclarationInstantiation may mark certain functions as hoisted
|
||||
// per Annex B. This affects code generation for FunctionDeclaration nodes.
|
||||
|
||||
if (!m_bytecode_executable) {
|
||||
size_t default_parameter_index = 0;
|
||||
for (auto& parameter : m_formal_parameters) {
|
||||
if (!parameter.default_value)
|
||||
|
@ -863,7 +868,13 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
|||
m_default_parameter_bytecode_executables.append(move(executable));
|
||||
}
|
||||
}
|
||||
|
||||
TRY(function_declaration_instantiation(nullptr));
|
||||
|
||||
if (!m_bytecode_executable) {
|
||||
m_bytecode_executable = TRY(compile(*m_ecmascript_code, m_kind, m_name));
|
||||
}
|
||||
|
||||
auto result_and_frame = bytecode_interpreter->run_and_return_frame(*m_bytecode_executable, nullptr);
|
||||
|
||||
VERIFY(result_and_frame.frame != nullptr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue