summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
diff options
context:
space:
mode:
authordavidot <davidot@serenityos.org>2022-11-17 01:39:59 +0100
committerLinus Groh <mail@linusgroh.de>2022-11-17 16:05:20 +0000
commit8fa6861f663b72231973f0e208dbba90a90a7f2c (patch)
tree1ab427f7cec66c4ad1feced4818947d8460e3d76 /Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
parent5ca6e8dca843c7efa8d078abb6756d3c9ad0f47b (diff)
downloadserenity-8fa6861f663b72231973f0e208dbba90a90a7f2c.zip
LibJS: Initialize functions in spec order
This is only visible with something like `Object.getOwnPropertyNames` on the global object. All other declaration instantiations put the functions on an environment making the order invisible. Note that spec order is not quite tree order as in non-strict mode functions which get hoisted out of blocks appear before top level functions. Co-authored-by: Hendiadyoin1 <leon.a@serenityos.org>
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp')
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
index 1f108dca5d..39abfd7172 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
@@ -804,6 +804,8 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
// Note: Already done in step iv.
// 3. Insert d as the first element of functionsToInitialize.
+ // NOTE: Since prepending is much slower, we just append
+ // and iterate in reverse order in step 17 below.
functions_to_initialize.append(function);
return {};
}));
@@ -958,7 +960,10 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
}));
// 17. For each Parse Node f of functionsToInitialize, do
- for (auto& declaration : functions_to_initialize) {
+ // NOTE: We iterate in reverse order since we appended the functions
+ // instead of prepending. We append because prepending is much slower
+ // and we only use the created vector here.
+ for (auto& declaration : functions_to_initialize.in_reverse()) {
// a. Let fn be the sole element of the BoundNames of f.
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
auto* function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object());