This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch tor-browser-91.9.0esr-11.5-2 in repository tor-browser.
commit b3fc1153364b2caca934e1da56fd90c934e0529f Author: Iain Ireland iireland@mozilla.com AuthorDate: Thu May 19 06:48:50 2022 +0000
Bug 1770048: Improve self-hosted new_List (ESR) r=jandem,tcampbell, a=dsmith
Differential Revision: https://phabricator.services.mozilla.com/D146774 --- js/src/builtin/Array.cpp | 32 ++++++++++++++++++++++++++++++++ js/src/builtin/Array.h | 2 ++ js/src/builtin/Module.js | 17 ++++++++--------- js/src/builtin/RegExp.js | 6 +++--- js/src/builtin/Utilities.js | 11 +---------- js/src/vm/SelfHosting.cpp | 3 ++- 6 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/js/src/builtin/Array.cpp b/js/src/builtin/Array.cpp index be262fb8ffebc..8afbd34fcf674 100644 --- a/js/src/builtin/Array.cpp +++ b/js/src/builtin/Array.cpp @@ -4243,3 +4243,35 @@ JS_PUBLIC_API bool JS::SetArrayLength(JSContext* cx, Handle<JSObject*> obj,
return SetLengthProperty(cx, obj, length); } + +bool js::intrinsic_newList(JSContext* cx, unsigned argc, js::Value* vp) { + CallArgs args = CallArgsFromVp(argc, vp); + MOZ_ASSERT(args.length() == 0); + + size_t length = 0; + gc::AllocKind allocKind = GuessArrayGCKind(length); + MOZ_ASSERT(CanChangeToBackgroundAllocKind(allocKind, &ArrayObject::class_)); + allocKind = ForegroundToBackgroundAllocKind(allocKind); + + /* + * Get a shape with zero fixed slots, regardless of the size class. + * See JSObject::createArray. + */ + RootedShape shape( + cx, SharedShape::getInitialShape(cx, &ArrayObject::class_, cx->realm(), + TaggedProto(), gc::AllocKind::OBJECT0)); + if (!shape) { + return false; + } + + gc::InitialHeap heap = gc::InitialHeap::DefaultHeap; + AutoSetNewObjectMetadata metadata(cx); + RootedArrayObject list(cx, ArrayObject::createArray(cx, allocKind, heap, + shape, length, metadata)); + if (!list || !AddLengthProperty(cx, list)) { + return false; + } + + args.rval().setObject(*list); + return true; +} diff --git a/js/src/builtin/Array.h b/js/src/builtin/Array.h index 2cea9fc920893..d49dca79f2474 100644 --- a/js/src/builtin/Array.h +++ b/js/src/builtin/Array.h @@ -116,6 +116,8 @@ extern bool array_slice(JSContext* cx, unsigned argc, js::Value* vp); extern JSObject* ArraySliceDense(JSContext* cx, HandleObject obj, int32_t begin, int32_t end, HandleObject result);
+extern bool intrinsic_newList(JSContext* cx, unsigned argc, js::Value* vp); + /* * Append the given (non-hole) value to the end of an array. The array must be * a newborn array -- that is, one which has not been exposed to script for diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js index 2716074452ec7..0b5cac4e030e6 100644 --- a/js/src/builtin/Module.js +++ b/js/src/builtin/Module.js @@ -14,7 +14,7 @@ function CallModuleResolveHook(module, moduleRequest, expectedMinimumStatus)
// https://tc39.es/ecma262/#sec-getexportednames // ES2020 15.2.1.17.2 GetExportedNames -function ModuleGetExportedNames(exportStarSet = []) +function ModuleGetExportedNames(exportStarSet = new_List()) { if (!IsObject(this) || !IsModule(this)) { return callFunction(CallModuleMethodIfWrapped, this, exportStarSet, @@ -26,13 +26,13 @@ function ModuleGetExportedNames(exportStarSet = [])
// Step 4 if (callFunction(ArrayIncludes, exportStarSet, module)) - return []; + return new_List();
// Step 5 DefineDataProperty(exportStarSet, exportStarSet.length, module);
// Step 6 - let exportedNames = []; + let exportedNames = new_List(); let namesCount = 0;
// Step 7 @@ -99,7 +99,7 @@ function ModuleSetStatus(module, newStatus) // - If the request is found to be ambiguous, the string `"ambiguous"` is // returned. // -function ModuleResolveExport(exportName, resolveSet = []) +function ModuleResolveExport(exportName, resolveSet = new_List()) { assert(typeof exportName === "string", "ModuleResolveExport");
@@ -206,7 +206,7 @@ function GetModuleNamespace(module) // Step 4 if (typeof namespace === "undefined") { let exportedNames = callFunction(module.getExportedNames, module); - let unambiguousNames = []; + let unambiguousNames = new_List(); for (let i = 0; i < exportedNames.length; i++) { let name = exportedNames[i]; let resolution = callFunction(module.resolveExport, module, name); @@ -312,7 +312,7 @@ function ModuleInstantiate() }
// Step 3 - let stack = []; + let stack = new_List();
// Steps 4-5 try { @@ -606,7 +606,7 @@ function ModuleEvaluate() }
// Step 4 - let stack = []; + let stack = new_List();
// Steps 5-6 try { @@ -769,7 +769,7 @@ function InnerModuleEvaluation(module, stack, index) }
// https://tc39.es/proposal-top-level-await/#sec-gather-async-parent-completion... -function GatherAsyncParentCompletions(module, execList = []) { +function GatherAsyncParentCompletions(module, execList = new_List()) { assert(module.status == MODULE_STATUS_EVALUATED, "bad status for async module");
// Step 5. @@ -809,4 +809,3 @@ function ExecuteAsyncModule(module) {
ExecuteModule(module); } - diff --git a/js/src/builtin/RegExp.js b/js/src/builtin/RegExp.js index 81b5d6f34c119..619664288c86a 100644 --- a/js/src/builtin/RegExp.js +++ b/js/src/builtin/RegExp.js @@ -349,7 +349,7 @@ function RegExpReplaceSlowPath(rx, S, lengthS, replaceValue, }
// Step 9. - var results = []; + var results = new_List(); var nResults = 0;
// Step 11. @@ -456,7 +456,7 @@ function RegExpGetComplexReplacement(result, matched, S, position, functionalReplace, firstDollarIndex) { // Step 14.h. - var captures = []; + var captures = new_List(); var capturesLength = 0;
// Step 14.k.i (reordered). @@ -546,7 +546,7 @@ function RegExpGetFunctionalReplacement(result, S, position, replaceValue) { }
// Steps 14.g-i, 14.k.i-ii. - var captures = []; + var captures = new_List(); for (var n = 0; n <= nCaptures; n++) { assert(typeof result[n] === "string" || result[n] === undefined, "RegExpMatcher returns only strings and undefined"); diff --git a/js/src/builtin/Utilities.js b/js/src/builtin/Utilities.js index 64ea59e4f2a2a..18400b490b6ef 100644 --- a/js/src/builtin/Utilities.js +++ b/js/src/builtin/Utilities.js @@ -27,16 +27,7 @@ // code are installed via the std_functions JSFunctionSpec[] in // SelfHosting.cpp.
-/********** List / Record specification types **********/ - -// A "List" is an internal type used in the ECMAScript spec to define a simple -// ordered list of values. It is never exposed to user script, but we use a -// simple Object (with null prototype) as a convenient implementation. -// -// NOTE: This does not track a `length` field. -function new_List() { - return std_Object_create(null); -} +/********** Specification types **********/
// A "Record" is an internal type used in the ECMAScript spec to define a struct diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 0246343da8d06..c90679caabdda 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2386,7 +2386,7 @@ static const JSFunctionSpec intrinsic_functions[] = { JS_INLINABLE_FN("UnsafeSetReservedSlot", intrinsic_UnsafeSetReservedSlot, 3, 0, IntrinsicUnsafeSetReservedSlot),
- // Intrinsics and standard functions used by Intl API implementation. +// Intrinsics and standard functions used by Intl API implementation. #ifdef JS_HAS_INTL_API JS_FN("intl_BestAvailableLocale", intl_BestAvailableLocale, 3, 0), JS_FN("intl_CallCollatorMethodIfWrapped", @@ -2476,6 +2476,7 @@ static const JSFunctionSpec intrinsic_functions[] = { #endif // JS_HAS_INTL_API
// Standard builtins used by self-hosting. + JS_FN("new_List", intrinsic_newList, 0, 0), JS_INLINABLE_FN("std_Array", array_construct, 1, 0, Array), JS_INLINABLE_FN("std_Array_pop", array_pop, 0, 0, ArrayPop), JS_INLINABLE_FN("std_Array_push", array_push, 1, 0, ArrayPush),