diff --git a/Libraries/LibJS/Runtime/TypedArray.cpp b/Libraries/LibJS/Runtime/TypedArray.cpp index b0efdd37161..d34d4b09cb7 100644 --- a/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Libraries/LibJS/Runtime/TypedArray.cpp @@ -351,7 +351,7 @@ ThrowCompletionOr typed_array_create_same_type(VM& vm, TypedArr auto& realm = *vm.current_realm(); // 1. Let constructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 68. - auto constructor = (realm.intrinsics().*exemplar.intrinsic_constructor())(); + auto constructor = exemplar.intrinsic_constructor(realm); // 2. Let result be ? TypedArrayCreate(constructor, argumentList). auto* result = TRY(typed_array_create(vm, constructor, move(arguments))); @@ -468,9 +468,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor) } \ \ ClassName::ClassName(Object& prototype, u32 length, ArrayBuffer& array_buffer) \ - : TypedArray(prototype, \ - bit_cast(&Intrinsics::snake_name##_constructor), \ - length, array_buffer, Kind::ClassName) \ + : TypedArray(prototype, length, array_buffer, Kind::ClassName) \ { \ if constexpr (#ClassName##sv.is_one_of("BigInt64Array", "BigUint64Array")) \ m_content_type = ContentType::BigInt; \ @@ -487,6 +485,11 @@ void TypedArrayBase::visit_edges(Visitor& visitor) return vm().names.ClassName.as_string(); \ } \ \ + GC::Ref ClassName::intrinsic_constructor(Realm& realm) const \ + { \ + return realm.intrinsics().snake_name##_constructor(); \ + } \ + \ PrototypeName::PrototypeName(Object& prototype) \ : Object(ConstructWithPrototypeTag::Tag, prototype, MayInterfereWithIndexedPropertyAccess::Yes) \ { \ diff --git a/Libraries/LibJS/Runtime/TypedArray.h b/Libraries/LibJS/Runtime/TypedArray.h index 9e5d8403bd2..4473b4fb5f8 100644 --- a/Libraries/LibJS/Runtime/TypedArray.h +++ b/Libraries/LibJS/Runtime/TypedArray.h @@ -35,14 +35,11 @@ public: #undef __JS_ENUMERATE }; - using IntrinsicConstructor = GC::Ref (Intrinsics::*)(); - ByteLength const& array_length() const { return m_array_length; } ByteLength const& byte_length() const { return m_byte_length; } u32 byte_offset() const { return m_byte_offset; } ContentType content_type() const { return m_content_type; } ArrayBuffer* viewed_array_buffer() const { return m_viewed_array_buffer; } - IntrinsicConstructor intrinsic_constructor() const { return m_intrinsic_constructor; } void set_array_length(ByteLength length) { m_array_length = move(length); } void set_byte_length(ByteLength length) { m_byte_length = move(length); } @@ -65,12 +62,13 @@ public: // 25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer virtual Value get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) = 0; + virtual GC::Ref intrinsic_constructor(Realm&) const = 0; + protected: - TypedArrayBase(Object& prototype, IntrinsicConstructor intrinsic_constructor, Kind kind, u32 element_size) + TypedArrayBase(Object& prototype, Kind kind, u32 element_size) : Object(ConstructWithPrototypeTag::Tag, prototype, MayInterfereWithIndexedPropertyAccess::Yes) , m_element_size(element_size) , m_kind(kind) - , m_intrinsic_constructor(intrinsic_constructor) { set_is_typed_array(); } @@ -82,7 +80,6 @@ protected: ContentType m_content_type { ContentType::Number }; Kind m_kind {}; GC::Ptr m_viewed_array_buffer; - IntrinsicConstructor m_intrinsic_constructor { nullptr }; private: virtual void visit_edges(Visitor&) override; @@ -498,8 +495,8 @@ public: Value get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) override { return viewed_array_buffer()->template get_modify_set_value(byte_index, value, move(operation), is_little_endian); } protected: - TypedArray(Object& prototype, IntrinsicConstructor intrinsic_constructor, u32 array_length, ArrayBuffer& array_buffer, Kind kind) - : TypedArrayBase(prototype, intrinsic_constructor, kind, sizeof(UnderlyingBufferDataType)) + TypedArray(Object& prototype, u32 array_length, ArrayBuffer& array_buffer, Kind kind) + : TypedArrayBase(prototype, kind, sizeof(UnderlyingBufferDataType)) { VERIFY(!Checked::multiplication_would_overflow(array_length, sizeof(UnderlyingBufferDataType))); m_viewed_array_buffer = &array_buffer; @@ -527,6 +524,7 @@ ThrowCompletionOr compare_typed_array_elements(VM&, Value x, Value y, Fu static ThrowCompletionOr> create(Realm&, u32 length); \ static GC::Ref create(Realm&, u32 length, ArrayBuffer& buffer); \ virtual FlyString const& element_name() const override; \ + virtual GC::Ref intrinsic_constructor(Realm&) const override; \ \ protected: \ ClassName(Object& prototype, u32 length, ArrayBuffer& array_buffer); \ diff --git a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index aced9071065..550351fcebc 100644 --- a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -97,7 +97,7 @@ static ThrowCompletionOr typed_array_species_create(VM& vm, Typ auto& realm = *vm.current_realm(); // 1. Let defaultConstructor be the intrinsic object listed in column one of Table 72 for exemplar.[[TypedArrayName]]. - auto default_constructor = (realm.intrinsics().*exemplar.intrinsic_constructor())(); + auto default_constructor = exemplar.intrinsic_constructor(realm); // 2. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor). auto* constructor = TRY(species_constructor(vm, exemplar, *default_constructor));