1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:28:11 +00:00

LibJS: Allocate concrete TypedArrays with a preallocated base TypedArray

TypedArray constructors/prototypes are currently allocating within their
C++ constructor when trying to access the intrinsic base TypedArray. To
prevent this, construct these objects with an already-allocated base
TypedArray.
This commit is contained in:
Timothy Flynn 2022-11-30 10:38:27 -05:00 committed by Tim Flynn
parent c0952e3670
commit 31d315001c
3 changed files with 23 additions and 8 deletions

View file

@ -259,12 +259,27 @@ void Intrinsics::initialize_intrinsics(Realm& realm)
m_object_prototype_to_string_function = &object_prototype()->get_without_side_effects(vm.names.toString).as_function(); m_object_prototype_to_string_function = &object_prototype()->get_without_side_effects(vm.names.toString).as_function();
} }
template<typename T>
constexpr inline bool IsTypedArrayConstructor = false;
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
template<> \
constexpr inline bool IsTypedArrayConstructor<ConstructorName> = true;
JS_ENUMERATE_TYPED_ARRAYS
#undef __JS_ENUMERATE
#define __JS_ENUMERATE_INNER(ClassName, snake_name, PrototypeName, ConstructorName, Namespace, snake_namespace) \ #define __JS_ENUMERATE_INNER(ClassName, snake_name, PrototypeName, ConstructorName, Namespace, snake_namespace) \
void Intrinsics::initialize_##snake_namespace##snake_name() \ void Intrinsics::initialize_##snake_namespace##snake_name() \
{ \ { \
auto& vm = this->vm(); \ auto& vm = this->vm(); \
m_##snake_namespace##snake_name##_prototype = heap().allocate<Namespace::PrototypeName>(m_realm, m_realm); \ \
m_##snake_namespace##snake_name##_constructor = heap().allocate<Namespace::ConstructorName>(m_realm, m_realm); \ if constexpr (IsTypedArrayConstructor<Namespace::ConstructorName>) { \
m_##snake_namespace##snake_name##_prototype = heap().allocate<Namespace::PrototypeName>(m_realm, *typed_array_prototype()); \
m_##snake_namespace##snake_name##_constructor = heap().allocate<Namespace::ConstructorName>(m_realm, m_realm, *typed_array_constructor()); \
} else { \
m_##snake_namespace##snake_name##_prototype = heap().allocate<Namespace::PrototypeName>(m_realm, m_realm); \
m_##snake_namespace##snake_name##_constructor = heap().allocate<Namespace::ConstructorName>(m_realm, m_realm); \
} \
\ \
/* FIXME: Add these special cases to JS_ENUMERATE_NATIVE_OBJECTS */ \ /* FIXME: Add these special cases to JS_ENUMERATE_NATIVE_OBJECTS */ \
if constexpr (IsSame<Namespace::ConstructorName, BigIntConstructor>) \ if constexpr (IsSame<Namespace::ConstructorName, BigIntConstructor>) \

View file

@ -462,8 +462,8 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
return vm().names.ClassName.as_string(); \ return vm().names.ClassName.as_string(); \
} \ } \
\ \
PrototypeName::PrototypeName(Realm& realm) \ PrototypeName::PrototypeName(Object& prototype) \
: Object(*realm.intrinsics().typed_array_prototype()) \ : Object(prototype) \
{ \ { \
} \ } \
\ \
@ -478,8 +478,8 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
define_direct_property(vm.names.BYTES_PER_ELEMENT, Value((i32)sizeof(Type)), 0); \ define_direct_property(vm.names.BYTES_PER_ELEMENT, Value((i32)sizeof(Type)), 0); \
} \ } \
\ \
ConstructorName::ConstructorName(Realm& realm) \ ConstructorName::ConstructorName(Realm& realm, Object& prototype) \
: TypedArrayConstructor(realm.vm().names.ClassName.as_string(), *realm.intrinsics().typed_array_constructor()) \ : TypedArrayConstructor(realm.vm().names.ClassName.as_string(), prototype) \
{ \ { \
} \ } \
\ \

View file

@ -484,7 +484,7 @@ ThrowCompletionOr<double> compare_typed_array_elements(VM&, Value x, Value y, Fu
virtual ~PrototypeName() override; \ virtual ~PrototypeName() override; \
\ \
private: \ private: \
PrototypeName(Realm&); \ PrototypeName(Object& prototype); \
}; \ }; \
class ConstructorName final : public TypedArrayConstructor { \ class ConstructorName final : public TypedArrayConstructor { \
JS_OBJECT(ConstructorName, TypedArrayConstructor); \ JS_OBJECT(ConstructorName, TypedArrayConstructor); \
@ -497,7 +497,7 @@ ThrowCompletionOr<double> compare_typed_array_elements(VM&, Value x, Value y, Fu
virtual ThrowCompletionOr<Object*> construct(FunctionObject& new_target) override; \ virtual ThrowCompletionOr<Object*> construct(FunctionObject& new_target) override; \
\ \
private: \ private: \
explicit ConstructorName(Realm&); \ explicit ConstructorName(Realm&, Object& prototype); \
virtual bool has_constructor() const override \ virtual bool has_constructor() const override \
{ \ { \
return true; \ return true; \