mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 15:38:10 +00:00
LibJS: Use ThrowCompletionOr in get_prototype_from_constructor()
Also add spec step comments to it while we're here.
This commit is contained in:
parent
bc1b8f9cc8
commit
2d4650714f
5 changed files with 21 additions and 19 deletions
|
@ -331,16 +331,27 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyName const&
|
|||
}
|
||||
|
||||
// 10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ), https://tc39.es/ecma262/#sec-getprototypefromconstructor
|
||||
Object* get_prototype_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)())
|
||||
ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)())
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. Assert: intrinsicDefaultProto is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object.
|
||||
|
||||
// 2. Let proto be ? Get(constructor, "prototype").
|
||||
auto prototype = constructor.get(vm.names.prototype);
|
||||
if (vm.exception())
|
||||
return nullptr;
|
||||
if (auto* exception = vm.exception())
|
||||
return throw_completion(exception->value());
|
||||
|
||||
// 3. If Type(proto) is not Object, then
|
||||
if (!prototype.is_object()) {
|
||||
auto* realm = TRY_OR_DISCARD(get_function_realm(global_object, constructor));
|
||||
// a. Let realm be ? GetFunctionRealm(constructor).
|
||||
auto* realm = TRY(get_function_realm(global_object, constructor));
|
||||
|
||||
// b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
|
||||
prototype = (realm->global_object().*intrinsic_default_prototype)();
|
||||
}
|
||||
|
||||
// 4. Return proto.
|
||||
return &prototype.as_object();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject&, Object con
|
|||
ThrowCompletionOr<Realm*> get_function_realm(GlobalObject&, FunctionObject const&);
|
||||
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
||||
bool validate_and_apply_property_descriptor(Object*, PropertyName const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
|
||||
Object* get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
|
||||
ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
|
||||
Object* create_unmapped_arguments_object(GlobalObject&, Span<Value> arguments);
|
||||
Object* create_mapped_arguments_object(GlobalObject&, FunctionObject&, Vector<FunctionNode::Parameter> const&, Span<Value> arguments, Environment&);
|
||||
Value canonical_numeric_index_string(GlobalObject&, PropertyName const&);
|
||||
|
@ -46,10 +46,7 @@ Value perform_eval(Value, GlobalObject&, CallerMode, EvalMode);
|
|||
template<typename T, typename... Args>
|
||||
T* ordinary_create_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)(), Args&&... args)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto* prototype = get_prototype_from_constructor(global_object, constructor, intrinsic_default_prototype);
|
||||
if (vm.exception())
|
||||
return nullptr;
|
||||
auto* prototype = TRY_OR_DISCARD(get_prototype_from_constructor(global_object, constructor, intrinsic_default_prototype));
|
||||
return global_object.heap().allocate<T>(global_object, forward<Args>(args)..., *prototype);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,9 +55,7 @@ Value ArrayConstructor::construct(FunctionObject& new_target)
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
auto* proto = get_prototype_from_constructor(global_object(), new_target, &GlobalObject::array_prototype);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* proto = TRY_OR_DISCARD(get_prototype_from_constructor(global_object(), new_target, &GlobalObject::array_prototype));
|
||||
|
||||
if (vm.argument_count() == 0)
|
||||
return Array::create(global_object(), 0, proto);
|
||||
|
|
|
@ -67,9 +67,7 @@ Value StringConstructor::construct(FunctionObject& new_target)
|
|||
primitive_string = vm.argument(0).to_primitive_string(global_object());
|
||||
if (!primitive_string)
|
||||
return {};
|
||||
auto* prototype = get_prototype_from_constructor(global_object(), new_target, &GlobalObject::string_prototype);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* prototype = TRY_OR_DISCARD(get_prototype_from_constructor(global_object(), new_target, &GlobalObject::string_prototype));
|
||||
return StringObject::create(global_object(), *primitive_string, *prototype);
|
||||
}
|
||||
|
||||
|
|
|
@ -270,10 +270,8 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
|
|||
#define JS_DEFINE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
||||
ClassName* ClassName::create(GlobalObject& global_object, u32 length, FunctionObject& new_target) \
|
||||
{ \
|
||||
auto& vm = global_object.vm(); \
|
||||
auto* prototype = get_prototype_from_constructor(global_object, new_target, &GlobalObject::snake_name##_prototype); \
|
||||
if (vm.exception()) \
|
||||
return {}; \
|
||||
auto* prototype = TRY_OR_DISCARD(get_prototype_from_constructor( \
|
||||
global_object, new_target, &GlobalObject::snake_name##_prototype)); \
|
||||
return global_object.heap().allocate<ClassName>(global_object, length, *prototype); \
|
||||
} \
|
||||
\
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue