mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 20:33:10 +00:00
LibJS: Return non-object argument unaltered from Object.setPrototypeOf()
This was missing step 3 from the spec: 3. If Type(O) is not Object, return O. Also use RequireObjectCoercible() for a better error message and make the rest of the code a bit easier to read and more similar to the spec text.
This commit is contained in:
parent
1f8b6ac3c3
commit
8a06a93ce2
|
@ -110,25 +110,25 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
|
|||
// 20.1.2.21 Object.setPrototypeOf ( O, proto ), https://tc39.es/ecma262/#sec-object.setprototypeof
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
||||
{
|
||||
auto* object = vm.argument(0).to_object(global_object);
|
||||
auto argument = require_object_coercible(global_object, vm.argument(0));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto prototype_value = vm.argument(1);
|
||||
Object* prototype;
|
||||
if (prototype_value.is_null()) {
|
||||
prototype = nullptr;
|
||||
} else if (prototype_value.is_object()) {
|
||||
prototype = &prototype_value.as_object();
|
||||
} else {
|
||||
if (!prototype_value.is_object() && !prototype_value.is_null()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
|
||||
return {};
|
||||
}
|
||||
if (!object->set_prototype(prototype)) {
|
||||
if (!vm.exception())
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||
if (!argument.is_object())
|
||||
return argument;
|
||||
auto* prototype = prototype_value.is_null() ? nullptr : &prototype_value.as_object();
|
||||
auto status = argument.as_object().set_prototype(prototype);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!status) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse);
|
||||
return {};
|
||||
}
|
||||
return object;
|
||||
return argument;
|
||||
}
|
||||
|
||||
// 20.1.2.14 Object.isExtensible ( O ), https://tc39.es/ecma262/#sec-object.isextensible
|
||||
|
|
|
@ -9,6 +9,13 @@ describe("correct behavior", () => {
|
|||
expect(Object.setPrototypeOf(o, p)).toBe(o);
|
||||
expect(Object.getPrototypeOf(o)).toBe(p);
|
||||
});
|
||||
|
||||
test("non-object argument is returned without being coerced to object", () => {
|
||||
let o = 42;
|
||||
let p = {};
|
||||
expect(Object.setPrototypeOf(o, p)).toBe(o);
|
||||
expect(Object.getPrototypeOf(o)).toBe(Number.prototype);
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
|
|
Loading…
Reference in a new issue