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

LibJS: Port Value::to_object() to NonnullGCPtr

This commit is contained in:
Linus Groh 2023-04-13 15:26:41 +02:00 committed by Andreas Kling
parent e79f5b6e85
commit f345f72b55
29 changed files with 264 additions and 263 deletions

View file

@ -3842,10 +3842,10 @@ JS::ThrowCompletionOr<void> @prototype_class@::initialize(JS::Realm& realm)
static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm) static JS::ThrowCompletionOr<@fully_qualified_name@*> impl_from(JS::VM& vm)
{ {
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<@fully_qualified_name@>(this_object)) if (!is<@fully_qualified_name@>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@name@"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "@name@");
return static_cast<@fully_qualified_name@*>(this_object); return static_cast<@fully_qualified_name@*>(this_object.ptr());
} }
JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::next) JS_DEFINE_NATIVE_FUNCTION(@prototype_class@::next)

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org> * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -33,20 +33,20 @@ 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 = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
if (!is<JS::WeakSet>(object)) if (!is<JS::WeakSet>(*object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakSet"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakSet");
auto* weak_set = static_cast<JS::WeakSet*>(object); auto& weak_set = static_cast<JS::WeakSet&>(*object);
return JS::Value(weak_set->values().size()); return JS::Value(weak_set.values().size());
} }
TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize) TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize)
{ {
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
if (!is<JS::WeakMap>(object)) if (!is<JS::WeakMap>(*object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakMap"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WeakMap");
auto* weak_map = static_cast<JS::WeakMap*>(object); auto& weak_map = static_cast<JS::WeakMap&>(*object);
return JS::Value(weak_map->values().size()); return JS::Value(weak_map.values().size());
} }
TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage) TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)

View file

@ -107,8 +107,8 @@ 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& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
if (!is<JS::Uint8Array>(object)) if (!is<JS::Uint8Array>(*object))
return vm.throw_completion<JS::TypeError>("Expected a Uint8Array argument to parse_webassembly_module"sv); return vm.throw_completion<JS::TypeError>("Expected a Uint8Array argument to parse_webassembly_module"sv);
auto& array = static_cast<JS::Uint8Array&>(*object); auto& array = static_cast<JS::Uint8Array&>(*object);
FixedMemoryStream stream { array.data() }; FixedMemoryStream stream { array.data() };
@ -137,12 +137,12 @@ TESTJS_GLOBAL_FUNCTION(parse_webassembly_module, parseWebAssemblyModule)
TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays) TESTJS_GLOBAL_FUNCTION(compare_typed_arrays, compareTypedArrays)
{ {
auto* lhs = TRY(vm.argument(0).to_object(vm)); auto lhs = TRY(vm.argument(0).to_object(vm));
if (!is<JS::TypedArrayBase>(lhs)) if (!is<JS::TypedArrayBase>(*lhs))
return vm.throw_completion<JS::TypeError>("Expected a TypedArray"sv); return vm.throw_completion<JS::TypeError>("Expected a TypedArray"sv);
auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs); auto& lhs_array = static_cast<JS::TypedArrayBase&>(*lhs);
auto* rhs = TRY(vm.argument(1).to_object(vm)); auto rhs = TRY(vm.argument(1).to_object(vm));
if (!is<JS::TypedArrayBase>(rhs)) if (!is<JS::TypedArrayBase>(*rhs))
return vm.throw_completion<JS::TypeError>("Expected a TypedArray"sv); return vm.throw_completion<JS::TypeError>("Expected a TypedArray"sv);
auto& rhs_array = static_cast<JS::TypedArrayBase&>(*rhs); auto& rhs_array = static_cast<JS::TypedArrayBase&>(*rhs);
return JS::Value(lhs_array.viewed_array_buffer()->buffer() == rhs_array.viewed_array_buffer()->buffer()); return JS::Value(lhs_array.viewed_array_buffer()->buffer() == rhs_array.viewed_array_buffer()->buffer());
@ -161,11 +161,11 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
{ {
auto name = TRY(vm.argument(0).to_deprecated_string(vm)); auto name = TRY(vm.argument(0).to_deprecated_string(vm));
auto this_value = vm.this_value(); auto this_value = vm.this_value();
auto* object = TRY(this_value.to_object(vm)); auto object = TRY(this_value.to_object(vm));
if (!is<WebAssemblyModule>(object)) if (!is<WebAssemblyModule>(*object))
return vm.throw_completion<JS::TypeError>("Not a WebAssemblyModule"sv); return vm.throw_completion<JS::TypeError>("Not a WebAssemblyModule"sv);
auto instance = static_cast<WebAssemblyModule*>(object); auto& instance = static_cast<WebAssemblyModule&>(*object);
for (auto& entry : instance->module_instance().exports()) { for (auto& entry : instance.module_instance().exports()) {
if (entry.name() == name) { if (entry.name() == name) {
auto& value = entry.value(); auto& value = entry.value();
if (auto ptr = value.get_pointer<Wasm::FunctionAddress>()) if (auto ptr = value.get_pointer<Wasm::FunctionAddress>())

View file

@ -174,23 +174,23 @@ void SheetGlobalObject::visit_edges(Visitor& visitor)
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_name) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_name)
{ {
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
return JS::PrimitiveString::create(vm, sheet_object->m_sheet.name()); return JS::PrimitiveString::create(vm, sheet_object.m_sheet.name());
} }
JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents) JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
{ {
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
if (vm.argument_count() != 1) if (vm.argument_count() != 1)
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to get_real_cell_contents()"sv); return vm.throw_completion<JS::TypeError>("Expected exactly one argument to get_real_cell_contents()"sv);
@ -198,11 +198,11 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected a String argument to get_real_cell_contents()"sv); return vm.throw_completion<JS::TypeError>("Expected a String argument to get_real_cell_contents()"sv);
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string())); auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
if (!position.has_value()) if (!position.has_value())
return vm.throw_completion<JS::TypeError>("Invalid cell name"sv); return vm.throw_completion<JS::TypeError>("Invalid cell name"sv);
auto const* cell = sheet_object->m_sheet.at(position.value()); auto const* cell = sheet_object.m_sheet.at(position.value());
if (!cell) if (!cell)
return JS::js_undefined(); return JS::js_undefined();
@ -214,12 +214,12 @@ 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
if (vm.argument_count() != 2) if (vm.argument_count() != 2)
return vm.throw_completion<JS::TypeError>("Expected exactly two arguments to set_real_cell_contents()"sv); return vm.throw_completion<JS::TypeError>("Expected exactly two arguments to set_real_cell_contents()"sv);
@ -227,7 +227,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected the first argument of set_real_cell_contents() to be a String"sv); return vm.throw_completion<JS::TypeError>("Expected the first argument of set_real_cell_contents() to be a String"sv);
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string())); auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
if (!position.has_value()) if (!position.has_value())
return vm.throw_completion<JS::TypeError>("Invalid cell name"sv); return vm.throw_completion<JS::TypeError>("Invalid cell name"sv);
@ -235,7 +235,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
if (!new_contents_value.is_string()) if (!new_contents_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected the second argument of set_real_cell_contents() to be a String"sv); return vm.throw_completion<JS::TypeError>("Expected the second argument of set_real_cell_contents() to be a String"sv);
auto& cell = sheet_object->m_sheet.ensure(position.value()); auto& cell = sheet_object.m_sheet.ensure(position.value());
auto new_contents = TRY(new_contents_value.as_string().deprecated_string()); auto new_contents = TRY(new_contents_value.as_string().deprecated_string());
cell.set_data(new_contents); cell.set_data(new_contents);
return JS::js_null(); return JS::js_null();
@ -245,24 +245,24 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
if (vm.argument_count() != 1) if (vm.argument_count() != 1)
return vm.throw_completion<JS::TypeError>("Expected exactly one argument to parse_cell_name()"sv); return vm.throw_completion<JS::TypeError>("Expected exactly one argument to parse_cell_name()"sv);
auto name_value = vm.argument(0); auto name_value = vm.argument(0);
if (!name_value.is_string()) if (!name_value.is_string())
return vm.throw_completion<JS::TypeError>("Expected a String argument to parse_cell_name()"sv); return vm.throw_completion<JS::TypeError>("Expected a String argument to parse_cell_name()"sv);
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string())); auto position = sheet_object.m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
if (!position.has_value()) if (!position.has_value())
return JS::js_undefined(); return JS::js_undefined();
auto object = JS::Object::create(realm, realm.intrinsics().object_prototype()); auto object = JS::Object::create(realm, realm.intrinsics().object_prototype());
object->define_direct_property("column", JS::PrimitiveString::create(vm, sheet_object->m_sheet.column(position.value().column)), JS::default_attributes); object->define_direct_property("column", JS::PrimitiveString::create(vm, sheet_object.m_sheet.column(position.value().column)), JS::default_attributes);
object->define_direct_property("row", JS::Value((unsigned)position.value().row), JS::default_attributes); object->define_direct_property("row", JS::Value((unsigned)position.value().row), JS::default_attributes);
return object; return object;
@ -275,20 +275,20 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::current_cell_position)
if (vm.argument_count() != 0) if (vm.argument_count() != 0)
return vm.throw_completion<JS::TypeError>("Expected no arguments to current_cell_position()"sv); return vm.throw_completion<JS::TypeError>("Expected no arguments to current_cell_position()"sv);
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
auto* current_cell = sheet_object->m_sheet.current_evaluated_cell(); auto* current_cell = sheet_object.m_sheet.current_evaluated_cell();
if (!current_cell) if (!current_cell)
return JS::js_null(); return JS::js_null();
auto position = current_cell->position(); auto position = current_cell->position();
auto object = JS::Object::create(realm, realm.intrinsics().object_prototype()); auto object = JS::Object::create(realm, realm.intrinsics().object_prototype());
object->define_direct_property("column", JS::PrimitiveString::create(vm, sheet_object->m_sheet.column(position.column)), JS::default_attributes); object->define_direct_property("column", JS::PrimitiveString::create(vm, sheet_object.m_sheet.column(position.column)), JS::default_attributes);
object->define_direct_property("row", JS::Value((unsigned)position.row), JS::default_attributes); object->define_direct_property("row", JS::Value((unsigned)position.row), JS::default_attributes);
return object; return object;
@ -305,13 +305,13 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
auto column_name_str = TRY(column_name.as_string().deprecated_string()); auto column_name_str = TRY(column_name.as_string().deprecated_string());
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
auto& sheet = sheet_object->m_sheet; auto& sheet = sheet_object.m_sheet;
auto column_index = sheet.column_index(column_name_str); auto column_index = sheet.column_index(column_name_str);
if (!column_index.has_value()) if (!column_index.has_value())
return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str))); return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str)));
@ -333,13 +333,13 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
auto offset = TRY(vm.argument(1).to_number(vm)); auto offset = TRY(vm.argument(1).to_number(vm));
auto offset_number = static_cast<i32>(offset.as_double()); auto offset_number = static_cast<i32>(offset.as_double());
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
auto& sheet = sheet_object->m_sheet; auto& sheet = sheet_object.m_sheet;
auto new_column = sheet.column_arithmetic(column_name_str, offset_number); auto new_column = sheet.column_arithmetic(column_name_str, offset_number);
if (!new_column.has_value()) if (!new_column.has_value())
return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str))); return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str)));
@ -357,13 +357,13 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
auto column_name_str = TRY(column_name.as_string().deprecated_string()); auto column_name_str = TRY(column_name.as_string().deprecated_string());
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<SheetGlobalObject>(this_object)) if (!is<SheetGlobalObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "SheetGlobalObject");
auto sheet_object = static_cast<SheetGlobalObject*>(this_object); auto& sheet_object = static_cast<SheetGlobalObject&>(*this_object);
auto& sheet = sheet_object->m_sheet; auto& sheet = sheet_object.m_sheet;
auto maybe_column_index = sheet.column_index(column_name_str); auto maybe_column_index = sheet.column_index(column_name_str);
if (!maybe_column_index.has_value()) if (!maybe_column_index.has_value())
return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str))); return vm.throw_completion<JS::TypeError>(TRY_OR_THROW_OOM(vm, String::formatted("'{}' is not a valid column", column_name_str)));
@ -401,12 +401,13 @@ JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
if (!name_value.is_string() && !name_value.is_number()) if (!name_value.is_string() && !name_value.is_number())
return vm.throw_completion<JS::TypeError>("Expected a String or Number argument to sheet()"sv); return vm.throw_completion<JS::TypeError>("Expected a String or Number argument to sheet()"sv);
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<WorkbookObject>(this_object)) if (!is<WorkbookObject>(*this_object))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WorkbookObject"); return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WorkbookObject");
auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook; auto& workbook_object = static_cast<WorkbookObject&>(*this_object);
auto& workbook = workbook_object.m_workbook;
if (name_value.is_string()) { if (name_value.is_string()) {
auto name = TRY(name_value.as_string().deprecated_string()); auto name = TRY(name_value.as_string().deprecated_string());

View file

@ -619,13 +619,13 @@ Completion WithStatement::execute(Interpreter& interpreter) const
auto value = TRY(m_object->execute(interpreter)).release_value(); auto value = TRY(m_object->execute(interpreter)).release_value();
// 2. Let obj be ? ToObject(? GetValue(value)). // 2. Let obj be ? ToObject(? GetValue(value)).
auto* object = TRY(value.to_object(vm)); auto object = TRY(value.to_object(vm));
// 3. Let oldEnv be the running execution context's LexicalEnvironment. // 3. Let oldEnv be the running execution context's LexicalEnvironment.
auto old_environment = vm.running_execution_context().lexical_environment; auto old_environment = vm.running_execution_context().lexical_environment;
// 4. Let newEnv be NewObjectEnvironment(obj, true, oldEnv). // 4. Let newEnv be NewObjectEnvironment(obj, true, oldEnv).
auto new_environment = new_object_environment(*object, true, old_environment); auto new_environment = new_object_environment(object, true, old_environment);
// 5. Set the running execution context's LexicalEnvironment to newEnv. // 5. Set the running execution context's LexicalEnvironment to newEnv.
vm.running_execution_context().lexical_environment = new_environment; vm.running_execution_context().lexical_environment = new_environment;
@ -1155,7 +1155,7 @@ Completion ForInStatement::loop_evaluation(Interpreter& interpreter, Vector<Depr
} }
// b. Let obj be ! ToObject(exprValue). // b. Let obj be ! ToObject(exprValue).
auto* object = MUST(rhs_result.to_object(vm)); auto object = MUST(rhs_result.to_object(vm));
// 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

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org> * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -271,7 +271,7 @@ ThrowCompletionOr<void> IteratorToArray::execute_impl(Bytecode::Interpreter& int
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto iterator_object = TRY(interpreter.accumulator().to_object(vm)); auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
auto iterator = object_to_iterator(vm, *iterator_object); auto iterator = object_to_iterator(vm, iterator_object);
auto array = MUST(Array::create(interpreter.realm(), 0)); auto array = MUST(Array::create(interpreter.realm(), 0));
size_t index = 0; size_t index = 0;
@ -340,7 +340,7 @@ ThrowCompletionOr<void> CopyObjectExcludingProperties::execute_impl(Bytecode::In
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* from_object = TRY(interpreter.reg(m_from_object).to_object(vm)); auto from_object = TRY(interpreter.reg(m_from_object).to_object(vm));
auto to_object = Object::create(realm, realm.intrinsics().object_prototype()); auto to_object = Object::create(realm, realm.intrinsics().object_prototype());
@ -431,7 +431,7 @@ ThrowCompletionOr<void> EnterObjectEnvironment::execute_impl(Bytecode::Interpret
auto& old_environment = vm.running_execution_context().lexical_environment; auto& old_environment = vm.running_execution_context().lexical_environment;
interpreter.saved_lexical_environment_stack().append(old_environment); interpreter.saved_lexical_environment_stack().append(old_environment);
auto object = TRY(interpreter.accumulator().to_object(vm)); auto object = TRY(interpreter.accumulator().to_object(vm));
vm.running_execution_context().lexical_environment = new_object_environment(*object, true, old_environment); vm.running_execution_context().lexical_environment = new_object_environment(object, true, old_environment);
return {}; return {};
} }
@ -492,7 +492,7 @@ ThrowCompletionOr<void> SetVariable::execute_impl(Bytecode::Interpreter& interpr
ThrowCompletionOr<void> GetById::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> GetById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.accumulator().to_object(vm)); auto object = TRY(interpreter.accumulator().to_object(vm));
interpreter.accumulator() = TRY(object->get(interpreter.current_executable().get_identifier(m_property))); interpreter.accumulator() = TRY(object->get(interpreter.current_executable().get_identifier(m_property)));
return {}; return {};
} }
@ -500,7 +500,7 @@ ThrowCompletionOr<void> GetById::execute_impl(Bytecode::Interpreter& interpreter
ThrowCompletionOr<void> PutById::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> PutById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.reg(m_base).to_object(vm)); auto object = TRY(interpreter.reg(m_base).to_object(vm));
PropertyKey name = interpreter.current_executable().get_identifier(m_property); PropertyKey name = interpreter.current_executable().get_identifier(m_property);
auto value = interpreter.accumulator(); auto value = interpreter.accumulator();
return put_by_property_key(object, value, name, interpreter, m_kind); return put_by_property_key(object, value, name, interpreter, m_kind);
@ -509,7 +509,7 @@ ThrowCompletionOr<void> PutById::execute_impl(Bytecode::Interpreter& interpreter
ThrowCompletionOr<void> DeleteById::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> DeleteById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.accumulator().to_object(vm)); auto object = TRY(interpreter.accumulator().to_object(vm));
auto const& identifier = interpreter.current_executable().get_identifier(m_property); auto const& identifier = interpreter.current_executable().get_identifier(m_property);
bool strict = vm.in_strict_mode(); bool strict = vm.in_strict_mode();
auto reference = Reference { object, identifier, {}, strict }; auto reference = Reference { object, identifier, {}, strict };
@ -854,7 +854,7 @@ void Yield::replace_references_impl(BasicBlock const& from, BasicBlock const& to
ThrowCompletionOr<void> GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.reg(m_base).to_object(vm)); auto object = TRY(interpreter.reg(m_base).to_object(vm));
auto property_key = TRY(interpreter.accumulator().to_property_key(vm)); auto property_key = TRY(interpreter.accumulator().to_property_key(vm));
@ -865,7 +865,7 @@ ThrowCompletionOr<void> GetByValue::execute_impl(Bytecode::Interpreter& interpre
ThrowCompletionOr<void> PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.reg(m_base).to_object(vm)); auto object = TRY(interpreter.reg(m_base).to_object(vm));
auto property_key = TRY(interpreter.reg(m_property).to_property_key(vm)); auto property_key = TRY(interpreter.reg(m_property).to_property_key(vm));
return put_by_property_key(object, interpreter.accumulator(), property_key, interpreter, m_kind); return put_by_property_key(object, interpreter.accumulator(), property_key, interpreter, m_kind);
@ -874,7 +874,7 @@ ThrowCompletionOr<void> PutByValue::execute_impl(Bytecode::Interpreter& interpre
ThrowCompletionOr<void> DeleteByValue::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> DeleteByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.reg(m_base).to_object(vm)); auto object = TRY(interpreter.reg(m_base).to_object(vm));
auto property_key = TRY(interpreter.accumulator().to_property_key(vm)); auto property_key = TRY(interpreter.accumulator().to_property_key(vm));
bool strict = vm.in_strict_mode(); bool strict = vm.in_strict_mode();
auto reference = Reference { object, property_key, {}, strict }; auto reference = Reference { object, property_key, {}, strict };
@ -917,14 +917,14 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
// Invariant 3 effectively allows the implementation to ignore newly added keys, and we do so (similar to other implementations). // Invariant 3 effectively allows the implementation to ignore newly added keys, and we do so (similar to other implementations).
// Invariants 1 and 6 through 9 are implemented in `enumerable_own_property_names`, which implements the EnumerableOwnPropertyNames AO. // Invariants 1 and 6 through 9 are implemented in `enumerable_own_property_names`, which implements the EnumerableOwnPropertyNames AO.
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* object = TRY(interpreter.accumulator().to_object(vm)); auto object = TRY(interpreter.accumulator().to_object(vm));
// Note: While the spec doesn't explicitly require these to be ordered, it says that the values should be retrieved via OwnPropertyKeys, // Note: While the spec doesn't explicitly require these to be ordered, it says that the values should be retrieved via OwnPropertyKeys,
// so we just keep the order consistent anyway. // so we just keep the order consistent anyway.
OrderedHashTable<PropertyKey> properties; OrderedHashTable<PropertyKey> properties;
HashTable<Object*> seen_objects; HashTable<NonnullGCPtr<Object>> seen_objects;
// Collect all keys immediately (invariant no. 5) // Collect all keys immediately (invariant no. 5)
for (auto* object_to_check = object; object_to_check && !seen_objects.contains(object_to_check); object_to_check = TRY(object_to_check->internal_get_prototype_of())) { for (auto object_to_check = GCPtr { object.ptr() }; object_to_check && !seen_objects.contains(*object_to_check); object_to_check = TRY(object_to_check->internal_get_prototype_of())) {
seen_objects.set(object_to_check); seen_objects.set(*object_to_check);
for (auto& key : TRY(object_to_check->enumerable_own_property_names(Object::PropertyKind::Key))) { for (auto& key : TRY(object_to_check->enumerable_own_property_names(Object::PropertyKind::Key))) {
properties.set(TRY(PropertyKey::from_value(vm, key))); properties.set(TRY(PropertyKey::from_value(vm, key)));
} }
@ -981,8 +981,8 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_object = TRY(interpreter.accumulator().to_object(vm)); auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
auto iterator = object_to_iterator(vm, *iterator_object); auto iterator = object_to_iterator(vm, iterator_object);
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!) // FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} })); TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} }));
@ -992,8 +992,8 @@ ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& inter
ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_object = TRY(interpreter.accumulator().to_object(vm)); auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
auto iterator = object_to_iterator(vm, *iterator_object); auto iterator = object_to_iterator(vm, iterator_object);
interpreter.accumulator() = TRY(iterator_next(vm, iterator)); interpreter.accumulator() = TRY(iterator_next(vm, iterator));
return {}; return {};
@ -1002,9 +1002,9 @@ ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interp
ThrowCompletionOr<void> IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> IteratorResultDone::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_result = TRY(interpreter.accumulator().to_object(vm)); auto iterator_result = TRY(interpreter.accumulator().to_object(vm));
auto complete = TRY(iterator_complete(vm, *iterator_result)); auto complete = TRY(iterator_complete(vm, iterator_result));
interpreter.accumulator() = Value(complete); interpreter.accumulator() = Value(complete);
return {}; return {};
} }
@ -1012,9 +1012,9 @@ ThrowCompletionOr<void> IteratorResultDone::execute_impl(Bytecode::Interpreter&
ThrowCompletionOr<void> IteratorResultValue::execute_impl(Bytecode::Interpreter& interpreter) const ThrowCompletionOr<void> IteratorResultValue::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
auto& vm = interpreter.vm(); auto& vm = interpreter.vm();
auto* iterator_result = TRY(interpreter.accumulator().to_object(vm)); auto iterator_result = TRY(interpreter.accumulator().to_object(vm));
interpreter.accumulator() = TRY(iterator_value(vm, *iterator_result)); interpreter.accumulator() = TRY(iterator_value(vm, iterator_result));
return {}; return {};
} }

View file

@ -236,10 +236,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
// 6. NOTE: items is not an Iterable so assume it is an array-like object. // 6. NOTE: items is not an Iterable so assume it is an array-like object.
// 7. Let arrayLike be ! ToObject(items). // 7. Let arrayLike be ! ToObject(items).
auto* array_like = MUST(items.to_object(vm)); auto array_like = MUST(items.to_object(vm));
// 8. Let len be ? LengthOfArrayLike(arrayLike). // 8. Let len be ? LengthOfArrayLike(arrayLike).
auto length = TRY(length_of_array_like(vm, *array_like)); auto length = TRY(length_of_array_like(vm, array_like));
GCPtr<Object> array; GCPtr<Object> array;

View file

@ -26,7 +26,7 @@
namespace JS { namespace JS {
static HashTable<Object*> s_array_join_seen_objects; static HashTable<NonnullGCPtr<Object>> s_array_join_seen_objects;
ArrayPrototype::ArrayPrototype(Realm& realm) ArrayPrototype::ArrayPrototype(Realm& realm)
: Array(realm.intrinsics().object_prototype()) : Array(realm.intrinsics().object_prototype())
@ -152,8 +152,8 @@ static ThrowCompletionOr<Object*> array_species_create(VM& vm, Object& original_
// 23.1.3.1 Array.prototype.at ( index ), https://tc39.es/ecma262/#sec-array.prototype.at // 23.1.3.1 Array.prototype.at ( index ), https://tc39.es/ecma262/#sec-array.prototype.at
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at) JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at)
{ {
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(vm)); auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(vm));
if (Value(relative_index).is_infinity()) if (Value(relative_index).is_infinity())
return js_undefined(); return js_undefined();
@ -172,9 +172,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::at)
// 23.1.3.2 Array.prototype.concat ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.concat // 23.1.3.2 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto* new_array = TRY(array_species_create(vm, *this_object, 0)); auto* new_array = TRY(array_species_create(vm, this_object, 0));
size_t n = 0; size_t n = 0;
@ -230,8 +230,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
// 23.1.3.4 Array.prototype.copyWithin ( target, start [ , end ] ), https://tc39.es/ecma262/#sec-array.prototype.copywithin // 23.1.3.4 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
auto relative_target = TRY(vm.argument(0).to_integer_or_infinity(vm)); auto relative_target = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -298,7 +298,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::entries)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
return ArrayIterator::create(realm, this_object, Object::PropertyKind::KeyAndValue); return ArrayIterator::create(realm, this_object, Object::PropertyKind::KeyAndValue);
} }
@ -310,10 +310,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -351,9 +351,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
// 23.1.3.7 Array.prototype.fill ( value [ , start [ , end ] ] ), https://tc39.es/ecma262/#sec-array.prototype.fill // 23.1.3.7 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
double relative_start = 0; double relative_start = 0;
double relative_end = length; double relative_end = length;
@ -396,17 +396,17 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, callback_function.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, callback_function.to_string_without_side_effects()));
// 4. Let A be ? ArraySpeciesCreate(O, 0). // 4. Let A be ? ArraySpeciesCreate(O, 0).
auto* array = TRY(array_species_create(vm, *object, 0)); auto* array = TRY(array_species_create(vm, object, 0));
// 5. Let k be 0. // 5. Let k be 0.
size_t k = 0; size_t k = 0;
@ -454,10 +454,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception. // 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function()) if (!predicate.is_function())
@ -493,10 +493,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception. // 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function()) if (!predicate.is_function())
@ -532,10 +532,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception. // 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function()) if (!predicate.is_function())
@ -571,10 +571,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(predicate) is false, throw a TypeError exception. // 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (!predicate.is_function()) if (!predicate.is_function())
@ -640,9 +640,9 @@ static ThrowCompletionOr<size_t> flatten_into_array(VM& vm, Object& new_array, O
// 23.1.3.13 Array.prototype.flat ( [ depth ] ), https://tc39.es/ecma262/#sec-array.prototype.flat // 23.1.3.13 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
double depth = 1; double depth = 1;
if (!vm.argument(0).is_undefined()) { if (!vm.argument(0).is_undefined()) {
@ -650,9 +650,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat)
depth = max(depth_num, 0.0); depth = max(depth_num, 0.0);
} }
auto* new_array = TRY(array_species_create(vm, *this_object, 0)); auto* new_array = TRY(array_species_create(vm, this_object, 0));
TRY(flatten_into_array(vm, *new_array, *this_object, length, 0, depth)); TRY(flatten_into_array(vm, *new_array, this_object, length, 0, depth));
return new_array; return new_array;
} }
@ -663,20 +663,20 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let sourceLen be ? LengthOfArrayLike(O). // 2. Let sourceLen be ? LengthOfArrayLike(O).
auto source_length = TRY(length_of_array_like(vm, *object)); auto source_length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(mapperFunction) is false, throw a TypeError exception. // 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
if (!mapper_function.is_function()) if (!mapper_function.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, mapper_function.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, mapper_function.to_string_without_side_effects()));
// 4. Let A be ? ArraySpeciesCreate(O, 0). // 4. Let A be ? ArraySpeciesCreate(O, 0).
auto* array = TRY(array_species_create(vm, *object, 0)); auto* array = TRY(array_species_create(vm, object, 0));
// 5. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg). // 5. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg).
TRY(flatten_into_array(vm, *array, *object, source_length, 0, 1, &mapper_function.as_function(), this_arg)); TRY(flatten_into_array(vm, *array, object, source_length, 0, 1, &mapper_function.as_function(), this_arg));
// 6. Return A. // 6. Return A.
return array; return array;
@ -689,10 +689,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -760,10 +760,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group)
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* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -816,10 +816,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_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* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -883,8 +883,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_to_map)
// 23.1.3.16 Array.prototype.includes ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-array.prototype.includes // 23.1.3.16 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
if (length == 0) if (length == 0)
return Value(false); return Value(false);
u64 from_index = 0; u64 from_index = 0;
@ -918,10 +918,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If len is 0, return -1𝔽. // 3. If len is 0, return -1𝔽.
if (length == 0) if (length == 0)
@ -986,7 +986,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
// 23.1.3.18 Array.prototype.join ( separator ), https://tc39.es/ecma262/#sec-array.prototype.join // 23.1.3.18 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
// 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".
@ -998,7 +998,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
s_array_join_seen_objects.remove(this_object); s_array_join_seen_objects.remove(this_object);
}; };
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
DeprecatedString separator = ","; DeprecatedString separator = ",";
if (!vm.argument(0).is_undefined()) if (!vm.argument(0).is_undefined())
separator = TRY(vm.argument(0).to_deprecated_string(vm)); separator = TRY(vm.argument(0).to_deprecated_string(vm));
@ -1021,7 +1021,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
return ArrayIterator::create(realm, this_object, Object::PropertyKind::Key); return ArrayIterator::create(realm, this_object, Object::PropertyKind::Key);
} }
@ -1033,10 +1033,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If len is 0, return -1𝔽. // 3. If len is 0, return -1𝔽.
if (length == 0) if (length == 0)
@ -1101,17 +1101,17 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, callback_function.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, callback_function.to_string_without_side_effects()));
// 4. Let A be ? ArraySpeciesCreate(O, len). // 4. Let A be ? ArraySpeciesCreate(O, len).
auto* array = TRY(array_species_create(vm, *object, length)); auto* array = TRY(array_species_create(vm, object, length));
// 5. Let k be 0. // 5. Let k be 0.
// 6. Repeat, while k < len, // 6. Repeat, while k < len,
@ -1144,8 +1144,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
// 23.1.3.22 Array.prototype.pop ( ), https://tc39.es/ecma262/#sec-array.prototype.pop // 23.1.3.22 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
if (length == 0) { if (length == 0) {
TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes)); TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
return js_undefined(); return js_undefined();
@ -1160,8 +1160,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
// 23.1.3.23 Array.prototype.push ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.push // 23.1.3.23 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, 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;
if (new_length > MAX_ARRAY_LIKE_INDEX) if (new_length > MAX_ARRAY_LIKE_INDEX)
@ -1180,10 +1180,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -1262,10 +1262,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -1340,8 +1340,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
// 23.1.3.26 Array.prototype.reverse ( ), https://tc39.es/ecma262/#sec-array.prototype.reverse // 23.1.3.26 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
auto middle = length / 2; auto middle = length / 2;
for (size_t lower = 0; lower < middle; ++lower) { for (size_t lower = 0; lower < middle; ++lower) {
@ -1375,8 +1375,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
// 23.1.3.27 Array.prototype.shift ( ), https://tc39.es/ecma262/#sec-array.prototype.shift // 23.1.3.27 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
if (length == 0) { if (length == 0) {
TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes)); TRY(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
return js_undefined(); return js_undefined();
@ -1402,9 +1402,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
// 23.1.3.28 Array.prototype.slice ( start, end ), https://tc39.es/ecma262/#sec-array.prototype.slice // 23.1.3.28 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto initial_length = TRY(length_of_array_like(vm, *this_object)); auto initial_length = TRY(length_of_array_like(vm, this_object));
auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm)); auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -1435,7 +1435,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
auto count = max(final - actual_start, 0.0); auto count = max(final - actual_start, 0.0);
auto* new_array = TRY(array_species_create(vm, *this_object, count)); auto* new_array = TRY(array_species_create(vm, this_object, count));
size_t index = 0; size_t index = 0;
size_t k = actual_start; size_t k = actual_start;
@ -1462,10 +1462,10 @@ 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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. If IsCallable(callbackfn) is false, throw a TypeError exception. // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
if (!callback_function.is_function()) if (!callback_function.is_function())
@ -1565,10 +1565,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, comparefn.to_string_without_side_effects())); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, comparefn.to_string_without_side_effects()));
// 2. Let obj be ? ToObject(this value). // 2. Let obj be ? ToObject(this value).
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 3. Let len be ? LengthOfArrayLike(obj). // 3. Let len be ? LengthOfArrayLike(obj).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 4. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called: // 4. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
Function<ThrowCompletionOr<double>(Value, Value)> sort_compare = [&](auto x, auto y) -> ThrowCompletionOr<double> { Function<ThrowCompletionOr<double>(Value, Value)> sort_compare = [&](auto x, auto y) -> ThrowCompletionOr<double> {
@ -1577,7 +1577,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
}; };
// 5. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, skip-holes). // 5. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, skip-holes).
auto sorted_list = TRY(sort_indexed_properties(vm, *object, length, sort_compare, Holes::SkipHoles)); auto sorted_list = TRY(sort_indexed_properties(vm, object, length, sort_compare, Holes::SkipHoles));
// 6. Let itemCount be the number of elements in sortedList. // 6. Let itemCount be the number of elements in sortedList.
auto item_count = sorted_list.size(); auto item_count = sorted_list.size();
@ -1607,9 +1607,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
// 23.1.3.31 Array.prototype.splice ( start, deleteCount, ...items ), https://tc39.es/ecma262/#sec-array.prototype.splice // 23.1.3.31 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto initial_length = TRY(length_of_array_like(vm, *this_object)); auto initial_length = TRY(length_of_array_like(vm, this_object));
auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm)); auto relative_start = TRY(vm.argument(0).to_integer_or_infinity(vm));
@ -1640,7 +1640,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
if (new_length > MAX_ARRAY_LIKE_INDEX) if (new_length > MAX_ARRAY_LIKE_INDEX)
return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize); return vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
auto* removed_elements = TRY(array_species_create(vm, *this_object, actual_delete_count)); auto* removed_elements = TRY(array_species_create(vm, this_object, actual_delete_count));
for (u64 i = 0; i < actual_delete_count; ++i) { for (u64 i = 0; i < actual_delete_count; ++i) {
auto from = actual_start + i; auto from = actual_start + i;
@ -1699,7 +1699,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
auto options = vm.argument(1); auto options = vm.argument(1);
// 1. Let array be ? ToObject(this value). // 1. Let array be ? ToObject(this value).
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (s_array_join_seen_objects.contains(this_object)) if (s_array_join_seen_objects.contains(this_object))
return PrimitiveString::create(vm, String {}); return PrimitiveString::create(vm, String {});
@ -1709,7 +1709,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
}; };
// 2. Let len be ? ToLength(? Get(array, "length")). // 2. Let len be ? ToLength(? Get(array, "length")).
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, this_object));
// 3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", "). // 3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
constexpr auto separator = ","sv; constexpr auto separator = ","sv;
@ -1752,10 +1752,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_reversed)
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. Let A be ? ArrayCreate(𝔽(len)). // 3. Let A be ? ArrayCreate(𝔽(len)).
auto array = TRY(Array::create(realm, length)); auto array = TRY(Array::create(realm, length));
@ -1794,10 +1794,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn);
// 2. Let O be ? ToObject(this value). // 2. Let O be ? ToObject(this value).
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 3. Let len be ? LengthOfArrayLike(O). // 3. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 4. Let A be ? ArrayCreate(𝔽(len)). // 4. Let A be ? ArrayCreate(𝔽(len)).
auto array = TRY(Array::create(realm, length)); auto array = TRY(Array::create(realm, length));
@ -1809,7 +1809,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_sorted)
}; };
// 6. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, read-through-holes). // 6. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, read-through-holes).
auto sorted_list = TRY(sort_indexed_properties(vm, *object, length, sort_compare, Holes::ReadThroughHoles)); auto sorted_list = TRY(sort_indexed_properties(vm, object, length, sort_compare, Holes::ReadThroughHoles));
// 7. Let j be 0. // 7. Let j be 0.
// 8. Repeat, while j < len, // 8. Repeat, while j < len,
@ -1833,10 +1833,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_spliced)
auto skip_count = vm.argument(1); auto skip_count = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. Let relativeStart be ? ToIntegerOrInfinity(start). // 3. Let relativeStart be ? ToIntegerOrInfinity(start).
auto relative_start = TRY(start.to_integer_or_infinity(vm)); auto relative_start = TRY(start.to_integer_or_infinity(vm));
@ -1961,7 +1961,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
// 1. Let array be ? ToObject(this value). // 1. Let array be ? ToObject(this value).
auto* array = TRY(vm.this_value().to_object(vm)); auto array = TRY(vm.this_value().to_object(vm));
// 2. Let func be ? Get(array, "join"). // 2. Let func be ? Get(array, "join").
auto func = TRY(array->get(vm.names.join)); auto func = TRY(array->get(vm.names.join));
@ -1977,8 +1977,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
// 23.1.3.37 Array.prototype.unshift ( ...items ), https://tc39.es/ecma262/#sec-array.prototype.unshift // 23.1.3.37 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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
auto length = TRY(length_of_array_like(vm, *this_object)); auto length = TRY(length_of_array_like(vm, 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;
if (arg_count > 0) { if (arg_count > 0) {
@ -2011,7 +2011,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::values)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
return ArrayIterator::create(realm, this_object, Object::PropertyKind::Value); return ArrayIterator::create(realm, this_object, Object::PropertyKind::Value);
} }
@ -2025,10 +2025,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::with)
auto value = vm.argument(1); auto value = vm.argument(1);
// 1. Let O be ? ToObject(this value). // 1. Let O be ? ToObject(this value).
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 2. Let len be ? LengthOfArrayLike(O). // 2. Let len be ? LengthOfArrayLike(O).
auto length = TRY(length_of_array_like(vm, *object)); auto length = TRY(length_of_array_like(vm, object));
// 3. Let relativeIndex be ? ToIntegerOrInfinity(index). // 3. Let relativeIndex be ? ToIntegerOrInfinity(index).
auto relative_index = TRY(index.to_integer_or_infinity(vm)); auto relative_index = TRY(index.to_integer_or_infinity(vm));

View file

@ -27,8 +27,8 @@ ThrowCompletionOr<NonnullGCPtr<GeneratorObject>> GeneratorObject::create(Realm&
} else { } else {
generating_function_prototype = TRY(generating_function->get(vm.names.prototype)); generating_function_prototype = TRY(generating_function->get(vm.names.prototype));
} }
auto* generating_function_prototype_object = TRY(generating_function_prototype.to_object(vm)); auto generating_function_prototype_object = TRY(generating_function_prototype.to_object(vm));
auto object = MUST_OR_THROW_OOM(realm.heap().allocate<GeneratorObject>(realm, realm, *generating_function_prototype_object, move(execution_context))); auto object = MUST_OR_THROW_OOM(realm.heap().allocate<GeneratorObject>(realm, realm, generating_function_prototype_object, move(execution_context)));
object->m_generating_function = generating_function; object->m_generating_function = generating_function;
object->m_frame = move(frame); object->m_frame = move(frame);
object->m_previous_value = initial_value; object->m_previous_value = initial_value;

View file

@ -602,7 +602,7 @@ ThrowCompletionOr<Object*> coerce_options_to_object(VM& vm, Value options)
} }
// 2. Return ? ToObject(options). // 2. Return ? ToObject(options).
return TRY(options.to_object(vm)); return TRY(options.to_object(vm)).ptr();
} }
// NOTE: 9.2.13 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal. // NOTE: 9.2.13 GetOption has been removed and is being pulled in from ECMA-262 in the Temporal proposal.

View file

@ -73,7 +73,7 @@ ThrowCompletionOr<Object*> to_date_time_options(VM& vm, Value options_value, Opt
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
// 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options). // 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
Object* options = nullptr; GCPtr<Object> options;
if (!options_value.is_undefined()) if (!options_value.is_undefined())
options = TRY(options_value.to_object(vm)); options = TRY(options_value.to_object(vm));
@ -150,7 +150,7 @@ ThrowCompletionOr<Object*> to_date_time_options(VM& vm, Value options_value, Opt
} }
// 13. Return options. // 13. Return options.
return options; return options.ptr();
} }
// 11.5.2 DateTimeStyleFormat ( dateStyle, timeStyle, styles ), https://tc39.es/ecma402/#sec-date-time-style-format // 11.5.2 DateTimeStyleFormat ( dateStyle, timeStyle, styles ), https://tc39.es/ecma402/#sec-date-time-style-format

View file

@ -432,7 +432,7 @@ ThrowCompletionOr<void> Object::copy_data_properties(VM& vm, Value source, HashT
if (source.is_nullish()) if (source.is_nullish())
return {}; return {};
auto* from_object = MUST(source.to_object(vm)); auto from_object = MUST(source.to_object(vm));
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 = MUST(PropertyKey::from_value(vm, next_key_value)); auto next_key = MUST(PropertyKey::from_value(vm, next_key_value));
@ -1201,7 +1201,7 @@ ThrowCompletionOr<Object*> Object::define_properties(Value properties)
auto& vm = this->vm(); auto& vm = this->vm();
// 1. Let props be ? ToObject(Properties). // 1. Let props be ? ToObject(Properties).
auto* props = TRY(properties.to_object(vm)); auto props = TRY(properties.to_object(vm));
// 2. Let keys be ? props.[[OwnPropertyKeys]](). // 2. Let keys be ? props.[[OwnPropertyKeys]]().
auto keys = TRY(props->internal_own_property_keys()); auto keys = TRY(props->internal_own_property_keys());

View file

@ -76,7 +76,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ObjectConstructor::construct(FunctionObj
auto value = vm.argument(0); auto value = vm.argument(0);
if (value.is_nullish()) if (value.is_nullish())
return Object::create(realm, realm.intrinsics().object_prototype()); return Object::create(realm, realm.intrinsics().object_prototype());
return *TRY(value.to_object(vm)); return TRY(value.to_object(vm));
} }
enum class GetOwnPropertyKeysType { enum class GetOwnPropertyKeysType {
@ -88,7 +88,7 @@ enum class GetOwnPropertyKeysType {
static ThrowCompletionOr<MarkedVector<Value>> get_own_property_keys(VM& vm, Value value, GetOwnPropertyKeysType type) static ThrowCompletionOr<MarkedVector<Value>> get_own_property_keys(VM& vm, Value value, GetOwnPropertyKeysType type)
{ {
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = TRY(value.to_object(vm)); auto object = TRY(value.to_object(vm));
// 2. Let keys be ? obj.[[OwnPropertyKeys]](). // 2. Let keys be ? obj.[[OwnPropertyKeys]]().
auto keys = TRY(object->internal_own_property_keys()); auto keys = TRY(object->internal_own_property_keys());
@ -131,7 +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 = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
// 2. Return ? obj.[[GetPrototypeOf]](). // 2. Return ? obj.[[GetPrototypeOf]]().
return TRY(object->internal_get_prototype_of()); return TRY(object->internal_get_prototype_of());
@ -258,7 +258,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 = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
auto key = TRY(vm.argument(1).to_property_key(vm)); auto key = TRY(vm.argument(1).to_property_key(vm));
auto descriptor = TRY(object->internal_get_own_property(key)); auto descriptor = TRY(object->internal_get_own_property(key));
return from_property_descriptor(vm, descriptor); return from_property_descriptor(vm, descriptor);
@ -270,7 +270,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
// 1. Let obj be ? ToObject(O). // 1. Let obj be ? ToObject(O).
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
// 2. Let ownKeys be ? obj.[[OwnPropertyKeys]](). // 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
auto own_keys = TRY(object->internal_own_property_keys()); auto own_keys = TRY(object->internal_own_property_keys());
@ -333,7 +333,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Key)); auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Key));
return Array::create_from(realm, name_list); return Array::create_from(realm, name_list);
} }
@ -343,7 +343,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Value)); auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::Value));
return Array::create_from(realm, name_list); return Array::create_from(realm, name_list);
} }
@ -353,7 +353,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* object = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::KeyAndValue)); auto name_list = TRY(object->enumerable_own_property_names(PropertyKind::KeyAndValue));
return Array::create_from(realm, name_list); return Array::create_from(realm, name_list);
} }
@ -387,7 +387,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 = TRY(vm.argument(0).to_object(vm)); auto object = TRY(vm.argument(0).to_object(vm));
// 2. Let key be ? ToPropertyKey(P). // 2. Let key be ? ToPropertyKey(P).
auto key = TRY(vm.argument(1).to_property_key(vm)); auto key = TRY(vm.argument(1).to_property_key(vm));
@ -400,7 +400,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 = TRY(vm.argument(0).to_object(vm)); auto to = TRY(vm.argument(0).to_object(vm));
// 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)
@ -415,7 +415,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
continue; continue;
// i. Let from be ! ToObject(nextSource). // i. Let from be ! ToObject(nextSource).
auto* from = MUST(next_source.to_object(vm)); auto from = MUST(next_source.to_object(vm));
// ii. Let keys be ? from.[[OwnPropertyKeys]](). // ii. Let keys be ? from.[[OwnPropertyKeys]]().
auto keys = TRY(from->internal_own_property_keys()); auto keys = TRY(from->internal_own_property_keys());

View file

@ -61,7 +61,7 @@ ThrowCompletionOr<bool> ObjectPrototype::internal_set_prototype_of(Object* proto
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property) JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
{ {
auto property_key = TRY(vm.argument(0).to_property_key(vm)); auto property_key = TRY(vm.argument(0).to_property_key(vm));
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
return Value(TRY(this_object->has_own_property(property_key))); return Value(TRY(this_object->has_own_property(property_key)));
} }
@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
return MUST_OR_THROW_OOM(PrimitiveString::create(vm, "[object Null]"sv)); return MUST_OR_THROW_OOM(PrimitiveString::create(vm, "[object Null]"sv));
// 3. Let O be ! ToObject(this value). // 3. Let O be ! ToObject(this value).
auto* object = MUST(this_value.to_object(vm)); auto object = MUST(this_value.to_object(vm));
// 4. Let isArray be ? IsArray(O). // 4. Let isArray be ? IsArray(O).
auto is_array = TRY(Value(object).is_array(vm)); auto is_array = TRY(Value(object).is_array(vm));
@ -96,22 +96,22 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
else if (object->is_function()) else if (object->is_function())
builtin_tag = "Function"; builtin_tag = "Function";
// 8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error". // 8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
else if (is<Error>(object)) else if (is<Error>(*object))
builtin_tag = "Error"; builtin_tag = "Error";
// 9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean". // 9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
else if (is<BooleanObject>(object)) else if (is<BooleanObject>(*object))
builtin_tag = "Boolean"; builtin_tag = "Boolean";
// 10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number". // 10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".
else if (is<NumberObject>(object)) else if (is<NumberObject>(*object))
builtin_tag = "Number"; builtin_tag = "Number";
// 11. Else if O has a [[StringData]] internal slot, let builtinTag be "String". // 11. Else if O has a [[StringData]] internal slot, let builtinTag be "String".
else if (is<StringObject>(object)) else if (is<StringObject>(*object))
builtin_tag = "String"; builtin_tag = "String";
// 12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date". // 12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".
else if (is<Date>(object)) else if (is<Date>(*object))
builtin_tag = "Date"; builtin_tag = "Date";
// 13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp". // 13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
else if (is<RegExpObject>(object)) else if (is<RegExpObject>(*object))
builtin_tag = "RegExp"; builtin_tag = "RegExp";
// 14. Else, let builtinTag be "Object". // 14. Else, let builtinTag be "Object".
else else
@ -152,7 +152,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::property_is_enumerable)
// 1. Let P be ? ToPropertyKey(V). // 1. Let P be ? ToPropertyKey(V).
auto property_key = TRY(vm.argument(0).to_property_key(vm)); auto property_key = TRY(vm.argument(0).to_property_key(vm));
// 2. Let O be ? ToObject(this value). // 2. Let O be ? ToObject(this value).
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
// 3. Let desc be ? O.[[GetOwnProperty]](P). // 3. Let desc be ? O.[[GetOwnProperty]](P).
auto property_descriptor = TRY(this_object->internal_get_own_property(property_key)); auto property_descriptor = TRY(this_object->internal_get_own_property(property_key));
// 4. If desc is undefined, return false. // 4. If desc is undefined, return false.
@ -169,7 +169,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 = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
for (;;) { for (;;) {
object = TRY(object->internal_get_prototype_of()); object = TRY(object->internal_get_prototype_of());
@ -183,7 +183,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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
auto getter = vm.argument(1); auto getter = vm.argument(1);
if (!getter.is_function()) if (!getter.is_function())
@ -201,7 +201,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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
auto setter = vm.argument(1); auto setter = vm.argument(1);
if (!setter.is_function()) if (!setter.is_function())
@ -219,7 +219,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 = TRY(vm.this_value().to_object(vm)); auto object = GCPtr { TRY(vm.this_value().to_object(vm)) };
auto key = TRY(vm.argument(0).to_property_key(vm)); auto key = TRY(vm.argument(0).to_property_key(vm));
@ -239,7 +239,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 = TRY(vm.this_value().to_object(vm)); auto object = GCPtr { TRY(vm.this_value().to_object(vm)) };
auto key = TRY(vm.argument(0).to_property_key(vm)); auto key = TRY(vm.argument(0).to_property_key(vm));
@ -259,7 +259,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 = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
return TRY(object->internal_get_prototype_of()); return TRY(object->internal_get_prototype_of());
} }

View file

@ -314,7 +314,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> PromiseConstructor::construct(FunctionOb
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
{ {
// 1. Let C be the this value. // 1. Let C be the this value.
auto* constructor = TRY(vm.this_value().to_object(vm)); auto constructor = TRY(vm.this_value().to_object(vm));
// 2. Let promiseCapability be ? NewPromiseCapability(C). // 2. Let promiseCapability be ? NewPromiseCapability(C).
auto promise_capability = TRY(new_promise_capability(vm, constructor)); auto promise_capability = TRY(new_promise_capability(vm, constructor));
@ -348,7 +348,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
{ {
// 1. Let C be the this value. // 1. Let C be the this value.
auto* constructor = TRY(vm.this_value().to_object(vm)); auto constructor = TRY(vm.this_value().to_object(vm));
// 2. Let promiseCapability be ? NewPromiseCapability(C). // 2. Let promiseCapability be ? NewPromiseCapability(C).
auto promise_capability = TRY(new_promise_capability(vm, constructor)); auto promise_capability = TRY(new_promise_capability(vm, constructor));
@ -382,7 +382,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
{ {
// 1. Let C be the this value. // 1. Let C be the this value.
auto* constructor = TRY(vm.this_value().to_object(vm)); auto constructor = TRY(vm.this_value().to_object(vm));
// 2. Let promiseCapability be ? NewPromiseCapability(C). // 2. Let promiseCapability be ? NewPromiseCapability(C).
auto promise_capability = TRY(new_promise_capability(vm, constructor)); auto promise_capability = TRY(new_promise_capability(vm, constructor));
@ -416,7 +416,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race) JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
{ {
// 1. Let C be the this value. // 1. Let C be the this value.
auto* constructor = TRY(vm.this_value().to_object(vm)); auto constructor = TRY(vm.this_value().to_object(vm));
// 2. Let promiseCapability be ? NewPromiseCapability(C). // 2. Let promiseCapability be ? NewPromiseCapability(C).
auto promise_capability = TRY(new_promise_capability(vm, constructor)); auto promise_capability = TRY(new_promise_capability(vm, constructor));
@ -452,7 +452,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
auto reason = vm.argument(0); auto reason = vm.argument(0);
// 1. Let C be the this value. // 1. Let C be the this value.
auto* constructor = TRY(vm.this_value().to_object(vm)); auto constructor = TRY(vm.this_value().to_object(vm));
// 2. Let promiseCapability be ? NewPromiseCapability(C). // 2. Let promiseCapability be ? NewPromiseCapability(C).
auto promise_capability = TRY(new_promise_capability(vm, constructor)); auto promise_capability = TRY(new_promise_capability(vm, constructor));

View file

@ -40,10 +40,10 @@ public:
// Use typed_this_object() when the spec coerces |this| value to an object. // Use typed_this_object() when the spec coerces |this| value to an object.
static ThrowCompletionOr<ObjectType*> typed_this_object(VM& vm) static ThrowCompletionOr<ObjectType*> typed_this_object(VM& vm)
{ {
auto* this_object = TRY(vm.this_value().to_object(vm)); auto this_object = TRY(vm.this_value().to_object(vm));
if (!is<ObjectType>(this_object)) if (!is<ObjectType>(*this_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name()); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name());
return static_cast<ObjectType*>(this_object); return static_cast<ObjectType*>(this_object.ptr());
} }
// Use typed_this_value() when the spec does not coerce |this| value to an object. // Use typed_this_value() when the spec does not coerce |this| value to an object.

View file

@ -40,7 +40,7 @@ ThrowCompletionOr<void> Reference::put_value(VM& vm, Value value)
// 5. If IsPropertyReference(V) is true, then // 5. If IsPropertyReference(V) is true, then
if (is_property_reference()) { if (is_property_reference()) {
// a. Let baseObj be ? ToObject(V.[[Base]]). // a. Let baseObj be ? ToObject(V.[[Base]]).
auto* base_obj = TRY(m_base_value.to_object(vm)); auto base_obj = TRY(m_base_value.to_object(vm));
// b. If IsPrivateReference(V) is true, then // b. If IsPrivateReference(V) is true, then
if (is_private_reference()) { if (is_private_reference()) {
@ -105,7 +105,7 @@ ThrowCompletionOr<Value> Reference::get_value(VM& vm) const
// as things currently stand this does the "wrong thing" but // as things currently stand this does the "wrong thing" but
// the error is unobservable // the error is unobservable
auto* base_obj = TRY(m_base_value.to_object(vm)); auto base_obj = TRY(m_base_value.to_object(vm));
// i. Return ? PrivateGet(baseObj, V.[[ReferencedName]]). // i. Return ? PrivateGet(baseObj, V.[[ReferencedName]]).
return base_obj->private_get(m_private_name); return base_obj->private_get(m_private_name);
@ -171,7 +171,7 @@ ThrowCompletionOr<bool> Reference::delete_(VM& vm)
return vm.throw_completion<ReferenceError>(ErrorType::UnsupportedDeleteSuperProperty); return vm.throw_completion<ReferenceError>(ErrorType::UnsupportedDeleteSuperProperty);
// c. Let baseObj be ! ToObject(ref.[[Base]]). // c. Let baseObj be ! ToObject(ref.[[Base]]).
auto* base_obj = MUST(m_base_value.to_object(vm)); auto base_obj = MUST(m_base_value.to_object(vm));
// d. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]). // d. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]).
bool delete_status = TRY(base_obj->internal_delete(m_name)); bool delete_status = TRY(base_obj->internal_delete(m_name));

View file

@ -51,7 +51,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next)
return create_iterator_result_object(vm, match, false); return create_iterator_result_object(vm, match, false);
} }
auto* match_object = TRY(match.to_object(vm)); auto match_object = TRY(match.to_object(vm));
auto match_string_value = TRY(match_object->get(0)); auto match_string_value = TRY(match_object->get(0));
auto match_string = TRY(match_string_value.to_deprecated_string(vm)); auto match_string = TRY(match_string_value.to_deprecated_string(vm));
if (match_string.is_empty()) { if (match_string.is_empty()) {

View file

@ -148,13 +148,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::raw)
auto substitution_count = vm.argument_count() > 0 ? vm.argument_count() - 1 : 0; auto substitution_count = vm.argument_count() > 0 ? vm.argument_count() - 1 : 0;
// 2. Let cooked be ? ToObject(template). // 2. Let cooked be ? ToObject(template).
auto* cooked = TRY(template_.to_object(vm)); auto cooked = TRY(template_.to_object(vm));
// 3. Let literals be ? ToObject(? Get(cooked, "raw")). // 3. Let literals be ? ToObject(? Get(cooked, "raw")).
auto* literals = TRY(TRY(cooked->get(vm.names.raw)).to_object(vm)); auto literals = TRY(TRY(cooked->get(vm.names.raw)).to_object(vm));
// 4. Let literalCount be ? LengthOfArrayLike(literals). // 4. Let literalCount be ? LengthOfArrayLike(literals).
auto literal_count = TRY(length_of_array_like(vm, *literals)); auto literal_count = TRY(length_of_array_like(vm, literals));
// 5. If literalCount ≤ 0, return the empty String. // 5. If literalCount ≤ 0, return the empty String.
if (literal_count == 0) if (literal_count == 0)

View file

@ -175,12 +175,12 @@ ThrowCompletionOr<PlainDate*> calendar_date_add(VM& vm, Object& calendar, Value
auto added_date = TRY(call(vm, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined())); auto added_date = TRY(call(vm, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]). // 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
auto* added_date_object = TRY(added_date.to_object(vm)); auto added_date_object = TRY(added_date.to_object(vm));
if (!is<PlainDate>(added_date_object)) if (!is<PlainDate>(*added_date_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
// 7. Return addedDate. // 7. Return addedDate.
return static_cast<PlainDate*>(added_date_object); return static_cast<PlainDate*>(added_date_object.ptr());
} }
// 12.2.7 CalendarDateUntil ( calendar, one, two, options [ , dateUntil ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateuntil // 12.2.7 CalendarDateUntil ( calendar, one, two, options [ , dateUntil ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateuntil
@ -196,12 +196,12 @@ ThrowCompletionOr<Duration*> calendar_date_until(VM& vm, Object& calendar, Value
auto duration = TRY(call(vm, date_until ?: js_undefined(), &calendar, one, two, &options)); auto duration = TRY(call(vm, date_until ?: js_undefined(), &calendar, one, two, &options));
// 4. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]). // 4. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
auto* duration_object = TRY(duration.to_object(vm)); auto duration_object = TRY(duration.to_object(vm));
if (!is<Duration>(duration_object)) if (!is<Duration>(*duration_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.Duration"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.Duration");
// 5. Return duration. // 5. Return duration.
return static_cast<Duration*>(duration_object); return static_cast<Duration*>(duration_object.ptr());
} }
// 12.2.8 CalendarYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryear // 12.2.8 CalendarYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryear
@ -525,12 +525,12 @@ ThrowCompletionOr<PlainDate*> calendar_date_from_fields(VM& vm, Object& calendar
auto date = TRY(Value(&calendar).invoke(vm, vm.names.dateFromFields, &fields, options ?: js_undefined())); auto date = TRY(Value(&calendar).invoke(vm, vm.names.dateFromFields, &fields, options ?: js_undefined()));
// 3. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]). // 3. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
auto* date_object = TRY(date.to_object(vm)); auto date_object = TRY(date.to_object(vm));
if (!is<PlainDate>(date_object)) if (!is<PlainDate>(*date_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
// 4. Return date. // 4. Return date.
return static_cast<PlainDate*>(date_object); return static_cast<PlainDate*>(date_object.ptr());
} }
// 12.2.25 CalendarYearMonthFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields // 12.2.25 CalendarYearMonthFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields
@ -542,12 +542,12 @@ ThrowCompletionOr<PlainYearMonth*> calendar_year_month_from_fields(VM& vm, Objec
auto year_month = TRY(Value(&calendar).invoke(vm, vm.names.yearMonthFromFields, &fields, options ?: js_undefined())); auto year_month = TRY(Value(&calendar).invoke(vm, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
// 3. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]). // 3. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
auto* year_month_object = TRY(year_month.to_object(vm)); auto year_month_object = TRY(year_month.to_object(vm));
if (!is<PlainYearMonth>(year_month_object)) if (!is<PlainYearMonth>(*year_month_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainYearMonth");
// 4. Return yearMonth. // 4. Return yearMonth.
return static_cast<PlainYearMonth*>(year_month_object); return static_cast<PlainYearMonth*>(year_month_object.ptr());
} }
// 12.2.26 CalendarMonthDayFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthdayfromfields // 12.2.26 CalendarMonthDayFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthdayfromfields
@ -559,12 +559,12 @@ ThrowCompletionOr<PlainMonthDay*> calendar_month_day_from_fields(VM& vm, Object&
auto month_day = TRY(Value(&calendar).invoke(vm, vm.names.monthDayFromFields, &fields, options ?: js_undefined())); auto month_day = TRY(Value(&calendar).invoke(vm, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
// 3. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]). // 3. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]).
auto* month_day_object = TRY(month_day.to_object(vm)); auto month_day_object = TRY(month_day.to_object(vm));
if (!is<PlainMonthDay>(month_day_object)) if (!is<PlainMonthDay>(*month_day_object))
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "Temporal.PlainMonthDay");
// 4. Return monthDay. // 4. Return monthDay.
return static_cast<PlainMonthDay*>(month_day_object); return static_cast<PlainMonthDay*>(month_day_object.ptr());
} }
// 12.2.27 MaybeFormatCalendarAnnotation ( calendarObject, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-maybeformatcalendarannotation // 12.2.27 MaybeFormatCalendarAnnotation ( calendarObject, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-maybeformatcalendarannotation

View file

@ -598,16 +598,16 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::merge_fields)
auto* calendar = TRY(typed_this_object(vm)); auto* calendar = TRY(typed_this_object(vm));
// 3. Set fields to ? ToObject(fields). // 3. Set fields to ? ToObject(fields).
auto* fields = TRY(vm.argument(0).to_object(vm)); auto fields = TRY(vm.argument(0).to_object(vm));
// 4. Set additionalFields to ? ToObject(additionalFields). // 4. Set additionalFields to ? ToObject(additionalFields).
auto* additional_fields = TRY(vm.argument(1).to_object(vm)); auto additional_fields = TRY(vm.argument(1).to_object(vm));
// 5. Assert: calendar.[[Identifier]] is "iso8601". // 5. Assert: calendar.[[Identifier]] is "iso8601".
VERIFY(calendar->identifier() == "iso8601"sv); VERIFY(calendar->identifier() == "iso8601"sv);
// 6. Return ? DefaultMergeCalendarFields(fields, additionalFields). // 6. Return ? DefaultMergeCalendarFields(fields, additionalFields).
return TRY(default_merge_calendar_fields(vm, *fields, *additional_fields)); return TRY(default_merge_calendar_fields(vm, fields, additional_fields));
} }
// 12.4.24 Temporal.Calendar.prototype.toString ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tostring // 12.4.24 Temporal.Calendar.prototype.toString ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tostring

View file

@ -20,11 +20,11 @@ namespace JS {
ThrowCompletionOr<TypedArrayBase*> typed_array_from(VM& vm, Value typed_array_value) ThrowCompletionOr<TypedArrayBase*> typed_array_from(VM& vm, Value typed_array_value)
{ {
auto* this_object = TRY(typed_array_value.to_object(vm)); auto this_object = TRY(typed_array_value.to_object(vm));
if (!this_object->is_typed_array()) if (!this_object->is_typed_array())
return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "TypedArray"); return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, "TypedArray");
return static_cast<TypedArrayBase*>(this_object); return static_cast<TypedArrayBase*>(this_object.ptr());
} }
// 23.2.4.4 ValidateTypedArray ( O ), https://tc39.es/ecma262/#sec-validatetypedarray // 23.2.4.4 ValidateTypedArray ( O ), https://tc39.es/ecma262/#sec-validatetypedarray

View file

@ -133,10 +133,10 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
// 7. NOTE: source is not an Iterable so assume it is already an array-like object. // 7. NOTE: source is not an Iterable so assume it is already an array-like object.
// 8. Let arrayLike be ! ToObject(source). // 8. Let arrayLike be ! ToObject(source).
auto* array_like = MUST(source.to_object(vm)); auto array_like = MUST(source.to_object(vm));
// 9. Let len be ? LengthOfArrayLike(arrayLike). // 9. Let len be ? LengthOfArrayLike(arrayLike).
auto length = TRY(length_of_array_like(vm, *array_like)); auto length = TRY(length_of_array_like(vm, array_like));
// 10. Let targetObj be ? TypedArrayCreate(C, « 𝔽(len) »). // 10. Let targetObj be ? TypedArrayCreate(C, « 𝔽(len) »).
MarkedVector<Value> arguments(vm.heap()); MarkedVector<Value> arguments(vm.heap());

View file

@ -1259,10 +1259,10 @@ static ThrowCompletionOr<void> set_typed_array_from_array_like(VM& vm, TypedArra
auto target_length = target.array_length(); auto target_length = target.array_length();
// 4. Let src be ? ToObject(source). // 4. Let src be ? ToObject(source).
auto* src = TRY(source.to_object(vm)); auto src = TRY(source.to_object(vm));
// 5. Let srcLength be ? LengthOfArrayLike(src). // 5. Let srcLength be ? LengthOfArrayLike(src).
auto source_length = TRY(length_of_array_like(vm, *src)); auto source_length = TRY(length_of_array_like(vm, src));
// 6. If targetOffset is +∞, throw a RangeError exception. // 6. If targetOffset is +∞, throw a RangeError exception.
if (isinf(target_offset)) if (isinf(target_offset))
@ -1702,7 +1702,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted)
return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn); return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn);
// 2. Let O be the this value. // 2. Let O be the this value.
auto* object = TRY(vm.this_value().to_object(vm)); auto object = TRY(vm.this_value().to_object(vm));
// 3. Perform ? ValidateTypedArray(O). // 3. Perform ? ValidateTypedArray(O).
auto* typed_array = TRY(validate_typed_array_from_this(vm)); auto* typed_array = TRY(validate_typed_array_from_this(vm));
@ -1723,7 +1723,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted)
}; };
// 8. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes). // 8. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes).
auto sorted_list = TRY(sort_indexed_properties(vm, *object, length, sort_compare, Holes::ReadThroughHoles)); auto sorted_list = TRY(sort_indexed_properties(vm, object, length, sort_compare, Holes::ReadThroughHoles));
// 9. Let j be 0. // 9. Let j be 0.
// 10. Repeat, while j < len, // 10. Repeat, while j < len,

View file

@ -347,7 +347,7 @@ ThrowCompletionOr<void> VM::property_binding_initialization(BindingPattern const
auto& vm = *this; auto& vm = *this;
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
auto* object = TRY(value.to_object(vm)); auto object = TRY(value.to_object(vm));
HashTable<PropertyKey> seen_names; HashTable<PropertyKey> seen_names;
for (auto& property : binding.entries) { for (auto& property : binding.entries) {

View file

@ -554,7 +554,7 @@ ThrowCompletionOr<Value> Value::to_primitive(VM& vm, PreferredType preferred_typ
} }
// 7.1.18 ToObject ( argument ), https://tc39.es/ecma262/#sec-toobject // 7.1.18 ToObject ( argument ), https://tc39.es/ecma262/#sec-toobject
ThrowCompletionOr<Object*> Value::to_object(VM& vm) const ThrowCompletionOr<NonnullGCPtr<Object>> Value::to_object(VM& vm) const
{ {
auto& realm = *vm.current_realm(); auto& realm = *vm.current_realm();
VERIFY(!is_empty()); VERIFY(!is_empty());
@ -562,7 +562,7 @@ ThrowCompletionOr<Object*> Value::to_object(VM& vm) const
// Number // Number
if (is_number()) { if (is_number()) {
// Return a new Number object whose [[NumberData]] internal slot is set to argument. See 21.1 for a description of Number objects. // Return a new Number object whose [[NumberData]] internal slot is set to argument. See 21.1 for a description of Number objects.
return NumberObject::create(realm, as_double()).ptr(); return NumberObject::create(realm, as_double());
} }
switch (m_value.tag) { switch (m_value.tag) {
@ -575,23 +575,23 @@ ThrowCompletionOr<Object*> Value::to_object(VM& vm) const
// Boolean // Boolean
case BOOLEAN_TAG: case BOOLEAN_TAG:
// Return a new Boolean object whose [[BooleanData]] internal slot is set to argument. See 20.3 for a description of Boolean objects. // Return a new Boolean object whose [[BooleanData]] internal slot is set to argument. See 20.3 for a description of Boolean objects.
return BooleanObject::create(realm, as_bool()).ptr(); return BooleanObject::create(realm, as_bool());
// String // String
case STRING_TAG: case STRING_TAG:
// Return a new String object whose [[StringData]] internal slot is set to argument. See 22.1 for a description of String objects. // Return a new String object whose [[StringData]] internal slot is set to argument. See 22.1 for a description of String objects.
return MUST_OR_THROW_OOM(StringObject::create(realm, const_cast<JS::PrimitiveString&>(as_string()), realm.intrinsics().string_prototype())).ptr(); return MUST_OR_THROW_OOM(StringObject::create(realm, const_cast<JS::PrimitiveString&>(as_string()), realm.intrinsics().string_prototype()));
// Symbol // Symbol
case SYMBOL_TAG: case SYMBOL_TAG:
// Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 20.4 for a description of Symbol objects. // Return a new Symbol object whose [[SymbolData]] internal slot is set to argument. See 20.4 for a description of Symbol objects.
return SymbolObject::create(realm, const_cast<JS::Symbol&>(as_symbol())).ptr(); return SymbolObject::create(realm, const_cast<JS::Symbol&>(as_symbol()));
// BigInt // BigInt
case BIGINT_TAG: case BIGINT_TAG:
// Return a new BigInt object whose [[BigIntData]] internal slot is set to argument. See 21.2 for a description of BigInt objects. // Return a new BigInt object whose [[BigIntData]] internal slot is set to argument. See 21.2 for a description of BigInt objects.
return BigIntObject::create(realm, const_cast<JS::BigInt&>(as_bigint())).ptr(); return BigIntObject::create(realm, const_cast<JS::BigInt&>(as_bigint()));
// Object // Object
case OBJECT_TAG: case OBJECT_TAG:
// Return argument. // Return argument.
return &const_cast<Object&>(as_object()); return const_cast<Object&>(as_object());
default: default:
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -1221,7 +1221,7 @@ ThrowCompletionOr<Value> Value::get(VM& vm, PropertyKey const& property_key) con
VERIFY(property_key.is_valid()); VERIFY(property_key.is_valid());
// 2. Let O be ? ToObject(V). // 2. Let O be ? ToObject(V).
auto* object = TRY(to_object(vm)); auto object = TRY(to_object(vm));
// 3. Return ? O.[[Get]](P, V). // 3. Return ? O.[[Get]](P, V).
return TRY(object->internal_get(property_key, *this)); return TRY(object->internal_get(property_key, *this));

View file

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

View file

@ -160,7 +160,7 @@ JS::ThrowCompletionOr<size_t> instantiate_module(JS::VM& vm, Wasm::Module const&
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()) {
auto* import_object = TRY(import_argument.to_object(vm)); auto import_object = TRY(import_argument.to_object(vm));
dbgln("Trying to resolve stuff because import object was specified"); dbgln("Trying to resolve stuff because import object was specified");
for (Wasm::Linker::Name const& import_name : linker.unresolved_imports()) { for (Wasm::Linker::Name const& import_name : linker.unresolved_imports()) {
dbgln("Trying to resolve {}::{}", import_name.module, import_name.name); dbgln("Trying to resolve {}::{}", import_name.module, import_name.name);
@ -171,7 +171,7 @@ JS::ThrowCompletionOr<size_t> instantiate_module(JS::VM& vm, Wasm::Module const&
auto object_or_error = value.to_object(vm); auto object_or_error = value.to_object(vm);
if (object_or_error.is_error()) if (object_or_error.is_error())
break; break;
auto* object = object_or_error.release_value(); 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;

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2020-2022, Ali Mohammad Pur <mpfard@serenityos.org> * Copyright (c) 2020-2022, Ali Mohammad Pur <mpfard@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -829,7 +829,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!variable.is_object()) if (!variable.is_object())
break; break;
auto const* object = MUST(variable.to_object(*g_vm)); auto const object = MUST(variable.to_object(*g_vm));
auto const& shape = object->shape(); auto const& shape = object->shape();
list_all_properties(shape, property_name); list_all_properties(shape, property_name);
break; break;