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

LibJS: Convert to_object() to ThrowCompletionOr

This commit is contained in:
Linus Groh 2021-10-12 19:24:57 +01:00
parent 9eb065a1f6
commit 52976bfac6
45 changed files with 239 additions and 490 deletions

View file

@ -974,9 +974,10 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
} else if (is_wrappable_type(parameter.type)) { } else if (is_wrappable_type(parameter.type)) {
if (!parameter.type.nullable) { if (!parameter.type.nullable) {
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
auto @cpp_name@_object = @js_name@@js_suffix@.to_object(global_object); auto @cpp_name@_object_or_error = @js_name@@js_suffix@.to_object(global_object);
if (vm.exception()) if (@cpp_name@_object_or_error.is_error())
@return_statement@ @return_statement@
auto @cpp_name@_object = @cpp_name@_object_or_error.release_value();
if (!is<@wrapper_name@>(@cpp_name@_object)) { if (!is<@wrapper_name@>(@cpp_name@_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
@ -989,9 +990,10 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
scoped_generator.append(R"~~~( scoped_generator.append(R"~~~(
@parameter.type.name@* @cpp_name@ = nullptr; @parameter.type.name@* @cpp_name@ = nullptr;
if (!@js_name@@js_suffix@.is_nullish()) { if (!@js_name@@js_suffix@.is_nullish()) {
auto @cpp_name@_object = @js_name@@js_suffix@.to_object(global_object); auto @cpp_name@_object_or_error = @js_name@@js_suffix@.to_object(global_object);
if (vm.exception()) if (@cpp_name@_object_or_error.is_error())
@return_statement@ @return_statement@
auto @cpp_name@_object = @cpp_name@_object_or_error.release_value();
if (!is<@wrapper_name@>(@cpp_name@_object)) { if (!is<@wrapper_name@>(@cpp_name@_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@parameter.type.name@");
@ -3030,9 +3032,7 @@ void @prototype_class@::initialize(JS::GlobalObject& global_object)
generator.append(R"~~~( generator.append(R"~~~(
static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_object) static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
)~~~"); )~~~");
if (interface.name == "EventTarget") { if (interface.name == "EventTarget") {
@ -3528,9 +3528,7 @@ void @prototype_class@::initialize(JS::GlobalObject& global_object)
static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_object) static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!is<@wrapper_class@>(this_object)) { if (!is<@wrapper_class@>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "@fully_qualified_name@");
return nullptr; return nullptr;

View file

@ -32,9 +32,7 @@ TESTJS_GLOBAL_FUNCTION(run_queued_promise_jobs, runQueuedPromiseJobs)
TESTJS_GLOBAL_FUNCTION(get_weak_set_size, getWeakSetSize) TESTJS_GLOBAL_FUNCTION(get_weak_set_size, getWeakSetSize)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (!object)
return {};
if (!is<JS::WeakSet>(object)) { if (!is<JS::WeakSet>(object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakSet"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakSet");
return {}; return {};
@ -45,9 +43,7 @@ TESTJS_GLOBAL_FUNCTION(get_weak_set_size, getWeakSetSize)
TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize) TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (!object)
return {};
if (!is<JS::WeakMap>(object)) { if (!is<JS::WeakMap>(object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakMap"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WeakMap");
return {}; return {};

View file

@ -93,9 +93,7 @@ HashMap<Wasm::Linker::Name, Wasm::ExternValue> WebAssemblyModule::s_spec_test_na
TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule) TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
{ {
auto object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
if (!is<JS::Uint8Array>(object)) { if (!is<JS::Uint8Array>(object)) {
vm.throw_exception<JS::TypeError>(global_object, "Expected a Uint8Array argument to parse_webassembly_module"); vm.throw_exception<JS::TypeError>(global_object, "Expected a Uint8Array argument to parse_webassembly_module");
return {}; return {};
@ -139,17 +137,13 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays) TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays)
{ {
auto lhs = vm.argument(0).to_object(global_object); auto* lhs = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
if (!is<JS::TypedArrayBase>(lhs)) { if (!is<JS::TypedArrayBase>(lhs)) {
vm.throw_exception<JS::TypeError>(global_object, "Expected a TypedArray"); vm.throw_exception<JS::TypeError>(global_object, "Expected a TypedArray");
return {}; return {};
} }
auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs); auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs);
auto rhs = vm.argument(1).to_object(global_object); auto* rhs = TRY_OR_DISCARD(vm.argument(1).to_object(global_object));
if (vm.exception())
return {};
if (!is<JS::TypedArrayBase>(rhs)) { if (!is<JS::TypedArrayBase>(rhs)) {
vm.throw_exception<JS::TypeError>(global_object, "Expected a TypedArray"); vm.throw_exception<JS::TypeError>(global_object, "Expected a TypedArray");
return {}; return {};
@ -169,10 +163,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
{ {
auto name = TRY_OR_DISCARD(vm.argument(0).to_string(global_object)); auto name = TRY_OR_DISCARD(vm.argument(0).to_string(global_object));
auto this_value = vm.this_value(global_object); auto this_value = vm.this_value(global_object);
auto object = this_value.to_object(global_object); auto* object = TRY_OR_DISCARD(this_value.to_object(global_object));
if (vm.exception()) if (!is<WebAssemblyModule>(object)) {
return {};
if (!object || !is<WebAssemblyModule>(object)) {
vm.throw_exception<JS::TypeError>(global_object, "Not a WebAssemblyModule"); vm.throw_exception<JS::TypeError>(global_object, "Not a WebAssemblyModule");
return {}; return {};
} }

View file

@ -171,9 +171,7 @@ void SheetGlobalObject::visit_edges(Visitor& visitor)
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -210,9 +208,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -251,9 +247,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -289,9 +283,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
return {}; return {};
} }
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -327,9 +319,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
auto& column_name_str = column_name.as_string().string(); auto& column_name_str = column_name.as_string().string();
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -368,9 +358,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
auto offset_number = offset.as_i32(); auto offset_number = offset.as_i32();
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<SheetGlobalObject>(this_object)) { if (!is<SheetGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
@ -423,9 +411,7 @@ JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
return {}; return {};
} }
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!is<WorkbookObject>(this_object)) { if (!is<WorkbookObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WorkbookObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WorkbookObject");

View file

@ -438,9 +438,7 @@ Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_obje
return {}; return {};
// 2. Let obj be ? ToObject(? GetValue(value)). // 2. Let obj be ? ToObject(? GetValue(value)).
auto* object = value.to_object(global_object); auto* object = TRY_OR_DISCARD(value.to_object(global_object));
if (interpreter.exception())
return {};
// 3. Let oldEnv be the running execution context's LexicalEnvironment. // 3. Let oldEnv be the running execution context's LexicalEnvironment.
auto* old_environment = interpreter.vm().running_execution_context().lexical_environment; auto* old_environment = interpreter.vm().running_execution_context().lexical_environment;
@ -819,8 +817,7 @@ Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
if (rhs_result.is_nullish()) if (rhs_result.is_nullish())
return js_undefined(); return js_undefined();
auto* object = rhs_result.to_object(global_object); auto* object = MUST(rhs_result.to_object(global_object));
VERIFY(object);
// 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset // 14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] ), https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
Environment* old_environment = interpreter.lexical_environment(); Environment* old_environment = interpreter.lexical_environment();

View file

@ -129,9 +129,10 @@ void IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& global_object = interpreter.global_object(); auto& global_object = interpreter.global_object();
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto iterator = interpreter.accumulator().to_object(global_object); auto iterator_or_error = interpreter.accumulator().to_object(global_object);
if (vm.exception()) if (iterator_or_error.is_error())
return; return;
auto* iterator = iterator_or_error.release_value();
auto array = Array::create(global_object, 0); auto array = Array::create(global_object, 0);
size_t index = 0; size_t index = 0;
@ -179,9 +180,10 @@ void NewRegExp::execute_impl(Bytecode::Interpreter& interpreter) const
void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpreter) const void CopyObjectExcludingProperties::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto* from_object = interpreter.reg(m_from_object).to_object(interpreter.global_object()); auto from_object_or_error = interpreter.reg(m_from_object).to_object(interpreter.global_object());
if (interpreter.vm().exception()) if (from_object_or_error.is_error())
return; return;
auto* from_object = from_object_or_error.release_value();
auto* to_object = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype()); auto* to_object = Object::create(interpreter.global_object(), interpreter.global_object().object_prototype());
@ -238,18 +240,23 @@ void SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const
void GetById::execute_impl(Bytecode::Interpreter& interpreter) const void GetById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.accumulator().to_object(interpreter.global_object())) { auto object_or_error = interpreter.accumulator().to_object(interpreter.global_object());
auto value_or_error = object->get(interpreter.current_executable().get_string(m_property)); if (object_or_error.is_error())
if (value_or_error.is_error()) return;
return; auto* object = object_or_error.release_value();
interpreter.accumulator() = value_or_error.release_value(); auto value_or_error = object->get(interpreter.current_executable().get_string(m_property));
} if (value_or_error.is_error())
return;
interpreter.accumulator() = value_or_error.release_value();
} }
void PutById::execute_impl(Bytecode::Interpreter& interpreter) const void PutById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object());
MUST(object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes)); if (object_or_error.is_error())
return;
auto* object = object_or_error.release_value();
MUST(object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes));
} }
void Jump::execute_impl(Bytecode::Interpreter& interpreter) const void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
@ -430,25 +437,29 @@ void Yield::replace_references_impl(BasicBlock const& from, BasicBlock const& to
void GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const void GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) { auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object());
auto property_key = interpreter.accumulator().to_property_key(interpreter.global_object()); if (object_or_error.is_error())
if (interpreter.vm().exception()) return;
return; auto* object = object_or_error.release_value();
auto value_or_error = object->get(property_key); auto property_key = interpreter.accumulator().to_property_key(interpreter.global_object());
if (value_or_error.is_error()) if (interpreter.vm().exception())
return; return;
interpreter.accumulator() = value_or_error.release_value(); auto value_or_error = object->get(property_key);
} if (value_or_error.is_error())
return;
interpreter.accumulator() = value_or_error.release_value();
} }
void PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const void PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) { auto object_or_error = interpreter.reg(m_base).to_object(interpreter.global_object());
auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object()); if (object_or_error.is_error())
if (interpreter.vm().exception()) return;
return; auto* object = object_or_error.release_value();
MUST(object->set(property_key, interpreter.accumulator(), Object::ShouldThrowExceptions::Yes)); auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object());
} if (interpreter.vm().exception())
return;
MUST(object->set(property_key, interpreter.accumulator(), Object::ShouldThrowExceptions::Yes));
} }
void GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const void GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const
@ -458,20 +469,29 @@ void GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const
void IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const void IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.accumulator().to_object(interpreter.global_object())) auto object_or_error = interpreter.accumulator().to_object(interpreter.global_object());
interpreter.accumulator() = iterator_next(*object); if (object_or_error.is_error())
return;
auto* object = object_or_error.release_value();
interpreter.accumulator() = iterator_next(*object);
} }
void IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const void IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* iterator_result = interpreter.accumulator().to_object(interpreter.global_object())) auto iterator_result_or_error = interpreter.accumulator().to_object(interpreter.global_object());
interpreter.accumulator() = Value(iterator_complete(interpreter.global_object(), *iterator_result)); if (iterator_result_or_error.is_error())
return;
auto* iterator_result = iterator_result_or_error.release_value();
interpreter.accumulator() = Value(iterator_complete(interpreter.global_object(), *iterator_result));
} }
void IteratorResultValue::execute_impl(Bytecode::Interpreter& interpreter) const void IteratorResultValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* iterator_result = interpreter.accumulator().to_object(interpreter.global_object())) auto iterator_result_or_error = interpreter.accumulator().to_object(interpreter.global_object());
interpreter.accumulator() = iterator_value(interpreter.global_object(), *iterator_result); if (iterator_result_or_error.is_error())
return;
auto* iterator_result = iterator_result_or_error.release_value();
interpreter.accumulator() = iterator_value(interpreter.global_object(), *iterator_result);
} }
void NewClass::execute_impl(Bytecode::Interpreter&) const void NewClass::execute_impl(Bytecode::Interpreter&) const

View file

@ -165,7 +165,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
} }
} }
auto* array_like = items.to_object(global_object); auto* array_like = MUST(items.to_object(global_object));
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *array_like)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *array_like));

View file

@ -160,9 +160,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -224,9 +222,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::for_each)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -271,9 +267,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -320,9 +314,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
// 23.1.3.20 Array.prototype.push ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.push // 23.1.3.20 Array.prototype.push ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.push
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
auto argument_count = vm.argument_count(); auto argument_count = vm.argument_count();
auto new_length = length + argument_count; auto new_length = length + argument_count;
@ -340,9 +332,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
// 23.1.3.31 Array.prototype.unshift ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.unshift // 23.1.3.31 Array.prototype.unshift ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.unshift
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
auto arg_count = vm.argument_count(); auto arg_count = vm.argument_count();
size_t new_length = length + arg_count; size_t new_length = length + arg_count;
@ -376,9 +366,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
// 23.1.3.19 Array.prototype.pop ( ), https://tc39.es/ecma262/#sec-array.prototype.pop // 23.1.3.19 Array.prototype.pop ( ), https://tc39.es/ecma262/#sec-array.prototype.pop
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
if (length == 0) { if (length == 0) {
TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes)); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
@ -394,9 +382,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
// 23.1.3.24 Array.prototype.shift ( ), https://tc39.es/ecma262/#sec-array.prototype.shift // 23.1.3.24 Array.prototype.shift ( ), https://tc39.es/ecma262/#sec-array.prototype.shift
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
if (length == 0) { if (length == 0) {
TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes)); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
@ -423,9 +409,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
// 23.1.3.30 Array.prototype.toString ( ), https://tc39.es/ecma262/#sec-array.prototype.tostring // 23.1.3.30 Array.prototype.toString ( ), https://tc39.es/ecma262/#sec-array.prototype.tostring
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto join_function = TRY_OR_DISCARD(this_object->get(vm.names.join)); auto join_function = TRY_OR_DISCARD(this_object->get(vm.names.join));
if (!join_function.is_function()) if (!join_function.is_function())
return ObjectPrototype::to_string(vm, global_object); return ObjectPrototype::to_string(vm, global_object);
@ -435,9 +419,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
// 23.1.3.29 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-array.prototype.tolocalestring // 23.1.3.29 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-array.prototype.tolocalestring
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (s_array_join_seen_objects.contains(this_object)) if (s_array_join_seen_objects.contains(this_object))
return js_string(vm, ""); return js_string(vm, "");
@ -466,9 +448,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
// 23.1.3.15 Array.prototype.join ( separator ), https://tc39.es/ecma262/#sec-array.prototype.join // 23.1.3.15 Array.prototype.join ( separator ), https://tc39.es/ecma262/#sec-array.prototype.join
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
// This is not part of the spec, but all major engines do some kind of circular reference checks. // This is not part of the spec, but all major engines do some kind of circular reference checks.
// FWIW: engine262, a "100% spec compliant" ECMA-262 impl, aborts with "too much recursion". // FWIW: engine262, a "100% spec compliant" ECMA-262 impl, aborts with "too much recursion".
@ -501,9 +481,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
// 23.1.3.1 Array.prototype.concat ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.concat // 23.1.3.1 Array.prototype.concat ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.concat
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto* new_array = array_species_create(global_object, *this_object, 0); auto* new_array = array_species_create(global_object, *this_object, 0);
if (vm.exception()) if (vm.exception())
@ -513,14 +491,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
// 23.1.3.1.1 IsConcatSpreadable ( O ), https://tc39.es/ecma262/#sec-isconcatspreadable // 23.1.3.1.1 IsConcatSpreadable ( O ), https://tc39.es/ecma262/#sec-isconcatspreadable
auto is_concat_spreadable = [&vm, &global_object](Value const& val) -> bool { auto is_concat_spreadable = [&vm, &global_object](Value const& val) -> bool {
if (!val.is_object()) { if (!val.is_object())
return false; return false;
} auto& object = val.as_object();
auto* object = val.to_object(global_object); auto spreadable = TRY_OR_DISCARD(object.get(*vm.well_known_symbol_is_concat_spreadable()));
if (vm.exception())
return false;
auto spreadable = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_is_concat_spreadable()));
if (!spreadable.is_undefined()) if (!spreadable.is_undefined())
return spreadable.to_boolean(); return spreadable.to_boolean();
@ -591,9 +565,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
// 23.1.3.25 Array.prototype.slice ( start, end ), https://tc39.es/ecma262/#sec-array.prototype.slice // 23.1.3.25 Array.prototype.slice ( start, end ), https://tc39.es/ecma262/#sec-array.prototype.slice
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto initial_length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto initial_length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
@ -660,9 +632,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
auto from_index = vm.argument(1); auto from_index = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -736,9 +706,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
auto initial_value = vm.argument(1); auto initial_value = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -826,9 +794,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
auto initial_value = vm.argument(1); auto initial_value = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -912,9 +878,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
// 23.1.3.23 Array.prototype.reverse ( ), https://tc39.es/ecma262/#sec-array.prototype.reverse // 23.1.3.23 Array.prototype.reverse ( ), https://tc39.es/ecma262/#sec-array.prototype.reverse
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
auto middle = length / 2; auto middle = length / 2;
@ -1067,9 +1031,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
return {}; return {};
} }
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1111,9 +1073,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
auto from_index = vm.argument(1); auto from_index = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1180,9 +1140,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
// 23.1.3.13 Array.prototype.includes ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-array.prototype.includes // 23.1.3.13 Array.prototype.includes ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-array.prototype.includes
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
if (length == 0) if (length == 0)
return Value(false); return Value(false);
@ -1218,9 +1176,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1261,9 +1217,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1304,9 +1258,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1347,9 +1299,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1390,9 +1340,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1439,9 +1387,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1484,9 +1430,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
// 23.1.3.28 Array.prototype.splice ( start, deleteCount, ...items ), https://tc39.es/ecma262#sec-array.prototype.splice // 23.1.3.28 Array.prototype.splice ( start, deleteCount, ...items ), https://tc39.es/ecma262#sec-array.prototype.splice
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto initial_length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto initial_length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
@ -1586,9 +1530,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
// 23.1.3.6 Array.prototype.fill ( value [ , start [ , end ] ] ), https://tc39.es/ecma262/#sec-array.prototype.fill // 23.1.3.6 Array.prototype.fill ( value [ , start [ , end ] ] ), https://tc39.es/ecma262/#sec-array.prototype.fill
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
@ -1633,9 +1575,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
// 23.1.3.32 Array.prototype.values ( ), https://tc39.es/ecma262/#sec-array.prototype.values // 23.1.3.32 Array.prototype.values ( ), https://tc39.es/ecma262/#sec-array.prototype.values
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Value); return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Value);
} }
@ -1643,9 +1583,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
// 23.1.3.16 Array.prototype.entries ( ), https://tc39.es/ecma262/#sec-array.prototype.entries // 23.1.3.16 Array.prototype.entries ( ), https://tc39.es/ecma262/#sec-array.prototype.entries
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::KeyAndValue); return ArrayIterator::create(global_object, this_object, Object::PropertyKind::KeyAndValue);
} }
@ -1653,9 +1591,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries)
// 23.1.3.16 Array.prototype.keys ( ), https://tc39.es/ecma262/#sec-array.prototype.keys // 23.1.3.16 Array.prototype.keys ( ), https://tc39.es/ecma262/#sec-array.prototype.keys
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Key); return ArrayIterator::create(global_object, this_object, Object::PropertyKind::Key);
} }
@ -1704,9 +1640,7 @@ static size_t flatten_into_array(GlobalObject& global_object, Object& new_array,
// 23.1.3.10 Array.prototype.flat ( [ depth ] ), https://tc39.es/ecma262/#sec-array.prototype.flat // 23.1.3.10 Array.prototype.flat ( [ depth ] ), https://tc39.es/ecma262/#sec-array.prototype.flat
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
@ -1735,9 +1669,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
auto this_arg = vm.argument(1); auto this_arg = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
// 2. Let sourceLen be ? LengthOfArrayLike(O). // 2. Let sourceLen be ? LengthOfArrayLike(O).
auto source_length = TRY_OR_DISCARD(length_of_array_like(global_object, *object)); auto source_length = TRY_OR_DISCARD(length_of_array_like(global_object, *object));
@ -1765,9 +1697,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
// 23.1.3.3 Array.prototype.copyWithin ( target, start [ , end ] ), https://tc39.es/ecma262/#sec-array.prototype.copywithin // 23.1.3.3 Array.prototype.copyWithin ( target, start [ , end ] ), https://tc39.es/ecma262/#sec-array.prototype.copywithin
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
auto relative_target = vm.argument(0).to_integer_or_infinity(global_object); auto relative_target = vm.argument(0).to_integer_or_infinity(global_object);
@ -1839,9 +1769,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
// 1.1 Array.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-array.prototype.at // 1.1 Array.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-array.prototype.at
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
auto relative_index = vm.argument(0).to_integer_or_infinity(global_object); auto relative_index = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception()) if (vm.exception())

View file

@ -644,7 +644,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
// b. Else, // b. Else,
else { else {
// i. Let thisValue be ! ToObject(thisArgument). // i. Let thisValue be ! ToObject(thisArgument).
this_value = this_argument.to_object(global_object()); this_value = MUST(this_argument.to_object(global_object()));
// ii. NOTE: ToObject produces wrapper objects using calleeRealm. // ii. NOTE: ToObject produces wrapper objects using calleeRealm.
// FIXME: It currently doesn't, as we pass the function's global object. // FIXME: It currently doesn't, as we pass the function's global object.

View file

@ -25,7 +25,7 @@ BoundFunction* FunctionObject::bind(Value bound_this_value, Vector<Value> argume
auto& vm = this->vm(); auto& vm = this->vm();
FunctionObject& target_function = is<BoundFunction>(*this) ? static_cast<BoundFunction&>(*this).bound_target_function() : *this; FunctionObject& target_function = is<BoundFunction>(*this) ? static_cast<BoundFunction&>(*this).bound_target_function() : *this;
auto bound_this_object = [&vm, bound_this_value, this]() -> Value { auto get_bound_this_object = [&vm, bound_this_value, this]() -> ThrowCompletionOr<Value> {
if (is<BoundFunction>(*this) && !static_cast<BoundFunction&>(*this).bound_this().is_empty()) if (is<BoundFunction>(*this) && !static_cast<BoundFunction&>(*this).bound_this().is_empty())
return static_cast<BoundFunction&>(*this).bound_this(); return static_cast<BoundFunction&>(*this).bound_this();
switch (bound_this_value.type()) { switch (bound_this_value.type()) {
@ -33,11 +33,12 @@ BoundFunction* FunctionObject::bind(Value bound_this_value, Vector<Value> argume
case Value::Type::Null: case Value::Type::Null:
if (vm.in_strict_mode()) if (vm.in_strict_mode())
return bound_this_value; return bound_this_value;
return &global_object(); return { &global_object() };
default: default:
return bound_this_value.to_object(global_object()); return { TRY(bound_this_value.to_object(global_object())) };
} }
}(); };
auto bound_this_object = TRY_OR_DISCARD(get_bound_this_object());
i32 computed_length = 0; i32 computed_length = 0;
auto length_property = TRY_OR_DISCARD(get(vm.names.length)); auto length_property = TRY_OR_DISCARD(get(vm.names.length));

View file

@ -45,9 +45,7 @@ FunctionPrototype::~FunctionPrototype()
// 20.2.3.1 Function.prototype.apply ( thisArg, argArray ), https://tc39.es/ecma262/#sec-function.prototype.apply // 20.2.3.1 Function.prototype.apply ( thisArg, argArray ), https://tc39.es/ecma262/#sec-function.prototype.apply
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply) JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!this_object->is_function()) { if (!this_object->is_function()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function"); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function");
return {}; return {};
@ -64,9 +62,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
// 20.2.3.2 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.bind // 20.2.3.2 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.bind
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind) JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!this_object->is_function()) { if (!this_object->is_function()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function"); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function");
return {}; return {};
@ -86,9 +82,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
// 20.2.3.3 Function.prototype.call ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.call // 20.2.3.3 Function.prototype.call ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.call
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call) JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!this_object->is_function()) { if (!this_object->is_function()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function"); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function");
return {}; return {};
@ -106,9 +100,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
// 20.2.3.5 Function.prototype.toString ( ), https://tc39.es/ecma262/#sec-function.prototype.tostring // 20.2.3.5 Function.prototype.toString ( ), https://tc39.es/ecma262/#sec-function.prototype.tostring
JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string) JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
if (!this_object->is_function()) { if (!this_object->is_function()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function"); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Function");
return {}; return {};

View file

@ -17,10 +17,7 @@ GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value init
{ {
// This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) // This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png)
auto generating_function_prototype = TRY_OR_DISCARD(generating_function->get(global_object.vm().names.prototype)); auto generating_function_prototype = TRY_OR_DISCARD(generating_function->get(global_object.vm().names.prototype));
auto* generating_function_prototype_object = generating_function_prototype.to_object(global_object); auto* generating_function_prototype_object = TRY_OR_DISCARD(generating_function_prototype.to_object(global_object));
if (!generating_function_prototype_object)
return {};
auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_prototype_object); auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_prototype_object);
object->m_generating_function = generating_function; object->m_generating_function = generating_function;
object->m_environment = generating_scope; object->m_environment = generating_scope;

View file

@ -208,9 +208,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_
// 4. Else, // 4. Else,
else { else {
// a. Let O be ? ToObject(locales). // a. Let O be ? ToObject(locales).
object = locales.to_object(global_object); object = TRY(locales.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
} }
// 5. Let len be ? ToLength(? Get(O, "length")). // 5. Let len be ? ToLength(? Get(O, "length")).
@ -589,8 +587,6 @@ ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<
// 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject // 9.2.12 CoerceOptionsToObject ( options ), https://tc39.es/ecma402/#sec-coerceoptionstoobject
ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options) ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object, Value options)
{ {
auto& vm = global_object.vm();
// 1. If options is undefined, then // 1. If options is undefined, then
if (options.is_undefined()) { if (options.is_undefined()) {
// a. Return ! OrdinaryObjectCreate(null). // a. Return ! OrdinaryObjectCreate(null).
@ -598,10 +594,7 @@ ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object,
} }
// 2. Return ? ToObject(options). // 2. Return ? ToObject(options).
auto result = options.to_object(global_object); return TRY(options.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
return result;
} }
// 9.2.13 GetOption ( options, property, type, values, fallback ), https://tc39.es/ecma402/#sec-getoption // 9.2.13 GetOption ( options, property, type, values, fallback ), https://tc39.es/ecma402/#sec-getoption

View file

@ -18,9 +18,7 @@ Object* get_iterator(GlobalObject& global_object, Value value, IteratorHint hint
if (method.is_empty()) { if (method.is_empty()) {
if (hint == IteratorHint::Async) if (hint == IteratorHint::Async)
TODO(); TODO();
auto object = value.to_object(global_object); auto object = TRY_OR_DISCARD(value.to_object(global_object));
if (!object)
return {};
method = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_iterator())); method = TRY_OR_DISCARD(object->get(*vm.well_known_symbol_iterator()));
} }
if (!method.is_function()) { if (!method.is_function()) {

View file

@ -30,9 +30,7 @@ IteratorPrototype::~IteratorPrototype()
// 27.1.2.1 %IteratorPrototype% [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator // 27.1.2.1 %IteratorPrototype% [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator
JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::symbol_iterator) JS_DEFINE_NATIVE_FUNCTION(IteratorPrototype::symbol_iterator)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
return this_object; return this_object;
} }

View file

@ -137,9 +137,7 @@ String JSONObject::serialize_json_property(GlobalObject& global_object, Stringif
auto& vm = global_object.vm(); auto& vm = global_object.vm();
auto value = TRY_OR_DISCARD(holder->get(key)); auto value = TRY_OR_DISCARD(holder->get(key));
if (value.is_object() || value.is_bigint()) { if (value.is_object() || value.is_bigint()) {
auto* value_object = value.to_object(global_object); auto* value_object = TRY_OR_DISCARD(value.to_object(global_object));
if (vm.exception())
return {};
auto to_json = TRY_OR_DISCARD(value_object->get(vm.names.toJSON)); auto to_json = TRY_OR_DISCARD(value_object->get(vm.names.toJSON));
if (to_json.is_function()) if (to_json.is_function())
value = TRY_OR_DISCARD(vm.call(to_json.as_function(), value, js_string(vm, key.to_string()))); value = TRY_OR_DISCARD(vm.call(to_json.as_function(), value, js_string(vm, key.to_string())));

View file

@ -449,8 +449,7 @@ ThrowCompletionOr<Object*> Object::copy_data_properties(Value source, HashTable<
if (source.is_nullish()) if (source.is_nullish())
return this; return this;
auto* from_object = source.to_object(global_object); auto* from_object = MUST(source.to_object(global_object));
VERIFY(from_object);
for (auto& next_key_value : TRY(from_object->internal_own_property_keys())) { for (auto& next_key_value : TRY(from_object->internal_own_property_keys())) {
auto next_key = PropertyName::from_value(global_object, next_key_value); auto next_key = PropertyName::from_value(global_object, next_key_value);
@ -1035,15 +1034,12 @@ void Object::define_native_function(PropertyName const& property_name, Function<
// 20.1.2.3.1 ObjectDefineProperties ( O, Properties ), https://tc39.es/ecma262/#sec-objectdefineproperties // 20.1.2.3.1 ObjectDefineProperties ( O, Properties ), https://tc39.es/ecma262/#sec-objectdefineproperties
ThrowCompletionOr<Object*> Object::define_properties(Value properties) ThrowCompletionOr<Object*> Object::define_properties(Value properties)
{ {
auto& vm = this->vm();
auto& global_object = this->global_object(); auto& global_object = this->global_object();
// 1. Assert: Type(O) is Object. // 1. Assert: Type(O) is Object.
// 2. Let props be ? ToObject(Properties). // 2. Let props be ? ToObject(Properties).
auto* props = properties.to_object(global_object); auto* props = TRY(properties.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
// 3. Let keys be ? props.[[OwnPropertyKeys]](). // 3. Let keys be ? props.[[OwnPropertyKeys]]().
auto keys = TRY(props->internal_own_property_keys()); auto keys = TRY(props->internal_own_property_keys());

View file

@ -78,7 +78,7 @@ Value ObjectConstructor::construct(FunctionObject& new_target)
auto value = vm.argument(0); auto value = vm.argument(0);
if (value.is_nullish()) if (value.is_nullish())
return Object::create(global_object, global_object.object_prototype()); return Object::create(global_object, global_object.object_prototype());
return value.to_object(global_object); return TRY_OR_DISCARD(value.to_object(global_object));
} }
enum class GetOwnPropertyKeysType { enum class GetOwnPropertyKeysType {
@ -92,9 +92,7 @@ static Array* get_own_property_keys(GlobalObject& global_object, Value value, Ge
auto& vm = global_object.vm(); auto& vm = global_object.vm();
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = value.to_object(global_object); auto* object = TRY_OR_DISCARD(value.to_object(global_object));
if (vm.exception())
return {};
// 2. Let keys be ? obj.[[OwnPropertyKeys]](). // 2. Let keys be ? obj.[[OwnPropertyKeys]]().
auto keys = TRY_OR_DISCARD(object->internal_own_property_keys()); auto keys = TRY_OR_DISCARD(object->internal_own_property_keys());
@ -133,9 +131,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
{ {
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
// 2. Return ? obj.[[GetPrototypeOf]](). // 2. Return ? obj.[[GetPrototypeOf]]().
return TRY_OR_DISCARD(object->internal_get_prototype_of()); return TRY_OR_DISCARD(object->internal_get_prototype_of());
@ -281,9 +277,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::seal)
// 20.1.2.8 Object.getOwnPropertyDescriptor ( O, P ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptor // 20.1.2.8 Object.getOwnPropertyDescriptor ( O, P ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto key = vm.argument(1).to_property_key(global_object); auto key = vm.argument(1).to_property_key(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
@ -295,9 +289,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
{ {
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
// 2. Let ownKeys be ? obj.[[OwnPropertyKeys]](). // 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
auto own_keys = TRY_OR_DISCARD(object->internal_own_property_keys()); auto own_keys = TRY_OR_DISCARD(object->internal_own_property_keys());
@ -364,9 +356,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is)
// 20.1.2.17 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys // 20.1.2.17 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::Key)); auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::Key));
return Array::create_from(global_object, name_list); return Array::create_from(global_object, name_list);
} }
@ -374,9 +364,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
// 20.1.2.22 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values // 20.1.2.22 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::Value)); auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::Value));
return Array::create_from(global_object, name_list); return Array::create_from(global_object, name_list);
} }
@ -384,9 +372,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
// 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries // 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
{ {
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::KeyAndValue)); auto name_list = TRY_OR_DISCARD(object->enumerable_own_property_names(PropertyKind::KeyAndValue));
return Array::create_from(global_object, name_list); return Array::create_from(global_object, name_list);
} }
@ -420,9 +406,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::has_own) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::has_own)
{ {
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
// 2. Let key be ? ToPropertyKey(P). // 2. Let key be ? ToPropertyKey(P).
auto key = vm.argument(1).to_property_key(global_object); auto key = vm.argument(1).to_property_key(global_object);
@ -437,9 +421,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::has_own)
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign) JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
{ {
// 1. Let to be ? ToObject(target). // 1. Let to be ? ToObject(target).
auto* to = vm.argument(0).to_object(global_object); auto* to = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
// 2. If only one argument was passed, return to. // 2. If only one argument was passed, return to.
if (vm.argument_count() == 1) if (vm.argument_count() == 1)
@ -454,8 +436,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
continue; continue;
// i. Let from be ! ToObject(nextSource). // i. Let from be ! ToObject(nextSource).
auto from = next_source.to_object(global_object); auto* from = MUST(next_source.to_object(global_object));
VERIFY(!vm.exception());
// ii. Let keys be ? from.[[OwnPropertyKeys]](). // ii. Let keys be ? from.[[OwnPropertyKeys]]().
auto keys = TRY_OR_DISCARD(from->internal_own_property_keys()); auto keys = TRY_OR_DISCARD(from->internal_own_property_keys());

View file

@ -65,9 +65,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
auto property_key = vm.argument(0).to_property_key(global_object); auto property_key = vm.argument(0).to_property_key(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
return Value(TRY_OR_DISCARD(this_object->has_own_property(property_key))); return Value(TRY_OR_DISCARD(this_object->has_own_property(property_key)));
} }
@ -85,8 +83,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
return js_string(vm, "[object Null]"); return js_string(vm, "[object Null]");
// 3. Let O be ! ToObject(this value). // 3. Let O be ! ToObject(this value).
auto* object = this_value.to_object(global_object); auto* object = MUST(this_value.to_object(global_object));
VERIFY(object);
// 4. Let isArray be ? IsArray(O). // 4. Let isArray be ? IsArray(O).
auto is_array = TRY_OR_DISCARD(Value(object).is_array(global_object)); auto is_array = TRY_OR_DISCARD(Value(object).is_array(global_object));
@ -150,7 +147,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_locale_string)
// 20.1.3.7 Object.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-object.prototype.valueof // 20.1.3.7 Object.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-object.prototype.valueof
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::value_of) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::value_of)
{ {
return vm.this_value(global_object).to_object(global_object); return TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
} }
// 20.1.3.4 Object.prototype.propertyIsEnumerable ( V ), https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable // 20.1.3.4 Object.prototype.propertyIsEnumerable ( V ), https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
@ -161,9 +158,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::property_is_enumerable)
if (vm.exception()) if (vm.exception())
return {}; return {};
// 2. Let O be ? ToObject(this value). // 2. Let O be ? ToObject(this value).
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
// 3. Let desc be ? O.[[GetOwnProperty]](P). // 3. Let desc be ? O.[[GetOwnProperty]](P).
auto property_descriptor = TRY_OR_DISCARD(this_object->internal_get_own_property(property_key)); auto property_descriptor = TRY_OR_DISCARD(this_object->internal_get_own_property(property_key));
// 4. If desc is undefined, return false. // 4. If desc is undefined, return false.
@ -180,9 +175,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::is_prototype_of)
if (!object_argument.is_object()) if (!object_argument.is_object())
return Value(false); return Value(false);
auto* object = &object_argument.as_object(); auto* object = &object_argument.as_object();
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return {};
for (;;) { for (;;) {
object = TRY_OR_DISCARD(object->internal_get_prototype_of()); object = TRY_OR_DISCARD(object->internal_get_prototype_of());
@ -196,9 +189,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::is_prototype_of)
// B.2.2.2 Object.prototype.__defineGetter__ ( P, getter ), https://tc39.es/ecma262/#sec-object.prototype.__defineGetter__ // B.2.2.2 Object.prototype.__defineGetter__ ( P, getter ), https://tc39.es/ecma262/#sec-object.prototype.__defineGetter__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_getter) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_getter)
{ {
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
auto getter = vm.argument(1); auto getter = vm.argument(1);
if (!getter.is_function()) { if (!getter.is_function()) {
@ -220,9 +211,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_getter)
// B.2.2.3 Object.prototype.__defineSetter__ ( P, getter ), https://tc39.es/ecma262/#sec-object.prototype.__defineSetter__ // B.2.2.3 Object.prototype.__defineSetter__ ( P, getter ), https://tc39.es/ecma262/#sec-object.prototype.__defineSetter__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter)
{ {
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
auto setter = vm.argument(1); auto setter = vm.argument(1);
if (!setter.is_function()) { if (!setter.is_function()) {
@ -244,9 +233,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter)
// B.2.2.4 Object.prototype.__lookupGetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupGetter__ // B.2.2.4 Object.prototype.__lookupGetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupGetter__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_getter) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_getter)
{ {
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
auto key = vm.argument(0).to_property_key(global_object); auto key = vm.argument(0).to_property_key(global_object);
if (vm.exception()) if (vm.exception())
@ -268,9 +255,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_getter)
// B.2.2.5 Object.prototype.__lookupSetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupSetter__ // B.2.2.5 Object.prototype.__lookupSetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupSetter__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_setter) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_setter)
{ {
auto* object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
auto key = vm.argument(0).to_property_key(global_object); auto key = vm.argument(0).to_property_key(global_object);
if (vm.exception()) if (vm.exception())
@ -292,9 +277,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_setter)
// B.2.2.1.1 get Object.prototype.__proto__, https://tc39.es/ecma262/#sec-get-object.prototype.__proto__ // B.2.2.1.1 get Object.prototype.__proto__, https://tc39.es/ecma262/#sec-get-object.prototype.__proto__
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter)
{ {
auto object = vm.this_value(global_object).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (vm.exception())
return {};
return TRY_OR_DISCARD(object->internal_get_prototype_of()); return TRY_OR_DISCARD(object->internal_get_prototype_of());
} }

View file

@ -277,9 +277,7 @@ Value PromiseConstructor::construct(FunctionObject& new_target)
// 27.2.4.1 Promise.all ( iterable ), https://tc39.es/ecma262/#sec-promise.all // 27.2.4.1 Promise.all ( iterable ), https://tc39.es/ecma262/#sec-promise.all
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto promise_capability = new_promise_capability(global_object, constructor); auto promise_capability = new_promise_capability(global_object, constructor);
if (vm.exception()) if (vm.exception())
@ -308,9 +306,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
// 27.2.4.2 Promise.allSettled ( iterable ), https://tc39.es/ecma262/#sec-promise.allsettled // 27.2.4.2 Promise.allSettled ( iterable ), https://tc39.es/ecma262/#sec-promise.allsettled
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto promise_capability = new_promise_capability(global_object, constructor); auto promise_capability = new_promise_capability(global_object, constructor);
if (vm.exception()) if (vm.exception())
@ -339,9 +335,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
// 27.2.4.3 Promise.any ( iterable ), https://tc39.es/ecma262/#sec-promise.any // 27.2.4.3 Promise.any ( iterable ), https://tc39.es/ecma262/#sec-promise.any
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto promise_capability = new_promise_capability(global_object, constructor); auto promise_capability = new_promise_capability(global_object, constructor);
if (vm.exception()) if (vm.exception())
@ -370,9 +364,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
// 27.2.4.5 Promise.race ( iterable ), https://tc39.es/ecma262/#sec-promise.race // 27.2.4.5 Promise.race ( iterable ), https://tc39.es/ecma262/#sec-promise.race
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto promise_capability = new_promise_capability(global_object, constructor); auto promise_capability = new_promise_capability(global_object, constructor);
if (vm.exception()) if (vm.exception())
@ -401,9 +393,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
// 27.2.4.6 Promise.reject ( r ), https://tc39.es/ecma262/#sec-promise.reject // 27.2.4.6 Promise.reject ( r ), https://tc39.es/ecma262/#sec-promise.reject
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto promise_capability = new_promise_capability(global_object, constructor); auto promise_capability = new_promise_capability(global_object, constructor);
if (vm.exception()) if (vm.exception())
return {}; return {};
@ -415,9 +405,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
// 27.2.4.7 Promise.resolve ( x ), https://tc39.es/ecma262/#sec-promise.resolve // 27.2.4.7 Promise.resolve ( x ), https://tc39.es/ecma262/#sec-promise.resolve
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
{ {
auto* constructor = vm.this_value(global_object).to_object(global_object); auto* constructor = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!constructor)
return {};
auto value = vm.argument(0); auto value = vm.argument(0);
return promise_resolve(global_object, *constructor, value); return promise_resolve(global_object, *constructor, value);
} }

View file

@ -61,9 +61,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::catch_)
// 27.2.5.3 Promise.prototype.finally ( onFinally ), https://tc39.es/ecma262/#sec-promise.prototype.finally // 27.2.5.3 Promise.prototype.finally ( onFinally ), https://tc39.es/ecma262/#sec-promise.prototype.finally
JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally) JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
{ {
auto* promise = vm.this_value(global_object).to_object(global_object); auto* promise = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!promise)
return {};
auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *promise, *global_object.promise_constructor())); auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *promise, *global_object.promise_constructor()));
Value then_finally; Value then_finally;
Value catch_finally; Value catch_finally;

View file

@ -44,9 +44,7 @@ public:
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return nullptr;
if (!is<ObjectType>(this_object)) { if (!is<ObjectType>(this_object)) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, PrototypeType::display_name()); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, PrototypeType::display_name());

View file

@ -32,9 +32,10 @@ void Reference::put_value(GlobalObject& global_object, Value value)
} }
if (is_property_reference()) { if (is_property_reference()) {
auto* base_obj = m_base_value.to_object(global_object); auto base_obj_or_error = m_base_value.to_object(global_object);
if (!base_obj) if (base_obj_or_error.is_error())
return; return;
auto* base_obj = base_obj_or_error.release_value();
auto succeeded_or_error = base_obj->internal_set(m_name, value, get_this_value()); auto succeeded_or_error = base_obj->internal_set(m_name, value, get_this_value());
if (succeeded_or_error.is_error()) if (succeeded_or_error.is_error())
@ -74,9 +75,7 @@ Value Reference::get_value(GlobalObject& global_object) const
} }
if (is_property_reference()) { if (is_property_reference()) {
auto* base_obj = m_base_value.to_object(global_object); auto* base_obj = TRY_OR_DISCARD(m_base_value.to_object(global_object));
if (!base_obj)
return {};
return TRY_OR_DISCARD(base_obj->get(m_name)); return TRY_OR_DISCARD(base_obj->get(m_name));
} }
@ -121,8 +120,7 @@ bool Reference::delete_(GlobalObject& global_object)
} }
// c. Let baseObj be ! ToObject(ref.[[Base]]). // c. Let baseObj be ! ToObject(ref.[[Base]]).
auto* base_obj = m_base_value.to_object(global_object); auto* base_obj = MUST(m_base_value.to_object(global_object));
VERIFY(base_obj);
// d. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]). // d. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]).
bool delete_status = TRY_OR_DISCARD(base_obj->internal_delete(m_name)); bool delete_status = TRY_OR_DISCARD(base_obj->internal_delete(m_name));

View file

@ -420,9 +420,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match)
return array; return array;
} }
auto* result_object = result.to_object(global_object); auto* result_object = TRY_OR_DISCARD(result.to_object(global_object));
if (!result_object)
return {};
auto match_object = TRY_OR_DISCARD(result_object->get(0)); auto match_object = TRY_OR_DISCARD(result_object->get(0));
auto match_str = TRY_OR_DISCARD(match_object.to_string(global_object)); auto match_str = TRY_OR_DISCARD(match_object.to_string(global_object));
@ -458,10 +456,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
auto matcher_value = vm.construct(*constructor, *constructor, move(arguments)); auto matcher_value = vm.construct(*constructor, *constructor, move(arguments));
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* matcher = matcher_value.to_object(global_object); auto* matcher = TRY_OR_DISCARD(matcher_value.to_object(global_object));
if (!matcher)
return {};
auto last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)).to_length(global_object); auto last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)).to_length(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
@ -506,10 +501,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
if (result.is_null()) if (result.is_null())
break; break;
auto* result_object = result.to_object(global_object); auto* result_object = TRY_OR_DISCARD(result.to_object(global_object));
if (!result_object)
return {};
results.append(result_object); results.append(result_object);
if (!global) if (!global)
break; break;
@ -566,14 +558,10 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
auto replace_result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), move(replacer_args))); auto replace_result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), move(replacer_args)));
replacement = TRY_OR_DISCARD(replace_result.to_string(global_object)); replacement = TRY_OR_DISCARD(replace_result.to_string(global_object));
} else { } else {
auto named_captures_object = js_undefined(); if (!named_captures.is_undefined())
if (!named_captures.is_undefined()) { named_captures = TRY_OR_DISCARD(named_captures.to_object(global_object));
named_captures_object = named_captures.to_object(global_object);
if (vm.exception())
return {};
}
replacement = TRY_OR_DISCARD(get_substitution(global_object, matched.view(), string_view, position, captures, named_captures_object, replace_value)); replacement = TRY_OR_DISCARD(get_substitution(global_object, matched.view(), string_view, position, captures, named_captures, replace_value));
} }
if (position >= next_source_position) { if (position >= next_source_position) {
@ -618,10 +606,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search)
if (result.is_null()) if (result.is_null())
return Value(-1); return Value(-1);
auto* result_object = result.to_object(global_object); auto* result_object = TRY_OR_DISCARD(result.to_object(global_object));
if (!result_object)
return {};
return TRY_OR_DISCARD(result_object->get(vm.names.index)); return TRY_OR_DISCARD(result_object->get(vm.names.index));
} }
@ -649,10 +634,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
auto splitter_value = vm.construct(*constructor, *constructor, move(arguments)); auto splitter_value = vm.construct(*constructor, *constructor, move(arguments));
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* splitter = splitter_value.to_object(global_object); auto* splitter = TRY_OR_DISCARD(splitter_value.to_object(global_object));
if (!splitter)
return {};
auto* array = Array::create(global_object, 0); auto* array = Array::create(global_object, 0);
size_t array_length = 0; size_t array_length = 0;
@ -705,12 +687,8 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
if (++array_length == limit) if (++array_length == limit)
return array; return array;
auto* result_object = result.to_object(global_object); auto* result_object = TRY_OR_DISCARD(result.to_object(global_object));
if (!result_object)
return {};
auto number_of_captures = TRY_OR_DISCARD(length_of_array_like(global_object, *result_object)); auto number_of_captures = TRY_OR_DISCARD(length_of_array_like(global_object, *result_object));
if (vm.exception())
return {};
if (number_of_captures > 0) if (number_of_captures > 0)
--number_of_captures; --number_of_captures;

View file

@ -54,9 +54,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next)
return create_iterator_result_object(global_object, match, false); return create_iterator_result_object(global_object, match, false);
} }
auto* match_object = match.to_object(global_object); auto* match_object = TRY_OR_DISCARD(match.to_object(global_object));
if (!match_object)
return {};
auto match_string_value = TRY_OR_DISCARD(match_object->get(0)); auto match_string_value = TRY_OR_DISCARD(match_object->get(0));
auto match_string = TRY_OR_DISCARD(match_string_value.to_string(global_object)); auto match_string = TRY_OR_DISCARD(match_string_value.to_string(global_object));
if (match_string.is_empty()) { if (match_string.is_empty()) {

View file

@ -69,17 +69,10 @@ Value StringConstructor::construct(FunctionObject& new_target)
// 22.1.2.4 String.raw ( template, ...substitutions ), https://tc39.es/ecma262/#sec-string.raw // 22.1.2.4 String.raw ( template, ...substitutions ), https://tc39.es/ecma262/#sec-string.raw
JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw) JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw)
{ {
auto* cooked = vm.argument(0).to_object(global_object); auto* cooked = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception()) auto raw_value = TRY_OR_DISCARD(cooked->get(vm.names.raw));
return {}; auto* raw = TRY_OR_DISCARD(raw_value.to_object(global_object));
auto* raw = TRY_OR_DISCARD(cooked->get(vm.names.raw)).to_object(global_object);
if (vm.exception())
return {};
auto literal_segments = TRY_OR_DISCARD(length_of_array_like(global_object, *raw)); auto literal_segments = TRY_OR_DISCARD(length_of_array_like(global_object, *raw));
if (vm.exception())
return {};
if (literal_segments == 0) if (literal_segments == 0)
return js_string(vm, ""); return js_string(vm, "");

View file

@ -421,9 +421,7 @@ ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Obje
auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, &options)); auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, &options));
// 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]). // 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
auto* date_object = date.to_object(global_object); auto* date_object = TRY(date.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
if (!is<PlainDate>(date_object)) if (!is<PlainDate>(date_object))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
@ -447,9 +445,7 @@ ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject& global_o
auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined())); auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]). // 6. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
auto* year_month_object = year_month.to_object(global_object); auto* year_month_object = TRY(year_month.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
if (!is<PlainYearMonth>(year_month_object)) if (!is<PlainYearMonth>(year_month_object))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth"); return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth");
@ -473,9 +469,7 @@ ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_obj
auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined())); auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]). // 6. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]).
auto* month_day_object = month_day.to_object(global_object); auto* month_day_object = TRY(month_day.to_object(global_object));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
if (!is<PlainMonthDay>(month_day_object)) if (!is<PlainMonthDay>(month_day_object))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay"); return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay");

View file

@ -604,14 +604,10 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::merge_fields)
VERIFY(calendar->identifier() == "iso8601"sv); VERIFY(calendar->identifier() == "iso8601"sv);
// 4. Set fields to ? ToObject(fields). // 4. Set fields to ? ToObject(fields).
auto* fields = vm.argument(0).to_object(global_object); auto* fields = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
// 5. Set additionalFields to ? ToObject(additionalFields). // 5. Set additionalFields to ? ToObject(additionalFields).
auto* additional_fields = vm.argument(1).to_object(global_object); auto* additional_fields = TRY_OR_DISCARD(vm.argument(1).to_object(global_object));
if (vm.exception())
return {};
// 6. Return ? DefaultMergeFields(fields, additionalFields). // 6. Return ? DefaultMergeFields(fields, additionalFields).
return TRY_OR_DISCARD(default_merge_fields(global_object, *fields, *additional_fields)); return TRY_OR_DISCARD(default_merge_fields(global_object, *fields, *additional_fields));

View file

@ -21,9 +21,7 @@ TypedArrayBase* typed_array_from(GlobalObject& global_object, Value typed_array_
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
auto* this_object = typed_array_value.to_object(global_object); auto* this_object = TRY_OR_DISCARD(typed_array_value.to_object(global_object));
if (!this_object)
return nullptr;
if (!this_object->is_typed_array()) { if (!this_object->is_typed_array()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "TypedArray"); vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "TypedArray");
return nullptr; return nullptr;

View file

@ -100,7 +100,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
return target_object; return target_object;
} }
auto array_like = source.to_object(global_object); auto array_like = MUST(source.to_object(global_object));
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *array_like)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *array_like));
MarkedValueList arguments(vm.heap()); MarkedValueList arguments(vm.heap());

View file

@ -790,10 +790,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set)
auto target_length = typed_array->array_length(); auto target_length = typed_array->array_length();
auto target_byte_offset = typed_array->byte_offset(); auto target_byte_offset = typed_array->byte_offset();
auto src = source.to_object(global_object); auto src = TRY_OR_DISCARD(source.to_object(global_object));
if (vm.exception())
return {};
auto source_length = TRY_OR_DISCARD(length_of_array_like(global_object, *src)); auto source_length = TRY_OR_DISCARD(length_of_array_like(global_object, *src));
if (isinf(target_offset)) { if (isinf(target_offset)) {

View file

@ -220,11 +220,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
// 14.3.3.1 Runtime Semantics: PropertyBindingInitialization, https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization // 14.3.3.1 Runtime Semantics: PropertyBindingInitialization, https://tc39.es/ecma262/#sec-destructuring-binding-patterns-runtime-semantics-propertybindinginitialization
ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment, GlobalObject& global_object) ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const& binding, Value value, Environment* environment, GlobalObject& global_object)
{ {
auto* object = value.to_object(global_object); auto* object = TRY(value.to_object(global_object));
if (!object) {
VERIFY(exception());
return JS::throw_completion(exception()->value());
}
HashTable<PropertyName, PropertyNameTraits> seen_names; HashTable<PropertyName, PropertyNameTraits> seen_names;
for (auto& property : binding.entries) { for (auto& property : binding.entries) {

View file

@ -434,13 +434,12 @@ ThrowCompletionOr<Value> Value::to_primitive(GlobalObject& global_object, Prefer
} }
// 7.1.18 ToObject ( argument ), https://tc39.es/ecma262/#sec-toobject // 7.1.18 ToObject ( argument ), https://tc39.es/ecma262/#sec-toobject
Object* Value::to_object(GlobalObject& global_object) const ThrowCompletionOr<Object*> Value::to_object(GlobalObject& global_object) const
{ {
switch (m_type) { switch (m_type) {
case Type::Undefined: case Type::Undefined:
case Type::Null: case Type::Null:
global_object.vm().throw_exception<TypeError>(global_object, ErrorType::ToObjectNullOrUndefined); return global_object.vm().throw_completion<TypeError>(global_object, ErrorType::ToObjectNullOrUndefined);
return nullptr;
case Type::Boolean: case Type::Boolean:
return BooleanObject::create(global_object, m_value.as_bool); return BooleanObject::create(global_object, m_value.as_bool);
case Type::Int32: case Type::Int32:
@ -455,7 +454,6 @@ Object* Value::to_object(GlobalObject& global_object) const
case Type::Object: case Type::Object:
return &const_cast<Object&>(as_object()); return &const_cast<Object&>(as_object());
default: default:
dbgln("Dying because I can't to_object() on {}", *this);
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
} }
@ -780,15 +778,11 @@ double Value::to_integer_or_infinity(GlobalObject& global_object) const
// 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv // 7.3.3 GetV ( V, P ), https://tc39.es/ecma262/#sec-getv
Value Value::get(GlobalObject& global_object, PropertyName const& property_name) const Value Value::get(GlobalObject& global_object, PropertyName const& property_name) const
{ {
auto& vm = global_object.vm();
// 1. Assert: IsPropertyKey(P) is true. // 1. Assert: IsPropertyKey(P) is true.
VERIFY(property_name.is_valid()); VERIFY(property_name.is_valid());
// 2. Let O be ? ToObject(V). // 2. Let O be ? ToObject(V).
auto* object = to_object(global_object); auto* object = TRY_OR_DISCARD(to_object(global_object));
if (vm.exception())
return {};
// 3. Return ? O.[[Get]](P, V). // 3. Return ? O.[[Get]](P, V).
return TRY_OR_DISCARD(object->internal_get(property_name, *this)); return TRY_OR_DISCARD(object->internal_get(property_name, *this));

View file

@ -307,7 +307,7 @@ public:
ThrowCompletionOr<Utf16String> to_utf16_string(GlobalObject&) const; ThrowCompletionOr<Utf16String> to_utf16_string(GlobalObject&) const;
ThrowCompletionOr<PrimitiveString*> to_primitive_string(GlobalObject&); ThrowCompletionOr<PrimitiveString*> to_primitive_string(GlobalObject&);
ThrowCompletionOr<Value> to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const; ThrowCompletionOr<Value> to_primitive(GlobalObject&, PreferredType preferred_type = PreferredType::Default) const;
Object* to_object(GlobalObject&) const; ThrowCompletionOr<Object*> to_object(GlobalObject&) const;
Value to_numeric(GlobalObject&) const; Value to_numeric(GlobalObject&) const;
Value to_number(GlobalObject&) const; Value to_number(GlobalObject&) const;
BigInt* to_bigint(GlobalObject&) const; BigInt* to_bigint(GlobalObject&) const;

View file

@ -170,8 +170,7 @@ static DOM::Window* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
this_value = global_object.value_of(); this_value = global_object.value_of();
} }
auto* this_object = this_value.to_object(global_object); auto* this_object = MUST(this_value.to_object(global_object));
VERIFY(this_object);
if (StringView("WindowObject") != this_object->class_name()) { if (StringView("WindowObject") != this_object->class_name()) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WindowObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WindowObject");
@ -343,9 +342,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_animation_frame)
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "requestAnimationFrame"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountOne, "requestAnimationFrame");
return {}; return {};
} }
auto* callback_object = vm.argument(0).to_object(global_object); auto* callback_object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (!callback_object)
return {};
if (!callback_object->is_function()) { if (!callback_object->is_function()) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
return {}; return {};
@ -378,9 +375,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::queue_microtask)
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "queueMicrotask"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::BadArgCountAtLeastOne, "queueMicrotask");
return {}; return {};
} }
auto* callback_object = vm.argument(0).to_object(global_object); auto* callback_object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (!callback_object)
return {};
if (!callback_object->is_function()) { if (!callback_object->is_function()) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAFunctionNoParam);
return {}; return {};
@ -545,10 +540,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::get_computed_style)
auto* impl = impl_from(vm, global_object); auto* impl = impl_from(vm, global_object);
if (!impl) if (!impl)
return {}; return {};
auto* object = vm.argument(0).to_object(global_object); auto* object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
if (!is<ElementWrapper>(object)) { if (!is<ElementWrapper>(object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "DOM element"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "DOM element");
return {}; return {};
@ -624,10 +616,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll)
String behavior_string = "auto"; String behavior_string = "auto";
if (vm.argument_count() == 1) { if (vm.argument_count() == 1) {
auto* options = vm.argument(0).to_object(global_object); auto* options = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto left = TRY_OR_DISCARD(options->get("left")); auto left = TRY_OR_DISCARD(options->get("left"));
if (!left.is_undefined()) if (!left.is_undefined())
x_value = left; x_value = left;
@ -684,9 +673,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by)
if (vm.argument_count() == 0) { if (vm.argument_count() == 0) {
options = JS::Object::create(global_object, nullptr); options = JS::Object::create(global_object, nullptr);
} else if (vm.argument_count() == 1) { } else if (vm.argument_count() == 1) {
options = vm.argument(0).to_object(global_object); options = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
} else if (vm.argument_count() >= 2) { } else if (vm.argument_count() >= 2) {
// We ignore arguments 2+ in line with behavior of Chrome and Firefox // We ignore arguments 2+ in line with behavior of Chrome and Firefox
options = JS::Object::create(global_object, nullptr); options = JS::Object::create(global_object, nullptr);

View file

@ -33,11 +33,7 @@ JS::Value WebAssemblyInstanceConstructor::construct(FunctionObject&)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
auto& global_object = this->global_object(); auto& global_object = this->global_object();
auto* module_argument = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
auto module_argument = vm.argument(0).to_object(global_object);
if (vm.exception())
return {};
if (!is<WebAssemblyModuleObject>(module_argument)) { if (!is<WebAssemblyModuleObject>(module_argument)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Module"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Module");
return {}; return {};

View file

@ -19,9 +19,7 @@ void WebAssemblyInstancePrototype::initialize(JS::GlobalObject& global_object)
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyInstancePrototype::exports_getter) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyInstancePrototype::exports_getter)
{ {
auto this_value = vm.this_value(global_object); auto this_value = vm.this_value(global_object);
auto this_object = this_value.to_object(global_object); auto* this_object = TRY_OR_DISCARD(this_value.to_object(global_object));
if (vm.exception())
return {};
if (!is<WebAssemblyInstanceObject>(this_object)) { if (!is<WebAssemblyInstanceObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Instance"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Instance");
return {}; return {};

View file

@ -32,10 +32,7 @@ JS::Value WebAssemblyMemoryConstructor::construct(FunctionObject&)
auto& vm = this->vm(); auto& vm = this->vm();
auto& global_object = this->global_object(); auto& global_object = this->global_object();
auto descriptor = vm.argument(0).to_object(global_object); auto descriptor = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto initial_value = TRY_OR_DISCARD(descriptor->get("initial")); auto initial_value = TRY_OR_DISCARD(descriptor->get("initial"));
auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum")); auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum"));

View file

@ -22,8 +22,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::grow)
auto page_count = vm.argument(0).to_u32(global_object); auto page_count = vm.argument(0).to_u32(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyMemoryObject>(this_object)) { if (!is<WebAssemblyMemoryObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Memory"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Memory");
return {}; return {};
} }
@ -44,8 +44,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::grow)
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::buffer_getter) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyMemoryPrototype::buffer_getter)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyMemoryObject>(this_object)) { if (!is<WebAssemblyMemoryObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Memory"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Memory");
return {}; return {};
} }

View file

@ -34,10 +34,7 @@ JS::Value WebAssemblyModuleConstructor::construct(FunctionObject&)
auto& vm = this->vm(); auto& vm = this->vm();
auto& global_object = this->global_object(); auto& global_object = this->global_object();
auto buffer_object = vm.argument(0).to_object(global_object); auto* buffer_object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto result = parse_module(global_object, buffer_object); auto result = parse_module(global_object, buffer_object);
if (result.is_error()) { if (result.is_error()) {
vm.throw_exception(global_object, result.error()); vm.throw_exception(global_object, result.error());

View file

@ -130,17 +130,19 @@ Result<size_t, JS::Value> parse_module(JS::GlobalObject& global_object, JS::Obje
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile)
{ {
// FIXME: This shouldn't block! // FIXME: This shouldn't block!
auto buffer = vm.argument(0).to_object(global_object); auto buffer_or_error = vm.argument(0).to_object(global_object);
JS::Value rejection_value; JS::Value rejection_value;
if (vm.exception()) { if (buffer_or_error.is_error()) {
rejection_value = vm.exception()->value(); rejection_value = buffer_or_error.throw_completion().value();
vm.clear_exception(); vm.clear_exception();
vm.stop_unwind();
} }
auto promise = JS::Promise::create(global_object); auto promise = JS::Promise::create(global_object);
if (!rejection_value.is_empty()) { if (!rejection_value.is_empty()) {
promise->reject(rejection_value); promise->reject(rejection_value);
return promise; return promise;
} }
auto* buffer = buffer_or_error.release_value();
auto result = parse_module(global_object, buffer); auto result = parse_module(global_object, buffer);
if (result.is_error()) if (result.is_error())
promise->reject(result.error()); promise->reject(result.error());
@ -155,11 +157,13 @@ Result<size_t, JS::Value> WebAssemblyObject::instantiate_module(Wasm::Module con
HashMap<Wasm::Linker::Name, Wasm::ExternValue> resolved_imports; HashMap<Wasm::Linker::Name, Wasm::ExternValue> resolved_imports;
auto import_argument = vm.argument(1); auto import_argument = vm.argument(1);
if (!import_argument.is_undefined()) { if (!import_argument.is_undefined()) {
[[maybe_unused]] auto import_object = import_argument.to_object(global_object); auto import_object_or_error = import_argument.to_object(global_object);
if (auto exception = vm.exception()) { if (import_object_or_error.is_error()) {
vm.clear_exception(); vm.clear_exception();
return exception->value(); vm.stop_unwind();
return import_object_or_error.throw_completion().value();
} }
[[maybe_unused]] auto* import_object = import_object_or_error.release_value();
dbgln("Trying to resolve stuff because import object was specified"); dbgln("Trying to resolve stuff because import object was specified");
for (const Wasm::Linker::Name& import_name : linker.unresolved_imports()) { for (const Wasm::Linker::Name& import_name : linker.unresolved_imports()) {
@ -168,10 +172,10 @@ Result<size_t, JS::Value> WebAssemblyObject::instantiate_module(Wasm::Module con
if (value_or_error.is_error()) if (value_or_error.is_error())
break; break;
auto value = value_or_error.release_value(); auto value = value_or_error.release_value();
auto object = value.to_object(global_object); auto object_or_error = value.to_object(global_object);
if (vm.exception()) if (object_or_error.is_error())
break; break;
auto* object = object_or_error.release_value();
auto import_or_error = object->get(import_name.name); auto import_or_error = object->get(import_name.name);
if (import_or_error.is_error()) if (import_or_error.is_error())
break; break;
@ -307,22 +311,17 @@ Result<size_t, JS::Value> WebAssemblyObject::instantiate_module(Wasm::Module con
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
{ {
// FIXME: This shouldn't block! // FIXME: This shouldn't block!
auto buffer = vm.argument(0).to_object(global_object); auto buffer_or_error = vm.argument(0).to_object(global_object);
auto promise = JS::Promise::create(global_object); auto promise = JS::Promise::create(global_object);
bool should_return_module = false; bool should_return_module = false;
auto take_exception_and_reject_if_needed = [&] { if (buffer_or_error.is_error()) {
if (vm.exception()) { auto rejection_value = buffer_or_error.throw_completion().value();
auto rejection_value = vm.exception()->value(); vm.clear_exception();
vm.clear_exception(); vm.stop_unwind();
promise->reject(rejection_value); promise->reject(rejection_value);
return true;
}
return false;
};
if (take_exception_and_reject_if_needed())
return promise; return promise;
}
auto* buffer = buffer_or_error.release_value();
const Wasm::Module* module { nullptr }; const Wasm::Module* module { nullptr };
if (is<JS::ArrayBuffer>(buffer) || is<JS::TypedArrayBase>(buffer)) { if (is<JS::ArrayBuffer>(buffer) || is<JS::TypedArrayBase>(buffer)) {

View file

@ -34,10 +34,7 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&)
auto& vm = this->vm(); auto& vm = this->vm();
auto& global_object = this->global_object(); auto& global_object = this->global_object();
auto descriptor = vm.argument(0).to_object(global_object); auto descriptor = TRY_OR_DISCARD(vm.argument(0).to_object(global_object));
if (vm.exception())
return {};
auto element_value = TRY_OR_DISCARD(descriptor->get("element")); auto element_value = TRY_OR_DISCARD(descriptor->get("element"));
if (!element_value.is_string()) { if (!element_value.is_string()) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects()); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects());

View file

@ -24,8 +24,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::grow)
auto delta = vm.argument(0).to_u32(global_object); auto delta = vm.argument(0).to_u32(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyTableObject>(this_object)) { if (!is<WebAssemblyTableObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table");
return {}; return {};
} }
@ -63,8 +63,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::get)
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyTableObject>(this_object)) { if (!is<WebAssemblyTableObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table");
return {}; return {};
} }
@ -93,8 +93,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::set)
if (vm.exception()) if (vm.exception())
return {}; return {};
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyTableObject>(this_object)) { if (!is<WebAssemblyTableObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table");
return {}; return {};
} }
@ -128,8 +128,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::set)
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::length_getter) JS_DEFINE_NATIVE_FUNCTION(WebAssemblyTablePrototype::length_getter)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object || !is<WebAssemblyTableObject>(this_object)) { if (!is<WebAssemblyTableObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Table");
return {}; return {};
} }

View file

@ -100,9 +100,7 @@ JS::ThrowCompletionOr<JS::MarkedValueList> ConsoleGlobalObject::internal_own_pro
JS_DEFINE_NATIVE_GETTER(ConsoleGlobalObject::inspected_node_getter) JS_DEFINE_NATIVE_GETTER(ConsoleGlobalObject::inspected_node_getter)
{ {
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = TRY_OR_DISCARD(vm.this_value(global_object).to_object(global_object));
if (!this_object)
return JS::js_null();
if (!is<ConsoleGlobalObject>(this_object)) { if (!is<ConsoleGlobalObject>(this_object)) {
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "ConsoleGlobalObject"); vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "ConsoleGlobalObject");

View file

@ -1347,7 +1347,7 @@ int main(int argc, char** argv)
if (!variable.is_object()) if (!variable.is_object())
break; break;
auto const* object = variable.to_object(interpreter->global_object()); auto const* object = MUST(variable.to_object(interpreter->global_object()));
auto const& shape = object->shape(); auto const& shape = object->shape();
list_all_properties(shape, property_name); list_all_properties(shape, property_name);
if (results.size()) if (results.size())