mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 10:22:45 +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
	
	 Linus Groh
						Linus Groh