diff options
Diffstat (limited to 'js/src/builtin')
-rw-r--r-- | js/src/builtin/.eslintrc.js | 8 | ||||
-rw-r--r-- | js/src/builtin/DataViewObject.cpp | 141 | ||||
-rw-r--r-- | js/src/builtin/DataViewObject.h | 43 | ||||
-rw-r--r-- | js/src/builtin/ModuleObject.cpp | 163 | ||||
-rw-r--r-- | js/src/builtin/ModuleObject.h | 31 | ||||
-rw-r--r-- | js/src/builtin/ReflectParse.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/String.cpp | 9 | ||||
-rw-r--r-- | js/src/builtin/TestingFunctions.cpp | 146 | ||||
-rw-r--r-- | js/src/builtin/intl/NumberFormat.js | 91 | ||||
-rw-r--r-- | js/src/builtin/intl/PluralRules.js | 42 | ||||
-rwxr-xr-x | js/src/builtin/intl/make_intl_data.py | 8 | ||||
-rw-r--r-- | js/src/builtin/temporal/PlainDate.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/temporal/PlainDateTime.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/temporal/PlainMonthDay.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/temporal/PlainTime.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/temporal/PlainYearMonth.cpp | 3 | ||||
-rw-r--r-- | js/src/builtin/temporal/ZonedDateTime.cpp | 3 |
17 files changed, 409 insertions, 294 deletions
diff --git a/js/src/builtin/.eslintrc.js b/js/src/builtin/.eslintrc.js index 89beca7d4c..76aad2f6fd 100644 --- a/js/src/builtin/.eslintrc.js +++ b/js/src/builtin/.eslintrc.js @@ -121,6 +121,14 @@ module.exports = { message: "'const' declarations are disallowed to avoid TDZ checks, use 'var' instead", }, ], + // Method signatures are important in builtins so disable unused argument errors. + "no-unused-vars": [ + "error", + { + args: "none", + vars: "local", + }, + ], }, globals: { diff --git a/js/src/builtin/DataViewObject.cpp b/js/src/builtin/DataViewObject.cpp index 1f7be86a70..425fdce51d 100644 --- a/js/src/builtin/DataViewObject.cpp +++ b/js/src/builtin/DataViewObject.cpp @@ -65,150 +65,27 @@ DataViewObject* DataViewObject::create( } ResizableDataViewObject* ResizableDataViewObject::create( - JSContext* cx, size_t byteOffset, size_t byteLength, bool autoLength, + JSContext* cx, size_t byteOffset, size_t byteLength, AutoLength autoLength, Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto) { MOZ_ASSERT(arrayBuffer->isResizable()); MOZ_ASSERT(!arrayBuffer->isDetached()); - MOZ_ASSERT(!autoLength || byteLength == 0, + MOZ_ASSERT(autoLength == AutoLength::No || byteLength == 0, "byte length is zero for 'auto' length views"); auto* obj = NewObjectWithClassProto<ResizableDataViewObject>(cx, proto); - if (!obj || !obj->init(cx, arrayBuffer, byteOffset, byteLength, - /* bytesPerElement = */ 1)) { + if (!obj || !obj->initResizable(cx, arrayBuffer, byteOffset, byteLength, + /* bytesPerElement = */ 1, autoLength)) { return nullptr; } - obj->setFixedSlot(AUTO_LENGTH_SLOT, BooleanValue(autoLength)); - return obj; } -/** - * GetViewByteLength ( viewRecord ) - * - * GetViewByteLength can be rewritten into the following spec steps when - * inlining the calls to MakeDataViewWithBufferWitnessRecord and - * IsViewOutOfBounds. - * - * 1. Let buffer be view.[[ViewedArrayBuffer]]. - * 2. If IsDetachedBuffer(buffer) is true, then - * a. Return out-of-bounds. - * 3. If IsFixedLengthArrayBuffer(buffer) is true, - * a. Return view.[[ByteLength]]. - * 4. Let bufferByteLength be ArrayBufferByteLength(buffer, order). - * 5. Let byteOffsetStart be view.[[ByteOffset]]. - * 6. If byteOffsetStart > bufferByteLength, then - * a. Return out-of-bounds. - * 7. If view.[[ByteLength]] is auto, then - * a. Return bufferByteLength - byteOffsetStart. - * 8. Let viewByteLength be view.[[ByteLength]]. - * 9. Let byteOffsetEnd be byteOffsetStart + viewByteLength. - * 10. If byteOffsetEnd > bufferByteLength, then - * a. Return out-of-bounds. - * 11. Return viewByteLength. - * - * The additional call to IsFixedLengthArrayBuffer is an optimization to skip - * unnecessary validation which doesn't apply for fixed length data-views. - * - * https://tc39.es/ecma262/#sec-getviewbytelength - * https://tc39.es/ecma262/#sec-makedataviewwithbufferwitnessrecord - * https://tc39.es/ecma262/#sec-isviewoutofbounds - */ -mozilla::Maybe<size_t> DataViewObject::byteLength() { - if (MOZ_UNLIKELY(hasDetachedBuffer())) { - return mozilla::Nothing{}; - } - - if (MOZ_LIKELY(is<FixedLengthDataViewObject>())) { - size_t viewByteLength = rawByteLength(); - return mozilla::Some(viewByteLength); - } - - auto* buffer = bufferEither(); - MOZ_ASSERT(buffer->isResizable()); - - size_t bufferByteLength = buffer->byteLength(); - size_t byteOffsetStart = ArrayBufferViewObject::byteOffset(); - if (byteOffsetStart > bufferByteLength) { - return mozilla::Nothing{}; - } - - if (as<ResizableDataViewObject>().isAutoLength()) { - return mozilla::Some(bufferByteLength - byteOffsetStart); - } - - size_t viewByteLength = rawByteLength(); - size_t byteOffsetEnd = byteOffsetStart + viewByteLength; - if (byteOffsetEnd > bufferByteLength) { - return mozilla::Nothing{}; - } - return mozilla::Some(viewByteLength); -} - -/** - * IsViewOutOfBounds ( viewRecord ) - * - * IsViewOutOfBounds can be rewritten into the following spec steps when - * inlining the call to MakeDataViewWithBufferWitnessRecord. - * - * 1. Let buffer be obj.[[ViewedArrayBuffer]]. - * 2. If IsDetachedBuffer(buffer) is true, then - * a. Return true. - * 3. If IsFixedLengthArrayBuffer(buffer) is true, then - * a. Return false. - * 4. Let byteLength be ArrayBufferByteLength(buffer, order). - * 5. Let byteOffsetStart be view.[[ByteOffset]]. - * 6. If byteOffsetStart > bufferByteLength, then - * a. Return true. - * 7. If view.[[ByteLength]] is auto, then - * a. Return false. - * 8. Let byteOffsetEnd be byteOffsetStart + view.[[ByteLength]]. - * 9. If byteOffsetEnd > bufferByteLength, then - * a. Return true. - * 10. Return false. - * - * The additional call to IsFixedLengthArrayBuffer is an optimization to skip - * unnecessary validation which doesn't apply for fixed length data-views. - * - * https://tc39.es/ecma262/#sec-makedataviewwithbufferwitnessrecord - * https://tc39.es/ecma262/#sec-isviewoutofbounds - */ -mozilla::Maybe<size_t> DataViewObject::byteOffset() { - if (MOZ_UNLIKELY(hasDetachedBuffer())) { - return mozilla::Nothing{}; - } - - size_t byteOffsetStart = ArrayBufferViewObject::byteOffset(); - - if (MOZ_LIKELY(is<FixedLengthDataViewObject>())) { - return mozilla::Some(byteOffsetStart); - } - - auto* buffer = bufferEither(); - MOZ_ASSERT(buffer->isResizable()); - - size_t bufferByteLength = buffer->byteLength(); - if (byteOffsetStart > bufferByteLength) { - return mozilla::Nothing{}; - } - - if (as<ResizableDataViewObject>().isAutoLength()) { - return mozilla::Some(byteOffsetStart); - } - - size_t viewByteLength = rawByteLength(); - size_t byteOffsetEnd = byteOffsetStart + viewByteLength; - if (byteOffsetEnd > bufferByteLength) { - return mozilla::Nothing{}; - } - return mozilla::Some(byteOffsetStart); -} - // ES2017 draft rev 931261ecef9b047b14daacf82884134da48dfe0f // 24.3.2.1 DataView (extracted part of the main algorithm) bool DataViewObject::getAndCheckConstructorArgs( JSContext* cx, HandleObject bufobj, const CallArgs& args, - size_t* byteOffsetPtr, size_t* byteLengthPtr, bool* autoLengthPtr) { + size_t* byteOffsetPtr, size_t* byteLengthPtr, AutoLength* autoLengthPtr) { // Step 3. if (!bufobj->is<ArrayBufferObjectMaybeShared>()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, @@ -243,10 +120,10 @@ bool DataViewObject::getAndCheckConstructorArgs( MOZ_ASSERT(offset <= ArrayBufferObject::ByteLengthLimit); uint64_t viewByteLength = 0; - bool autoLength = false; + auto autoLength = AutoLength::No; if (!args.hasDefined(2)) { if (buffer->isResizable()) { - autoLength = true; + autoLength = AutoLength::Yes; } else { // Step 8.a viewByteLength = bufferByteLength - offset; @@ -305,7 +182,7 @@ bool DataViewObject::constructSameCompartment(JSContext* cx, size_t byteOffset = 0; size_t byteLength = 0; - bool autoLength = false; + auto autoLength = AutoLength::No; if (!getAndCheckConstructorArgs(cx, bufobj, args, &byteOffset, &byteLength, &autoLength)) { return false; @@ -365,7 +242,7 @@ bool DataViewObject::constructWrapped(JSContext* cx, HandleObject bufobj, // NB: This entails the IsArrayBuffer check size_t byteOffset = 0; size_t byteLength = 0; - bool autoLength = false; + auto autoLength = AutoLength::No; if (!getAndCheckConstructorArgs(cx, unwrapped, args, &byteOffset, &byteLength, &autoLength)) { return false; diff --git a/js/src/builtin/DataViewObject.h b/js/src/builtin/DataViewObject.h index a17b3e1174..db134a5696 100644 --- a/js/src/builtin/DataViewObject.h +++ b/js/src/builtin/DataViewObject.h @@ -48,7 +48,7 @@ class DataViewObject : public ArrayBufferViewObject { const CallArgs& args, size_t* byteOffsetPtr, size_t* byteLengthPtr, - bool* autoLengthPtr); + AutoLength* autoLengthPtr); static bool constructSameCompartment(JSContext* cx, HandleObject bufobj, const CallArgs& args); static bool constructWrapped(JSContext* cx, HandleObject bufobj, @@ -58,16 +58,16 @@ class DataViewObject : public ArrayBufferViewObject { JSContext* cx, size_t byteOffset, size_t byteLength, Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto); - protected: - size_t rawByteLength() const { - return size_t(getFixedSlot(LENGTH_SLOT).toPrivate()); - } - public: static const JSClass protoClass_; - mozilla::Maybe<size_t> byteLength(); - mozilla::Maybe<size_t> byteOffset(); + /** + * Return the current byteLength, or |Nothing| if the DataView is detached or + * out-of-bounds. + */ + mozilla::Maybe<size_t> byteLength() { + return ArrayBufferViewObject::length(); + } template <typename NativeType> static bool offsetIsInBounds(uint64_t offset, size_t byteLength) { @@ -173,19 +173,11 @@ class FixedLengthDataViewObject : public DataViewObject { public: static const JSClass class_; - size_t byteOffset() const { return ArrayBufferViewObject::byteOffset(); } - - size_t byteLength() const { return rawByteLength(); } - - bool offsetIsInBounds(uint32_t byteSize, uint64_t offset) const { - return DataViewObject::offsetIsInBounds(byteSize, offset, byteLength()); + size_t byteOffset() const { + return ArrayBufferViewObject::byteOffsetSlotValue(); } - template <typename NativeType> - NativeType read(uint64_t offset, bool isLittleEndian) { - return DataViewObject::read<NativeType>(offset, byteLength(), - isLittleEndian); - } + size_t byteLength() const { return ArrayBufferViewObject::lengthSlotValue(); } }; /** @@ -195,19 +187,14 @@ class ResizableDataViewObject : public DataViewObject { friend class DataViewObject; static ResizableDataViewObject* create( - JSContext* cx, size_t byteOffset, size_t byteLength, bool autoLength, - Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, HandleObject proto); + JSContext* cx, size_t byteOffset, size_t byteLength, + AutoLength autoLength, Handle<ArrayBufferObjectMaybeShared*> arrayBuffer, + HandleObject proto); public: - static const uint8_t AUTO_LENGTH_SLOT = DataViewObject::RESERVED_SLOTS; - - static const uint8_t RESERVED_SLOTS = DataViewObject::RESERVED_SLOTS + 1; + static const uint8_t RESERVED_SLOTS = RESIZABLE_RESERVED_SLOTS; static const JSClass class_; - - bool isAutoLength() const { - return getFixedSlot(AUTO_LENGTH_SLOT).toBoolean(); - } }; // For structured cloning. diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 0be9aec17b..b9db9bf02d 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -20,7 +20,7 @@ #include "gc/Tracer.h" #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin, JS::LimitedColumnNumberOneOrigin #include "js/friend/ErrorMessages.h" // JSMSG_* -#include "js/Modules.h" // JS::GetModulePrivate, JS::ModuleDynamicImportHook +#include "js/Modules.h" // JS::GetModulePrivate, JS::ModuleDynamicImportHook, JS::ModuleType #include "vm/EqualityOperations.h" // js::SameValue #include "vm/Interpreter.h" // Execute, Lambda, ReportRuntimeLexicalError #include "vm/ModuleBuilder.h" // js::ModuleBuilder @@ -31,6 +31,7 @@ #include "builtin/HandlerFunction-inl.h" // js::ExtraValueFromHandler, js::NewHandler{,WithExtraValue}, js::TargetFromHandler #include "gc/GCContext-inl.h" +#include "vm/EnvironmentObject-inl.h" // EnvironmentObject::setAliasedBinding #include "vm/JSObject-inl.h" #include "vm/JSScript-inl.h" #include "vm/List-inl.h" @@ -184,8 +185,8 @@ ResolvedBindingObject* ResolvedBindingObject::create( DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ModuleRequestObject, specifier, SpecifierSlot) -ArrayObject* ModuleRequestObject::assertions() const { - JSObject* obj = getReservedSlot(AssertionSlot).toObjectOrNull(); +ArrayObject* ModuleRequestObject::attributes() const { + JSObject* obj = getReservedSlot(AttributesSlot).toObjectOrNull(); if (!obj) { return nullptr; } @@ -193,6 +194,52 @@ ArrayObject* ModuleRequestObject::assertions() const { return &obj->as<ArrayObject>(); } +bool ModuleRequestObject::hasAttributes() const { + return !getReservedSlot(ModuleRequestObject::AttributesSlot) + .isNullOrUndefined(); +} + +/* static */ +bool ModuleRequestObject::getModuleType( + JSContext* cx, const Handle<ModuleRequestObject*> moduleRequest, + JS::ModuleType& moduleType) { + if (!moduleRequest->hasAttributes()) { + moduleType = JS::ModuleType::JavaScript; + return true; + } + + Rooted<ArrayObject*> attributesArray(cx, moduleRequest->attributes()); + RootedObject attributeObject(cx); + RootedId typeId(cx, NameToId(cx->names().type)); + RootedValue value(cx); + + uint32_t numberOfAttributes = attributesArray->length(); + for (uint32_t i = 0; i < numberOfAttributes; i++) { + attributeObject = &attributesArray->getDenseElement(i).toObject(); + + if (!GetProperty(cx, attributeObject, attributeObject, typeId, &value)) { + continue; + } + + int32_t isJsonString; + if (!js::CompareStrings(cx, cx->names().json, value.toString(), + &isJsonString)) { + return false; + } + + if (isJsonString == 0) { + moduleType = JS::ModuleType::JSON; + return true; + } + + moduleType = JS::ModuleType::Unknown; + return true; + } + + moduleType = JS::ModuleType::JavaScript; + return true; +} + /* static */ bool ModuleRequestObject::isInstance(HandleValue value) { return value.isObject() && value.toObject().is<ModuleRequestObject>(); @@ -201,7 +248,7 @@ bool ModuleRequestObject::isInstance(HandleValue value) { /* static */ ModuleRequestObject* ModuleRequestObject::create( JSContext* cx, Handle<JSAtom*> specifier, - Handle<ArrayObject*> maybeAssertions) { + Handle<ArrayObject*> maybeAttributes) { ModuleRequestObject* self = NewObjectWithGivenProto<ModuleRequestObject>(cx, nullptr); if (!self) { @@ -209,7 +256,7 @@ ModuleRequestObject* ModuleRequestObject::create( } self->initReservedSlot(SpecifierSlot, StringOrNullValue(specifier)); - self->initReservedSlot(AssertionSlot, ObjectOrNullValue(maybeAssertions)); + self->initReservedSlot(AttributesSlot, ObjectOrNullValue(maybeAttributes)); return self; } @@ -618,6 +665,21 @@ void ModuleNamespaceObject::ProxyHandler::finalize(JS::GCContext* gcx, } /////////////////////////////////////////////////////////////////////////// +// SyntheticModuleFields + +// The fields of a synthetic module record, as described in: +// https://tc39.es/proposal-json-modules/#sec-synthetic-module-records +class js::SyntheticModuleFields { + public: + ExportNameVector exportNames; + + public: + void trace(JSTracer* trc); +}; + +void SyntheticModuleFields::trace(JSTracer* trc) { exportNames.trace(trc); } + +/////////////////////////////////////////////////////////////////////////// // CyclicModuleFields // The fields of a cyclic module record, as described in: @@ -857,6 +919,10 @@ Span<const ExportEntry> ModuleObject::starExportEntries() const { return cyclicModuleFields()->starExportEntries(); } +const ExportNameVector& ModuleObject::syntheticExportNames() const { + return syntheticModuleFields()->exportNames; +} + void ModuleObject::initFunctionDeclarations( UniquePtr<FunctionDeclarationVector> decls) { cyclicModuleFields()->functionDeclarations = std::move(decls); @@ -883,12 +949,39 @@ ModuleObject* ModuleObject::create(JSContext* cx) { } /* static */ +ModuleObject* ModuleObject::createSynthetic( + JSContext* cx, MutableHandle<ExportNameVector> exportNames) { + Rooted<UniquePtr<SyntheticModuleFields>> syntheticFields(cx); + syntheticFields = cx->make_unique<SyntheticModuleFields>(); + if (!syntheticFields) { + return nullptr; + } + + Rooted<ModuleObject*> self( + cx, NewObjectWithGivenProto<ModuleObject>(cx, nullptr)); + if (!self) { + return nullptr; + } + + InitReservedSlot(self, SyntheticModuleFieldsSlot, syntheticFields.release(), + MemoryUse::ModuleSyntheticFields); + + self->syntheticModuleFields()->exportNames = std::move(exportNames.get()); + + return self; +} + +/* static */ void ModuleObject::finalize(JS::GCContext* gcx, JSObject* obj) { ModuleObject* self = &obj->as<ModuleObject>(); if (self->hasCyclicModuleFields()) { gcx->delete_(obj, self->cyclicModuleFields(), MemoryUse::ModuleCyclicFields); } + if (self->hasSyntheticModuleFields()) { + gcx->delete_(obj, self->syntheticModuleFields(), + MemoryUse::ModuleSyntheticFields); + } } ModuleEnvironmentObject& ModuleObject::initialEnvironment() const { @@ -960,6 +1053,7 @@ void ModuleObject::setAsyncEvaluating() { void ModuleObject::initScriptSlots(HandleScript script) { MOZ_ASSERT(script); MOZ_ASSERT(script->sourceObject()); + MOZ_ASSERT(script->filename()); initReservedSlot(ScriptSlot, PrivateGCThingValue(script)); cyclicModuleFields()->scriptSourceObject = script->sourceObject(); } @@ -1021,10 +1115,12 @@ static inline void AssertValidModuleStatus(ModuleStatus status) { } ModuleStatus ModuleObject::status() const { - // TODO: When implementing synthetic module records it may be convenient to - // make this method always return a ModuleStatus::Evaluated for such a module - // so we can assert a module's status without checking which kind it is, even - // though synthetic modules don't have this field according to the spec. + // Always return `ModuleStatus::Evaluated` so we can assert a module's status + // without checking which kind it is, even though synthetic modules don't have + // this field according to the spec. + if (hasSyntheticModuleFields()) { + return ModuleStatus::Evaluated; + } ModuleStatus status = cyclicModuleFields()->status; AssertValidModuleStatus(status); @@ -1161,6 +1257,22 @@ ModuleObject* ModuleObject::getCycleRoot() const { return cyclicModuleFields()->cycleRoot; } +bool ModuleObject::hasSyntheticModuleFields() const { + bool result = !getReservedSlot(SyntheticModuleFieldsSlot).isUndefined(); + MOZ_ASSERT_IF(result, !hasCyclicModuleFields()); + return result; +} + +SyntheticModuleFields* ModuleObject::syntheticModuleFields() { + MOZ_ASSERT(!hasCyclicModuleFields()); + void* ptr = getReservedSlot(SyntheticModuleFieldsSlot).toPrivate(); + MOZ_ASSERT(ptr); + return static_cast<SyntheticModuleFields*>(ptr); +} +const SyntheticModuleFields* ModuleObject::syntheticModuleFields() const { + return const_cast<ModuleObject*>(this)->syntheticModuleFields(); +} + bool ModuleObject::hasTopLevelCapability() const { return cyclicModuleFields()->topLevelCapability; } @@ -1206,6 +1318,9 @@ void ModuleObject::trace(JSTracer* trc, JSObject* obj) { if (module.hasCyclicModuleFields()) { module.cyclicModuleFields()->trace(trc); } + if (module.hasSyntheticModuleFields()) { + module.syntheticModuleFields()->trace(trc); + } } /* static */ @@ -1328,6 +1443,27 @@ bool ModuleObject::createEnvironment(JSContext* cx, return true; } +/*static*/ +bool ModuleObject::createSyntheticEnvironment(JSContext* cx, + Handle<ModuleObject*> self, + Handle<GCVector<Value>> values) { + Rooted<ModuleEnvironmentObject*> env( + cx, ModuleEnvironmentObject::createSynthetic(cx, self)); + if (!env) { + return false; + } + + MOZ_ASSERT(env->shape()->propMapLength() == values.length()); + + for (uint32_t i = 0; i < values.length(); i++) { + env->setAliasedBinding(env->firstSyntheticValueSlot() + i, values[i]); + } + + self->setInitialEnvironment(env); + + return true; +} + /////////////////////////////////////////////////////////////////////////// // ModuleBuilder @@ -2542,10 +2678,11 @@ static bool OnResolvedDynamicModule(JSContext* cx, unsigned argc, Value* vp) { return RejectPromiseWithPendingError(cx, promise); } - MOZ_ASSERT(module->getCycleRoot() - ->topLevelCapability() - ->as<PromiseObject>() - .state() == JS::PromiseState::Fulfilled); + MOZ_ASSERT_IF(module->hasCyclicModuleFields(), + module->getCycleRoot() + ->topLevelCapability() + ->as<PromiseObject>() + .state() == JS::PromiseState::Fulfilled); RootedObject ns(cx, GetOrCreateModuleNamespace(cx, module)); if (!ns) { diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index 015cb42a5f..d39d65b18c 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -43,6 +43,7 @@ namespace js { class ArrayObject; class CyclicModuleFields; +class SyntheticModuleFields; class ListObject; class ModuleEnvironmentObject; class ModuleObject; @@ -51,16 +52,20 @@ class ScriptSourceObject; class ModuleRequestObject : public NativeObject { public: - enum { SpecifierSlot = 0, AssertionSlot, SlotCount }; + enum { SpecifierSlot = 0, AttributesSlot, SlotCount }; static const JSClass class_; static bool isInstance(HandleValue value); [[nodiscard]] static ModuleRequestObject* create( JSContext* cx, Handle<JSAtom*> specifier, - Handle<ArrayObject*> maybeAssertions); + Handle<ArrayObject*> maybeAttributes); JSAtom* specifier() const; - ArrayObject* assertions() const; + ArrayObject* attributes() const; + bool hasAttributes() const; + static bool getModuleType(JSContext* cx, + const Handle<ModuleRequestObject*> moduleRequest, + JS::ModuleType& moduleType); }; using ModuleRequestVector = @@ -309,6 +314,10 @@ constexpr uint32_t ASYNC_EVALUATING_POST_ORDER_INIT = 1; // Value that the field is set to after being cleared. constexpr uint32_t ASYNC_EVALUATING_POST_ORDER_CLEARED = 0; +// Currently, the ModuleObject class is used to represent both the Source Text +// Module Record and the Synthetic Module Record. Ideally, this is something +// that should be refactored to follow the same hierarchy as in the spec. +// TODO: See Bug 1880519. class ModuleObject : public NativeObject { public: // Module fields including those for AbstractModuleRecords described by: @@ -318,6 +327,8 @@ class ModuleObject : public NativeObject { EnvironmentSlot, NamespaceSlot, CyclicModuleFieldsSlot, + // `SyntheticModuleFields` if a synthetic module. Otherwise `undefined`. + SyntheticModuleFieldsSlot, SlotCount }; @@ -327,6 +338,9 @@ class ModuleObject : public NativeObject { static ModuleObject* create(JSContext* cx); + static ModuleObject* createSynthetic( + JSContext* cx, MutableHandle<ExportNameVector> exportNames); + // Initialize the slots on this object that are dependent on the script. void initScriptSlots(HandleScript script); @@ -364,6 +378,8 @@ class ModuleObject : public NativeObject { mozilla::Span<const ExportEntry> localExportEntries() const; mozilla::Span<const ExportEntry> indirectExportEntries() const; mozilla::Span<const ExportEntry> starExportEntries() const; + const ExportNameVector& syntheticExportNames() const; + IndirectBindingMap& importBindings(); void setStatus(ModuleStatus newStatus); @@ -390,6 +406,8 @@ class ModuleObject : public NativeObject { void clearAsyncEvaluatingPostOrder(); void setCycleRoot(ModuleObject* cycleRoot); ModuleObject* getCycleRoot() const; + bool hasCyclicModuleFields() const; + bool hasSyntheticModuleFields() const; static void onTopLevelEvaluationFinished(ModuleObject* module); @@ -413,6 +431,9 @@ class ModuleObject : public NativeObject { MutableHandle<UniquePtr<ExportNameVector>> exports); static bool createEnvironment(JSContext* cx, Handle<ModuleObject*> self); + static bool createSyntheticEnvironment(JSContext* cx, + Handle<ModuleObject*> self, + Handle<GCVector<Value>> values); void initAsyncSlots(JSContext* cx, bool hasTopLevelAwait, Handle<ListObject*> asyncParentModules); @@ -423,9 +444,11 @@ class ModuleObject : public NativeObject { static void trace(JSTracer* trc, JSObject* obj); static void finalize(JS::GCContext* gcx, JSObject* obj); - bool hasCyclicModuleFields() const; CyclicModuleFields* cyclicModuleFields(); const CyclicModuleFields* cyclicModuleFields() const; + + SyntheticModuleFields* syntheticModuleFields(); + const SyntheticModuleFields* syntheticModuleFields() const; }; JSObject* GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module); diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index 62eac477ad..dde953143e 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -2885,7 +2885,8 @@ bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { } case ParseNodeKind::DotExpr: - case ParseNodeKind::OptionalDotExpr: { + case ParseNodeKind::OptionalDotExpr: + case ParseNodeKind::ArgumentsLength: { PropertyAccessBase* prop = &pn->as<PropertyAccessBase>(); MOZ_ASSERT(prop->pn_pos.encloses(prop->expression().pn_pos)); diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index 16e92b554c..1da2270cfb 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -566,15 +566,10 @@ static inline void CopyChars(CharT* to, const JSLinearString* from, MOZ_ASSERT(begin + length <= from->length()); JS::AutoCheckCannotGC nogc; - if constexpr (std::is_same_v<CharT, Latin1Char>) { - MOZ_ASSERT(from->hasLatin1Chars()); + if (from->hasLatin1Chars()) { CopyChars(to, from->latin1Chars(nogc) + begin, length); } else { - if (from->hasLatin1Chars()) { - CopyChars(to, from->latin1Chars(nogc) + begin, length); - } else { - CopyChars(to, from->twoByteChars(nogc) + begin, length); - } + CopyChars(to, from->twoByteChars(nogc) + begin, length); } } diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index f762f28f3e..498fa1746d 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1595,17 +1595,20 @@ static bool WasmLosslessInvoke(JSContext* cx, unsigned argc, Value* vp) { JS_ReportErrorASCII(cx, "not enough arguments"); return false; } - if (!args.get(0).isObject()) { + if (!args.get(0).isObject() || !args.get(0).toObject().is<JSFunction>()) { JS_ReportErrorASCII(cx, "argument is not an object"); return false; } - RootedFunction func(cx, args[0].toObject().maybeUnwrapIf<JSFunction>()); + RootedFunction func(cx, &args[0].toObject().as<JSFunction>()); if (!func || !wasm::IsWasmExportedFunction(func)) { JS_ReportErrorASCII(cx, "argument is not an exported wasm function"); return false; } + // Switch to the function's realm + AutoRealm ar(cx, func); + // Get the instance and funcIndex for calling the function wasm::Instance& instance = wasm::ExportedFunctionToInstance(func); uint32_t funcIndex = wasm::ExportedFunctionToFuncIndex(func); @@ -2042,6 +2045,95 @@ static bool WasmDisassemble(JSContext* cx, unsigned argc, Value* vp) { return false; } +static bool ToIonDumpContents(JSContext* cx, HandleValue value, + wasm::IonDumpContents* contents) { + RootedString option(cx, JS::ToString(cx, value)); + + if (!option) { + return false; + } + + bool isEqual = false; + if (!JS_StringEqualsLiteral(cx, option, "mir", &isEqual) || isEqual) { + *contents = wasm::IonDumpContents::UnoptimizedMIR; + return isEqual; + } else if (!JS_StringEqualsLiteral(cx, option, "unopt-mir", &isEqual) || + isEqual) { + *contents = wasm::IonDumpContents::UnoptimizedMIR; + return isEqual; + } else if (!JS_StringEqualsLiteral(cx, option, "opt-mir", &isEqual) || + isEqual) { + *contents = wasm::IonDumpContents::OptimizedMIR; + return isEqual; + } else if (!JS_StringEqualsLiteral(cx, option, "lir", &isEqual) || isEqual) { + *contents = wasm::IonDumpContents::LIR; + return isEqual; + } else { + return false; + } +} + +static bool WasmDumpIon(JSContext* cx, unsigned argc, Value* vp) { + if (!wasm::HasSupport(cx)) { + JS_ReportErrorASCII(cx, "wasm support unavailable"); + return false; + } + + CallArgs args = CallArgsFromVp(argc, vp); + + args.rval().set(UndefinedValue()); + + SharedMem<uint8_t*> dataPointer; + size_t byteLength; + if (!args.get(0).isObject() || !IsBufferSource(args.get(0).toObjectOrNull(), + &dataPointer, &byteLength)) { + JS_ReportErrorASCII(cx, "argument is not a buffer source"); + return false; + } + + uint32_t targetFuncIndex; + if (!ToUint32(cx, args.get(1), &targetFuncIndex)) { + JS_ReportErrorASCII(cx, "argument is not a func index"); + return false; + } + + wasm::IonDumpContents contents = wasm::IonDumpContents::Default; + if (args.length() > 2 && !ToIonDumpContents(cx, args.get(2), &contents)) { + JS_ReportErrorASCII(cx, "argument is not a valid dump contents"); + return false; + } + + wasm::MutableBytes bytecode = cx->new_<wasm::ShareableBytes>(); + if (!bytecode) { + return false; + } + if (!bytecode->append(dataPointer.unwrap(), byteLength)) { + ReportOutOfMemory(cx); + return false; + } + + UniqueChars error; + JSSprinter out(cx); + if (!out.init()) { + ReportOutOfMemory(cx); + return false; + } + + if (!wasm::DumpIonFunctionInModule(*bytecode, targetFuncIndex, contents, out, + &error)) { + if (error) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, + JSMSG_WASM_COMPILE_ERROR, error.get()); + return false; + } + ReportOutOfMemory(cx); + return false; + } + + args.rval().set(StringValue(out.release(cx))); + return true; +} + enum class Flag { Tier2Complete, Deserialized }; static bool WasmReturnFlag(JSContext* cx, unsigned argc, Value* vp, Flag flag) { @@ -2073,7 +2165,6 @@ static bool WasmReturnFlag(JSContext* cx, unsigned argc, Value* vp, Flag flag) { return true; } -#if defined(DEBUG) static bool wasmMetadataAnalysis(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); @@ -2082,10 +2173,6 @@ static bool wasmMetadataAnalysis(JSContext* cx, unsigned argc, Value* vp) { return false; } - if (!cx->options().wasmTestMetadata()) { - return false; - } - if (args[0].toObject().is<WasmModuleObject>()) { HashMap<const char*, uint32_t, mozilla::CStringHasher, SystemAllocPolicy> hashmap = args[0] @@ -2096,6 +2183,7 @@ static bool wasmMetadataAnalysis(JSContext* cx, unsigned argc, Value* vp) { .metadataAnalysis(cx); if (hashmap.empty()) { JS_ReportErrorASCII(cx, "Metadata analysis has failed"); + return false; } // metadataAnalysis returned a map of {key, value} with various statistics @@ -2107,16 +2195,21 @@ static bool wasmMetadataAnalysis(JSContext* cx, unsigned argc, Value* vp) { auto value = iter.get().value(); JSString* string = JS_NewStringCopyZ(cx, key); + if (!string) { + return false; + } + if (!props.append( IdValuePair(NameToId(string->asLinear().toPropertyName(cx)), NumberValue(value)))) { - ReportOutOfMemory(cx); return false; } } - JSObject* results = - NewPlainObjectWithUniqueNames(cx, props.begin(), props.length()); + JSObject* results = NewPlainObjectWithUniqueNames(cx, props); + if (!results) { + return false; + } args.rval().setObject(*results); return true; @@ -2127,7 +2220,6 @@ static bool wasmMetadataAnalysis(JSContext* cx, unsigned argc, Value* vp) { return false; } -#endif static bool WasmHasTier2CompilationCompleted(JSContext* cx, unsigned argc, Value* vp) { @@ -4523,7 +4615,9 @@ static bool ReadGeckoProfilingStack(JSContext* cx, unsigned argc, Value* vp) { case JS::ProfilingFrameIterator::Frame_Ion: frameKindStr = "ion"; break; - case JS::ProfilingFrameIterator::Frame_Wasm: + case JS::ProfilingFrameIterator::Frame_WasmBaseline: + case JS::ProfilingFrameIterator::Frame_WasmIon: + case JS::ProfilingFrameIterator::Frame_WasmOther: frameKindStr = "wasm"; break; default: @@ -5264,15 +5358,17 @@ class CustomSerializableObject : public NativeObject { static ActivityLog* getThreadLog() { if (!self.initialized() || !self.get()) { self.infallibleInit(); + AutoEnterOOMUnsafeRegion oomUnsafe; self.set(js_new<ActivityLog>()); - MOZ_RELEASE_ASSERT(self.get()); + if (!self.get()) { + oomUnsafe.crash("allocating activity log"); + } if (!TlsContext.get()->runtime()->atExit( [](void* vpData) { auto* log = static_cast<ActivityLog*>(vpData); js_delete(log); }, self.get())) { - AutoEnterOOMUnsafeRegion oomUnsafe; oomUnsafe.crash("atExit"); } } @@ -7199,6 +7295,8 @@ static bool CompileToStencil(JSContext* cx, uint32_t argc, Value* vp) { } CompileOptions options(cx); + options.setFile("<compileToStencil>"); + RootedString displayURL(cx); RootedString sourceMapURL(cx); UniqueChars fileNameBytes; @@ -7230,13 +7328,10 @@ static bool CompileToStencil(JSContext* cx, uint32_t argc, Value* vp) { AutoReportFrontendContext fc(cx); RefPtr<JS::Stencil> stencil; - JS::CompilationStorage compileStorage; if (isModule) { - stencil = - JS::CompileModuleScriptToStencil(&fc, options, srcBuf, compileStorage); + stencil = JS::CompileModuleScriptToStencil(&fc, options, srcBuf); } else { - stencil = - JS::CompileGlobalScriptToStencil(&fc, options, srcBuf, compileStorage); + stencil = JS::CompileGlobalScriptToStencil(&fc, options, srcBuf); } if (!stencil) { return false; @@ -7368,6 +7463,8 @@ static bool CompileToStencilXDR(JSContext* cx, uint32_t argc, Value* vp) { } CompileOptions options(cx); + options.setFile("<compileToStencilXDR>"); + RootedString displayURL(cx); RootedString sourceMapURL(cx); UniqueChars fileNameBytes; @@ -9750,6 +9847,15 @@ JS_FOR_WASM_FEATURES(WASM_FEATURE) " ImportJitExit - wasm-to-jitted-JS stubs\n" " all - all kinds, including obscure ones\n"), + JS_FN_HELP("wasmDumpIon", WasmDumpIon, 2, 0, +"wasmDumpIon(bytecode, funcIndex, [, contents])\n", +"wasmDumpIon(bytecode, funcIndex, [, contents])" +" Returns a dump of compiling a function in the specified module with Ion." +" The `contents` flag controls what is dumped. one of:" +" `mir` | `unopt-mir`: Unoptimized MIR (the default)" +" `opt-mir`: Optimized MIR" +" `lir`: LIR"), + JS_FN_HELP("wasmHasTier2CompilationCompleted", WasmHasTier2CompilationCompleted, 1, 0, "wasmHasTier2CompilationCompleted(module)", " Returns a boolean indicating whether a given module has finished compiled code for tier2. \n" @@ -9948,11 +10054,9 @@ JS_FOR_WASM_FEATURES(WASM_FEATURE) " element's edge is the node of the i+1'th array element; the destination of\n" " the last array element is implicitly |target|.\n"), -#if defined(DEBUG) JS_FN_HELP("wasmMetadataAnalysis", wasmMetadataAnalysis, 1, 0, "wasmMetadataAnalysis(wasmObject)", " Prints an analysis of the size of metadata on this wasm object.\n"), -#endif #if defined(DEBUG) || defined(JS_JITSPEW) JS_FN_HELP("dumpObject", DumpObject, 1, 0, diff --git a/js/src/builtin/intl/NumberFormat.js b/js/src/builtin/intl/NumberFormat.js index be3b74a8ac..6dc77fb639 100644 --- a/js/src/builtin/intl/NumberFormat.js +++ b/js/src/builtin/intl/NumberFormat.js @@ -190,7 +190,7 @@ function UnwrapNumberFormat(nf) { * * Applies digit options used for number formatting onto the intl object. * - * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + * ES2024 Intl draft rev a1db4567870dbe505121a4255f1210338757190a */ function SetNumberFormatDigitOptions( lazyData, @@ -216,15 +216,6 @@ function SetNumberFormatDigitOptions( lazyData.minimumIntegerDigits = mnid; // Step 7. - var roundingPriority = GetOption( - options, - "roundingPriority", - "string", - ["auto", "morePrecision", "lessPrecision"], - "auto" - ); - - // Step 8. var roundingIncrement = GetNumberOption( options, "roundingIncrement", @@ -233,7 +224,7 @@ function SetNumberFormatDigitOptions( 1 ); - // Step 9. + // Step 8. switch (roundingIncrement) { case 1: case 2: @@ -259,7 +250,7 @@ function SetNumberFormatDigitOptions( ); } - // Step 10. + // Step 9. var roundingMode = GetOption( options, "roundingMode", @@ -278,6 +269,15 @@ function SetNumberFormatDigitOptions( "halfExpand" ); + // Step 10. + var roundingPriority = GetOption( + options, + "roundingPriority", + "string", + ["auto", "morePrecision", "lessPrecision"], + "auto" + ); + // Step 11. var trailingZeroDisplay = GetOption( options, @@ -303,52 +303,52 @@ function SetNumberFormatDigitOptions( // Step 16. lazyData.trailingZeroDisplay = trailingZeroDisplay; - // Steps 17-18. + // Step 17. var hasSignificantDigits = mnsd !== undefined || mxsd !== undefined; - // Step 19-20. + // Step 28. var hasFractionDigits = mnfd !== undefined || mxfd !== undefined; - // Steps 21 and 23.a. + // Steps 19 and 21.a. var needSignificantDigits = roundingPriority !== "auto" || hasSignificantDigits; - // Steps 22 and 23.b.i. + // Steps 20 and 21.b.i. var needFractionalDigits = roundingPriority !== "auto" || !(hasSignificantDigits || (!hasFractionDigits && notation === "compact")); - // Step 24. + // Step 22. if (needSignificantDigits) { - // Step 24.a. + // Step 22.a. if (hasSignificantDigits) { - // Step 24.a.i. + // Step 22.a.i. mnsd = DefaultNumberOption(mnsd, 1, 21, 1); lazyData.minimumSignificantDigits = mnsd; - // Step 24.a.ii. + // Step 22.a.ii. mxsd = DefaultNumberOption(mxsd, mnsd, 21, 21); lazyData.maximumSignificantDigits = mxsd; } else { - // Step 24.b.i. + // Step 22.b.i. lazyData.minimumSignificantDigits = 1; - // Step 24.b.ii. + // Step 22.b.ii. lazyData.maximumSignificantDigits = 21; } } - // Step 25. + // Step 23. if (needFractionalDigits) { - // Step 25.a. + // Step 23.a. if (hasFractionDigits) { - // Step 25.a.i. + // Step 23.a.i. mnfd = DefaultNumberOption(mnfd, 0, 100, undefined); - // Step 25.a.ii. + // Step 23.a.ii. mxfd = DefaultNumberOption(mxfd, 0, 100, undefined); - // Step 25.a.iii. + // Step 23.a.iii. if (mnfd === undefined) { assert( mxfd !== undefined, @@ -357,31 +357,31 @@ function SetNumberFormatDigitOptions( mnfd = std_Math_min(mnfdDefault, mxfd); } - // Step 25.a.iv. + // Step 23.a.iv. else if (mxfd === undefined) { mxfd = std_Math_max(mxfdDefault, mnfd); } - // Step 25.a.v. + // Step 23.a.v. else if (mnfd > mxfd) { ThrowRangeError(JSMSG_INVALID_DIGITS_VALUE, mxfd); } - // Step 25.a.vi. + // Step 23.a.vi. lazyData.minimumFractionDigits = mnfd; - // Step 25.a.vii. + // Step 23.a.vii. lazyData.maximumFractionDigits = mxfd; } else { - // Step 25.b.i. + // Step 23.b.i. lazyData.minimumFractionDigits = mnfdDefault; - // Step 25.b.ii. + // Step 23.b.ii. lazyData.maximumFractionDigits = mxfdDefault; } } - // Steps 26-30. + // Steps 24-28. if (!needSignificantDigits && !needFractionalDigits) { assert(!hasSignificantDigits, "bad significant digits in fallback case"); assert( @@ -393,23 +393,23 @@ function SetNumberFormatDigitOptions( `bad notation in fallback case: ${notation}` ); - // Steps 26.a-e. + // Steps 24.a-f. lazyData.minimumFractionDigits = 0; lazyData.maximumFractionDigits = 0; lazyData.minimumSignificantDigits = 1; lazyData.maximumSignificantDigits = 2; lazyData.roundingPriority = "morePrecision"; } else { - // Steps 27-30. + // Steps 25-28. // // Our implementation stores |roundingPriority| instead of using // [[RoundingType]]. lazyData.roundingPriority = roundingPriority; } - // Step 31. + // Step 29. if (roundingIncrement !== 1) { - // Step 31.a. + // Step 29.a. // // [[RoundingType]] is `fractionDigits` if |roundingPriority| is equal to // "auto" and |hasSignificantDigits| is false. @@ -428,7 +428,7 @@ function SetNumberFormatDigitOptions( ); } - // Step 31.b. + // Step 29.b. // // Minimum and maximum fraction digits must be equal. if ( @@ -1128,7 +1128,7 @@ function Intl_NumberFormat_formatRangeToParts(start, end) { * * Returns the resolved options for a NumberFormat object. * - * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + * ES2024 Intl draft rev a1db4567870dbe505121a4255f1210338757190a */ function Intl_NumberFormat_resolvedOptions() { // Steps 1-3. @@ -1244,20 +1244,15 @@ function Intl_NumberFormat_resolvedOptions() { } DefineDataProperty(result, "signDisplay", internals.signDisplay); - DefineDataProperty(result, "roundingMode", internals.roundingMode); DefineDataProperty(result, "roundingIncrement", internals.roundingIncrement); + DefineDataProperty(result, "roundingMode", internals.roundingMode); + DefineDataProperty(result, "roundingPriority", internals.roundingPriority); DefineDataProperty( result, "trailingZeroDisplay", internals.trailingZeroDisplay ); - // Steps 6-8. - // - // Our implementation doesn't use [[RoundingType]], but instead directly - // stores the computed `roundingPriority` value. - DefineDataProperty(result, "roundingPriority", internals.roundingPriority); - - // Step 9. + // Step 6. return result; } diff --git a/js/src/builtin/intl/PluralRules.js b/js/src/builtin/intl/PluralRules.js index 1dbf6656df..260fdbd568 100644 --- a/js/src/builtin/intl/PluralRules.js +++ b/js/src/builtin/intl/PluralRules.js @@ -339,7 +339,7 @@ function Intl_PluralRules_selectRange(start, end) { * * Returns the resolved options for a PluralRules object. * - * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6 + * ES2024 Intl draft rev a1db4567870dbe505121a4255f1210338757190a */ function Intl_PluralRules_resolvedOptions() { // Step 1. @@ -359,7 +359,20 @@ function Intl_PluralRules_resolvedOptions() { var internals = getPluralRulesInternals(pluralRules); - // Steps 3-4. + // Step 4. + var internalsPluralCategories = internals.pluralCategories; + if (internalsPluralCategories === null) { + internalsPluralCategories = intl_GetPluralCategories(pluralRules); + internals.pluralCategories = internalsPluralCategories; + } + + // Step 5.b. + var pluralCategories = []; + for (var i = 0; i < internalsPluralCategories.length; i++) { + DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]); + } + + // Steps 3 and 5. var result = { locale: internals.locale, type: internals.type, @@ -406,35 +419,16 @@ function Intl_PluralRules_resolvedOptions() { ); } - DefineDataProperty(result, "roundingMode", internals.roundingMode); + DefineDataProperty(result, "pluralCategories", pluralCategories); DefineDataProperty(result, "roundingIncrement", internals.roundingIncrement); + DefineDataProperty(result, "roundingMode", internals.roundingMode); + DefineDataProperty(result, "roundingPriority", internals.roundingPriority); DefineDataProperty( result, "trailingZeroDisplay", internals.trailingZeroDisplay ); - // Step 5. - var internalsPluralCategories = internals.pluralCategories; - if (internalsPluralCategories === null) { - internalsPluralCategories = intl_GetPluralCategories(pluralRules); - internals.pluralCategories = internalsPluralCategories; - } - - var pluralCategories = []; - for (var i = 0; i < internalsPluralCategories.length; i++) { - DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]); - } - // Step 6. - DefineDataProperty(result, "pluralCategories", pluralCategories); - - // Steps 7-9. - // - // Our implementation doesn't use [[RoundingType]], but instead directly - // stores the computed `roundingPriority` value. - DefineDataProperty(result, "roundingPriority", internals.roundingPriority); - - // Step 10. return result; } diff --git a/js/src/builtin/intl/make_intl_data.py b/js/src/builtin/intl/make_intl_data.py index 7042c0a005..a8357445c4 100755 --- a/js/src/builtin/intl/make_intl_data.py +++ b/js/src/builtin/intl/make_intl_data.py @@ -2213,7 +2213,7 @@ def listIANAFiles(tzdataDir): def readIANAFiles(tzdataDir, files): """Read all IANA time zone files from the given iterable.""" - nameSyntax = "[\w/+\-]+" + nameSyntax = r"[\w/+\-]+" pZone = re.compile(r"Zone\s+(?P<name>%s)\s+.*" % nameSyntax) pLink = re.compile( r"Link\s+(?P<target>%s)\s+(?P<name>%s)(?:\s+#.*)?" % (nameSyntax, nameSyntax) @@ -2310,7 +2310,7 @@ def readICUResourceFile(filename): maybeMultiComments = r"(?:/\*[^*]*\*/)*" maybeSingleComment = r"(?://.*)?" lineStart = "^%s" % maybeMultiComments - lineEnd = "%s\s*%s$" % (maybeMultiComments, maybeSingleComment) + lineEnd = r"%s\s*%s$" % (maybeMultiComments, maybeSingleComment) return re.compile(r"\s*".join(chain([lineStart], args, [lineEnd]))) tableName = r'(?P<quote>"?)(?P<name>.+?)(?P=quote)' @@ -2554,7 +2554,7 @@ def icuTzDataVersion(icuTzDir): zoneinfo = os.path.join(icuTzDir, "zoneinfo64.txt") if not os.path.isfile(zoneinfo): raise RuntimeError("file not found: %s" % zoneinfo) - version = searchInFile("^//\s+tz version:\s+([0-9]{4}[a-z])$", zoneinfo) + version = searchInFile(r"^//\s+tz version:\s+([0-9]{4}[a-z])$", zoneinfo) if version is None: raise RuntimeError( "%s does not contain a valid tzdata version string" % zoneinfo @@ -3711,7 +3711,7 @@ const allUnits = {}; """.format( all_units_array ) - + """ + + r""" // Test only sanctioned unit identifiers are allowed. for (const typeAndUnit of allUnits) { diff --git a/js/src/builtin/temporal/PlainDate.cpp b/js/src/builtin/temporal/PlainDate.cpp index 759456c9cc..a4ad0e418f 100644 --- a/js/src/builtin/temporal/PlainDate.cpp +++ b/js/src/builtin/temporal/PlainDate.cpp @@ -2295,8 +2295,7 @@ static bool PlainDate_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 8. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } diff --git a/js/src/builtin/temporal/PlainDateTime.cpp b/js/src/builtin/temporal/PlainDateTime.cpp index 8861b484bd..8f137cfe43 100644 --- a/js/src/builtin/temporal/PlainDateTime.cpp +++ b/js/src/builtin/temporal/PlainDateTime.cpp @@ -2507,8 +2507,7 @@ static bool PlainDateTime_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 14. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } diff --git a/js/src/builtin/temporal/PlainMonthDay.cpp b/js/src/builtin/temporal/PlainMonthDay.cpp index f97b7ad68c..0896100a3f 100644 --- a/js/src/builtin/temporal/PlainMonthDay.cpp +++ b/js/src/builtin/temporal/PlainMonthDay.cpp @@ -903,8 +903,7 @@ static bool PlainMonthDay_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 8. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } diff --git a/js/src/builtin/temporal/PlainTime.cpp b/js/src/builtin/temporal/PlainTime.cpp index 9501b5853b..bf35b9d93e 100644 --- a/js/src/builtin/temporal/PlainTime.cpp +++ b/js/src/builtin/temporal/PlainTime.cpp @@ -2432,8 +2432,7 @@ static bool PlainTime_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 10. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } diff --git a/js/src/builtin/temporal/PlainYearMonth.cpp b/js/src/builtin/temporal/PlainYearMonth.cpp index a4e2f8f9e4..b95efd3179 100644 --- a/js/src/builtin/temporal/PlainYearMonth.cpp +++ b/js/src/builtin/temporal/PlainYearMonth.cpp @@ -1534,8 +1534,7 @@ static bool PlainYearMonth_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 8. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } diff --git a/js/src/builtin/temporal/ZonedDateTime.cpp b/js/src/builtin/temporal/ZonedDateTime.cpp index 690ff223b1..92842a9626 100644 --- a/js/src/builtin/temporal/ZonedDateTime.cpp +++ b/js/src/builtin/temporal/ZonedDateTime.cpp @@ -3958,8 +3958,7 @@ static bool ZonedDateTime_getISOFields(JSContext* cx, const CallArgs& args) { } // Step 22. - auto* obj = - NewPlainObjectWithUniqueNames(cx, fields.begin(), fields.length()); + auto* obj = NewPlainObjectWithUniqueNames(cx, fields); if (!obj) { return false; } |