diff options
author | davidot <davidot@serenityos.org> | 2022-11-17 01:39:59 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-11-17 16:05:20 +0000 |
commit | 8fa6861f663b72231973f0e208dbba90a90a7f2c (patch) | |
tree | 1ab427f7cec66c4ad1feced4818947d8460e3d76 /Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp | |
parent | 5ca6e8dca843c7efa8d078abb6756d3c9ad0f47b (diff) | |
download | serenity-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.cpp | 7 |
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()); |