LibJS: Do not inherit TypedArray constructors from TypedArrayConstructor

In: https://tc39.es/ecma262/#sec-%typedarray%-intrinsic-object

The spec says:
> is a constructor function object that all of the TypedArray
> constructor objects inherit from.

From what I understand from this, it effectively just means is that the
prototype for the constructor should simply be set to
TypedArrayConstructor. We _were_ doing that, but also inheriting from
it in C++.

This meant we were invoking TypedArrayConstructor::initialize for each
of the typed arrays. This is not actually what we want, since it means
that the 'of' and 'from' functions were being defined as native
properties in both the concrete typed array (e.g Uint8Array), and the
abstract TypedArray. Instead, the properties should only be defined and
inherited from the abstract TypedArray class.

Diff Tests:
    +4     -4 

Co-Authored-By: Andreas Kling <kling@serenityos.org>
This commit is contained in:
Shannon Booth 2023-12-27 11:59:32 +13:00 committed by Tim Flynn
parent 009729d5e3
commit 5d0fb4bac3
5 changed files with 28 additions and 3 deletions

View file

@ -503,7 +503,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
} \
\
ConstructorName::ConstructorName(Realm& realm, Object& prototype) \
: TypedArrayConstructor(realm.vm().names.ClassName.as_string(), prototype) \
: NativeFunction(realm.vm().names.ClassName.as_string(), prototype) \
{ \
} \
\

View file

@ -509,8 +509,8 @@ ThrowCompletionOr<double> compare_typed_array_elements(VM&, Value x, Value y, Fu
private: \
PrototypeName(Object& prototype); \
}; \
class ConstructorName final : public TypedArrayConstructor { \
JS_OBJECT(ConstructorName, TypedArrayConstructor); \
class ConstructorName final : public NativeFunction { \
JS_OBJECT(ConstructorName, NativeFunction); \
JS_DECLARE_ALLOCATOR(ConstructorName); \
\
public: \

View file

@ -27,3 +27,11 @@ test("basic functionality", () => {
expect(newTypedArray[2]).toBe(3n);
});
});
test("is inherited from TypedArray base class", () => {
TYPED_ARRAYS.forEach(T1 => {
TYPED_ARRAYS.forEach(T2 => {
expect(T1.from).toBe(T2.from);
});
});
});

View file

@ -390,3 +390,12 @@ test("source is not the same value as the receiver, and the index is invalid", (
expect(receiver[2]).toBeUndefined();
});
});
test("constructor functions are defined in the TypedArray prototype, rather than the object itself", () => {
TYPED_ARRAYS.forEach(T => {
for (property of ["of", "from"]) {
expect(T.hasOwnProperty(property)).toBe(false);
expect(Object.getPrototypeOf(T).hasOwnProperty(property)).toBe(true);
}
});
});

View file

@ -27,3 +27,11 @@ test("basic functionality", () => {
expect(newTypedArray[2]).toBe(3n);
});
});
test("is inherited from TypedArray base class", () => {
TYPED_ARRAYS.forEach(T1 => {
TYPED_ARRAYS.forEach(T2 => {
expect(T1.of).toBe(T2.of);
});
});
});