summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/AST.cpp11
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.cpp13
-rw-r--r--Userland/Libraries/LibJS/Runtime/Accessor.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp11
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp72
-rw-r--r--Userland/Libraries/LibJS/Runtime/DatePrototype.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/FunctionObject.cpp5
-rw-r--r--Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp6
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalObject.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp15
-rw-r--r--Userland/Libraries/LibJS/Runtime/JSONObject.cpp16
-rw-r--r--Userland/Libraries/LibJS/Runtime/JobCallback.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Object.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Promise.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp6
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp16
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/ProxyObject.cpp69
-rw-r--r--Userland/Libraries/LibJS/Runtime/ReflectObject.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/StringPrototype.cpp32
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp80
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp18
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp37
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.cpp15
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.h10
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.cpp20
-rw-r--r--Userland/Libraries/LibJS/Runtime/Value.h4
-rw-r--r--Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp4
33 files changed, 187 insertions, 321 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp
index d0d5ad88a4..70a6a9c59b 100644
--- a/Userland/Libraries/LibJS/AST.cpp
+++ b/Userland/Libraries/LibJS/AST.cpp
@@ -246,7 +246,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
return TRY_OR_DISCARD(perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct));
}
- return vm.call(function, this_value, move(arg_list));
+ return TRY_OR_DISCARD(vm.call(function, this_value, move(arg_list)));
}
// 13.3.7.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
@@ -976,11 +976,8 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
if (field.is_static()) {
Value field_value = js_undefined();
- if (initializer) {
- field_value = interpreter.vm().call(*initializer, class_constructor_value);
- if (interpreter.exception())
- return {};
- }
+ if (initializer)
+ field_value = TRY_OR_DISCARD(interpreter.vm().call(*initializer, class_constructor_value));
class_constructor->create_data_property_or_throw(property_key, field_value);
if (interpreter.exception())
@@ -2280,7 +2277,7 @@ Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& glo
raw_strings->indexed_properties().append(value);
}
strings->define_direct_property(vm.names.raw, raw_strings, 0);
- return vm.call(tag_function, js_undefined(), move(arguments));
+ return TRY_OR_DISCARD(vm.call(tag_function, js_undefined(), move(arguments)));
}
void TryStatement::dump(int indent) const
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp
index 15e03fca86..fd25bb3ab8 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp
@@ -295,16 +295,21 @@ void Call::execute_impl(Bytecode::Interpreter& interpreter) const
Value return_value;
if (m_argument_count == 0 && m_type == CallType::Call) {
- return_value = interpreter.vm().call(function, this_value);
+ auto return_value_or_error = interpreter.vm().call(function, this_value);
+ if (!return_value_or_error.is_error())
+ return_value = return_value_or_error.release_value();
} else {
MarkedValueList argument_values { interpreter.vm().heap() };
for (size_t i = 0; i < m_argument_count; ++i) {
argument_values.append(interpreter.reg(m_arguments[i]));
}
- if (m_type == CallType::Call)
- return_value = interpreter.vm().call(function, this_value, move(argument_values));
- else
+ if (m_type == CallType::Call) {
+ auto return_value_or_error = interpreter.vm().call(function, this_value, move(argument_values));
+ if (!return_value_or_error.is_error())
+ return_value = return_value_or_error.release_value();
+ } else {
return_value = interpreter.vm().construct(function, function, move(argument_values));
+ }
}
interpreter.accumulator() = return_value;
diff --git a/Userland/Libraries/LibJS/Runtime/Accessor.h b/Userland/Libraries/LibJS/Runtime/Accessor.h
index 5dfed111a7..9f30ba0be4 100644
--- a/Userland/Libraries/LibJS/Runtime/Accessor.h
+++ b/Userland/Libraries/LibJS/Runtime/Accessor.h
@@ -35,7 +35,7 @@ public:
{
if (!m_getter)
return js_undefined();
- return vm().call(*m_getter, this_value);
+ return TRY_OR_DISCARD(vm().call(*m_getter, this_value));
}
void call_setter(Value this_value, Value setter_value)
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp
index 4956552fee..4660d78eec 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp
@@ -151,7 +151,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
Value mapped_value;
if (map_fn) {
- mapped_value = vm.call(*map_fn, this_arg, next_value, Value(k));
+ mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, next_value, Value(k)));
if (vm.exception()) {
iterator_close(*iterator);
return {};
@@ -192,13 +192,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
for (size_t k = 0; k < length; ++k) {
auto k_value = array_like->get(k);
Value mapped_value;
- if (map_fn) {
- mapped_value = vm.call(*map_fn, this_arg, k_value, Value(k));
- if (vm.exception())
- return {};
- } else {
+ if (map_fn)
+ mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k)));
+ else
mapped_value = k_value;
- }
array_object.create_data_property_or_throw(k, mapped_value);
}
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
index 7e4718d84f..6c44484aa3 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
@@ -206,12 +206,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
return {};
// ii. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
- auto selected = vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto selected = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If selected is true, then
- if (selected.to_boolean()) {
+ if (selected) {
// 1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(to)), kValue).
array->create_data_property_or_throw(to, k_value);
@@ -322,9 +320,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
return {};
// ii. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
- auto mapped_value = vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto mapped_value = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object));
// iii. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
array->create_data_property_or_throw(property_name, mapped_value);
@@ -495,7 +491,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_string)
return {};
if (!join_function.is_function())
return ObjectPrototype::to_string(vm, global_object);
- return vm.call(join_function.as_function(), this_object);
+ return TRY_OR_DISCARD(vm.call(join_function.as_function(), this_object));
}
// 23.1.3.29 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-array.prototype.tolocalestring
@@ -524,9 +520,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
return {};
if (value.is_nullish())
continue;
- auto locale_string_result = value.invoke(global_object, vm.names.toLocaleString);
- if (vm.exception())
- return {};
+ auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString));
auto string = locale_string_result.to_string(global_object);
if (vm.exception())
return {};
@@ -912,9 +906,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
return {};
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
- accumulator = vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ accumulator = TRY_OR_DISCARD(vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value(k), object));
}
// d. Set k to k + 1.
@@ -1012,9 +1004,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
return {};
// ii. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
- accumulator = vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object);
- if (vm.exception())
- return {};
+ accumulator = TRY_OR_DISCARD(vm.call(callback_function.as_function(), js_undefined(), accumulator, k_value, Value((size_t)k), object));
}
// d. Set k to k - 1.
@@ -1128,9 +1118,10 @@ static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject
} else if (y.is_undefined()) {
comparison_result = -1;
} else if (compare_func) {
- auto call_result = vm.call(*compare_func, js_undefined(), left[left_index], right[right_index]);
- if (vm.exception())
+ auto call_result_or_error = vm.call(*compare_func, js_undefined(), left[left_index], right[right_index]);
+ if (call_result_or_error.is_error())
return;
+ auto call_result = call_result_or_error.release_value();
auto number = call_result.to_number(global_object);
if (vm.exception())
@@ -1393,12 +1384,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
return {};
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(predicate.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// d. If testResult is true, return kValue.
- if (test_result.to_boolean())
+ if (test_result)
return k_value;
// e. Set k to k + 1.
@@ -1440,12 +1429,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
return {};
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(predicate.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// d. If testResult is true, return 𝔽(k).
- if (test_result.to_boolean())
+ if (test_result)
return Value(k);
// e. Set k to k + 1.
@@ -1487,12 +1474,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
return {};
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
// d. If testResult is true, return kValue.
- if (test_result.to_boolean())
+ if (test_result)
return k_value;
// e. Set k to k - 1.
@@ -1534,12 +1519,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
return {};
// c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
// d. If testResult is true, return 𝔽(k).
- if (test_result.to_boolean())
+ if (test_result)
return Value((double)k);
// e. Set k to k - 1.
@@ -1588,12 +1571,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
return {};
// ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If testResult is true, return true.
- if (test_result.to_boolean())
+ if (test_result)
return Value(true);
}
@@ -1643,12 +1624,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
return {};
// ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
- auto test_result = vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object);
- if (vm.exception())
- return {};
+ auto test_result = TRY_OR_DISCARD(vm.call(callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
// iii. If testResult is false, return false.
- if (!test_result.to_boolean())
+ if (!test_result)
return Value(false);
}
@@ -1887,11 +1866,8 @@ static size_t flatten_into_array(GlobalObject& global_object, Object& new_array,
if (vm.exception())
return {};
- if (mapper_func) {
- value = vm.call(*mapper_func, this_arg, value, Value(j), &array);
- if (vm.exception())
- return {};
- }
+ if (mapper_func)
+ value = TRY_OR_DISCARD(vm.call(*mapper_func, this_arg, value, Value(j), &array));
if (depth > 0 && TRY_OR_DISCARD(value.is_array(global_object))) {
if (vm.did_reach_stack_space_limit()) {
diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
index d7240a7406..d348b2851c 100644
--- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp
@@ -842,7 +842,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_json)
if (time_value.is_number() && !time_value.is_finite_number())
return js_null();
- return this_value.invoke(global_object, vm.names.toISOString);
+ return TRY_OR_DISCARD(this_value.invoke(global_object, vm.names.toISOString));
}
// 14.1.1 Date.prototype.toTemporalInstant ( ), https://tc39.es/proposal-temporal/#sec-date.prototype.totemporalinstant
diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp
index 341ac80169..872542be61 100644
--- a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp
@@ -76,9 +76,10 @@ void FunctionObject::InstanceField::define_field(VM& vm, Object& receiver) const
{
Value init_value = js_undefined();
if (initializer) {
- init_value = vm.call(*initializer, receiver.value_of());
- if (vm.exception())
+ auto init_value_or_error = vm.call(*initializer, receiver.value_of());
+ if (init_value_or_error.is_error())
return;
+ init_value = init_value_or_error.release_value();
}
receiver.create_data_property_or_throw(name, init_value);
}
diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp
index 75b0a34ab2..295dd1b3c2 100644
--- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp
@@ -56,9 +56,9 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
auto this_arg = vm.argument(0);
auto arg_array = vm.argument(1);
if (arg_array.is_nullish())
- return vm.call(function, this_arg);
+ return TRY_OR_DISCARD(vm.call(function, this_arg));
auto arguments = TRY_OR_DISCARD(create_list_from_array_like(global_object, arg_array));
- return vm.call(function, this_arg, move(arguments));
+ return TRY_OR_DISCARD(vm.call(function, this_arg, move(arguments)));
}
// 20.2.3.2 Function.prototype.bind ( thisArg, ...args ), https://tc39.es/ecma262/#sec-function.prototype.bind
@@ -100,7 +100,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
for (size_t i = 1; i < vm.argument_count(); ++i)
arguments.append(vm.argument(i));
}
- return vm.call(function, this_arg, move(arguments));
+ return TRY_OR_DISCARD(vm.call(function, this_arg, move(arguments)));
}
// 20.2.3.5 Function.prototype.toString ( ), https://tc39.es/ecma262/#sec-function.prototype.tostring
diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h
index b2d47bfc4c..b03340ec86 100644
--- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h
+++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h
@@ -160,7 +160,7 @@ template<>
inline bool Object::fast_is<GlobalObject>() const { return is_global_object(); }
template<typename... Args>
-[[nodiscard]] ALWAYS_INLINE Value Value::invoke(GlobalObject& global_object, PropertyName const& property_name, Args... args)
+[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> Value::invoke(GlobalObject& global_object, PropertyName const& property_name, Args... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedValueList arglist { global_object.vm().heap() };
diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp
index afdf4d2f13..9dccef24ac 100644
--- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp
@@ -29,9 +29,7 @@ Object* get_iterator(GlobalObject& global_object, Value value, IteratorHint hint
vm.throw_exception<TypeError>(global_object, ErrorType::NotIterable, value.to_string_without_side_effects());
return nullptr;
}
- auto iterator = vm.call(method.as_function(), value);
- if (vm.exception())
- return {};
+ auto iterator = TRY_OR_DISCARD(vm.call(method.as_function(), value));
if (!iterator.is_object()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotIterable, value.to_string_without_side_effects());
return nullptr;
@@ -56,12 +54,10 @@ Object* iterator_next(Object& iterator, Value value)
Value result;
if (value.is_empty())
- result = vm.call(next_method.as_function(), &iterator);
+ result = TRY_OR_DISCARD(vm.call(next_method.as_function(), &iterator));
else
- result = vm.call(next_method.as_function(), &iterator, value);
+ result = TRY_OR_DISCARD(vm.call(next_method.as_function(), &iterator, value));
- if (vm.exception())
- return {};
if (!result.is_object()) {
vm.throw_exception<TypeError>(global_object, ErrorType::IterableNextBadReturn);
return nullptr;
@@ -132,11 +128,12 @@ void iterator_close(Object& iterator)
if (!return_method)
return restore_completion(); // If return is undefined, return Completion(completion).
- auto result = vm.call(*return_method, &iterator);
+ auto result_or_error = vm.call(*return_method, &iterator);
if (completion_exception)
return restore_completion(); // If completion.[[Type]] is throw, return Completion(completion).
- if (vm.exception())
+ if (result_or_error.is_error())
return; // If innerResult.[[Type]] is throw, return Completion(innerResult).
+ auto result = result_or_error.release_value();
if (!result.is_object()) {
vm.throw_exception<TypeError>(global_object, ErrorType::IterableReturnBadReturn);
return; // If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception.
diff --git a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp
index 568037eeff..0a64678feb 100644
--- a/Userland/Libraries/LibJS/Runtime/JSONObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/JSONObject.cpp
@@ -152,18 +152,12 @@ String JSONObject::serialize_json_property(GlobalObject& global_object, Stringif
auto to_json = value_object->get(vm.names.toJSON);
if (vm.exception())
return {};
- if (to_json.is_function()) {
- value = vm.call(to_json.as_function(), value, js_string(vm, key.to_string()));
- if (vm.exception())
- return {};
- }
+ if (to_json.is_function())
+ value = TRY_OR_DISCARD(vm.call(to_json.as_function(), value, js_string(vm, key.to_string())));
}
- if (state.replacer_function) {
- value = vm.call(*state.replacer_function, holder, js_string(vm, key.to_string()), value);
- if (vm.exception())
- return {};
- }
+ if (state.replacer_function)
+ value = TRY_OR_DISCARD(vm.call(*state.replacer_function, holder, js_string(vm, key.to_string()), value));
if (value.is_object()) {
auto& value_object = value.as_object();
@@ -507,7 +501,7 @@ Value JSONObject::internalize_json_property(GlobalObject& global_object, Object*
}
}
- return vm.call(reviver, Value(holder), js_string(vm, name.to_string()), value);
+ return TRY_OR_DISCARD(vm.call(reviver, Value(holder), js_string(vm, name.to_string()), value));
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/JobCallback.h b/Userland/Libraries/LibJS/Runtime/JobCallback.h
index 8be1854abd..a9d95607b3 100644
--- a/Userland/Libraries/LibJS/Runtime/JobCallback.h
+++ b/Userland/Libraries/LibJS/Runtime/JobCallback.h
@@ -28,7 +28,7 @@ template<typename... Args>
{
VERIFY(job_callback.callback);
auto& callback = *job_callback.callback;
- return vm.call(callback, this_value, args...);
+ return TRY_OR_DISCARD(vm.call(callback, this_value, args...));
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp
index 1d5e2bb54b..438382d06f 100644
--- a/Userland/Libraries/LibJS/Runtime/Object.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Object.cpp
@@ -703,7 +703,7 @@ Value Object::internal_get(PropertyName const& property_name, Value receiver) co
return js_undefined();
// 8. Return ? Call(getter, Receiver).
- return vm.call(*getter, receiver);
+ return TRY_OR_DISCARD(vm.call(*getter, receiver));
}
static bool ordinary_set_with_own_descriptor(Object&, PropertyName const&, Value, Value, Optional<PropertyDescriptor>);
@@ -1199,7 +1199,7 @@ Value Object::ordinary_to_primitive(Value::PreferredType preferred_type) const
if (vm.exception())
return {};
if (method.is_function()) {
- auto result = vm.call(method.as_function(), const_cast<Object*>(this));
+ auto result = TRY_OR_DISCARD(vm.call(method.as_function(), const_cast<Object*>(this)));
if (!result.is_object())
return result;
}
diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
index fef4b6992b..b1547f138d 100644
--- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
@@ -144,7 +144,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_locale_string)
{
auto this_value = vm.this_value(global_object);
- return this_value.invoke(global_object, vm.names.toString);
+ return TRY_OR_DISCARD(this_value.invoke(global_object, vm.names.toString));
}
// 20.1.3.7 Object.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-object.prototype.valueof
diff --git a/Userland/Libraries/LibJS/Runtime/Promise.cpp b/Userland/Libraries/LibJS/Runtime/Promise.cpp
index 126acfb3f0..f9d93b97f7 100644
--- a/Userland/Libraries/LibJS/Runtime/Promise.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Promise.cpp
@@ -32,9 +32,7 @@ Object* promise_resolve(GlobalObject& global_object, Object& constructor, Value
auto promise_capability = new_promise_capability(global_object, &constructor);
if (vm.exception())
return nullptr;
- [[maybe_unused]] auto result = vm.call(*promise_capability.resolve, js_undefined(), value);
- if (vm.exception())
- return nullptr;
+ [[maybe_unused]] auto result = TRY_OR_DISCARD(vm.call(*promise_capability.resolve, js_undefined(), value));
return promise_capability.promise;
}
diff --git a/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp b/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp
index 630afddb29..8fc64ade9f 100644
--- a/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp
@@ -113,9 +113,7 @@ static Value perform_promise_common(GlobalObject& global_object, Object& iterato
values->values().append(js_undefined());
- auto next_promise = vm.call(promise_resolve.as_function(), constructor, next_value);
- if (vm.exception())
- return {};
+ auto next_promise = TRY_OR_DISCARD(vm.call(promise_resolve.as_function(), constructor, next_value));
++remaining_elements_count->value;
@@ -410,7 +408,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::reject)
if (vm.exception())
return {};
auto reason = vm.argument(0);
- [[maybe_unused]] auto result = vm.call(*promise_capability.reject, js_undefined(), reason);
+ [[maybe_unused]] auto result = TRY_OR_DISCARD(vm.call(*promise_capability.reject, js_undefined(), reason));
return promise_capability.promise;
}
diff --git a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp b/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp
index 4aef8c5753..e5074f5ec0 100644
--- a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp
@@ -62,11 +62,11 @@ Value PromiseReactionJob::call()
vm.stop_unwind();
auto* reject_function = promise_capability.value().reject;
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's reject function @ {}", this, reject_function);
- return vm.call(*reject_function, js_undefined(), handler_result);
+ return TRY_OR_DISCARD(vm.call(*reject_function, js_undefined(), handler_result));
} else {
auto* resolve_function = promise_capability.value().resolve;
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's resolve function @ {}", this, resolve_function);
- return vm.call(*resolve_function, js_undefined(), handler_result);
+ return TRY_OR_DISCARD(vm.call(*resolve_function, js_undefined(), handler_result));
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp b/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
index 8efcb6e85e..3774cce9cc 100644
--- a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
@@ -55,7 +55,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::catch_)
{
auto this_value = vm.this_value(global_object);
auto on_rejected = vm.argument(0);
- return this_value.invoke(global_object, vm.names.then, js_undefined(), on_rejected);
+ return TRY_OR_DISCARD(this_value.invoke(global_object, vm.names.then, js_undefined(), on_rejected));
}
// 27.2.5.3 Promise.prototype.finally ( onFinally ), https://tc39.es/ecma262/#sec-promise.prototype.finally
@@ -77,16 +77,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
auto value = vm.argument(0);
- auto result = vm.call(on_finally, js_undefined());
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(on_finally, js_undefined()));
auto* promise = promise_resolve(global_object, constructor, result);
if (vm.exception())
return {};
auto* value_thunk = NativeFunction::create(global_object, "", [value](auto&, auto&) -> Value {
return value;
});
- return Value(promise).invoke(global_object, vm.names.then, value_thunk);
+ return TRY_OR_DISCARD(Value(promise).invoke(global_object, vm.names.then, value_thunk));
});
then_finally_function->define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
@@ -95,9 +93,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
auto& constructor = const_cast<FunctionObject&>(*constructor_handle.cell());
auto& on_finally = const_cast<FunctionObject&>(*on_finally_handle.cell());
auto reason = vm.argument(0);
- auto result = vm.call(on_finally, js_undefined());
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(on_finally, js_undefined()));
auto* promise = promise_resolve(global_object, constructor, result);
if (vm.exception())
return {};
@@ -105,14 +101,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
vm.throw_exception(global_object, reason);
return {};
});
- return Value(promise).invoke(global_object, vm.names.then, thrower);
+ return TRY_OR_DISCARD(Value(promise).invoke(global_object, vm.names.then, thrower));
});
catch_finally_function->define_direct_property(vm.names.length, Value(1), Attribute::Configurable);
then_finally = Value(then_finally_function);
catch_finally = Value(catch_finally_function);
}
- return Value(promise).invoke(global_object, vm.names.then, then_finally, catch_finally);
+ return TRY_OR_DISCARD(Value(promise).invoke(global_object, vm.names.then, then_finally, catch_finally));
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp b/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
index 22019a1eb2..83dd7cd8c2 100644
--- a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
@@ -67,7 +67,7 @@ Value PromiseAllResolveElementFunction::resolve_element()
if (--m_remaining_elements.value == 0) {
auto values_array = Array::create_from(global_object, m_values.values());
- return vm.call(*m_capability.resolve, js_undefined(), values_array);
+ return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
}
return js_undefined();
@@ -96,7 +96,7 @@ Value PromiseAllSettledResolveElementFunction::resolve_element()
if (--m_remaining_elements.value == 0) {
auto values_array = Array::create_from(global_object, m_values.values());
- return vm.call(*m_capability.resolve, js_undefined(), values_array);
+ return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
}
return js_undefined();
@@ -125,7 +125,7 @@ Value PromiseAllSettledRejectElementFunction::resolve_element()
if (--m_remaining_elements.value == 0) {
auto values_array = Array::create_from(global_object, m_values.values());
- return vm.call(*m_capability.resolve, js_undefined(), values_array);
+ return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
}
return js_undefined();
@@ -154,7 +154,7 @@ Value PromiseAnyRejectElementFunction::resolve_element()
auto* error = AggregateError::create(global_object);
error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true });
- return vm.call(*m_capability.reject, js_undefined(), error);
+ return TRY_OR_DISCARD(vm.call(*m_capability.reject, js_undefined(), error));
}
return js_undefined();
diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
index 39d99f6017..ac2d9628f2 100644
--- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
@@ -73,9 +73,7 @@ Object* ProxyObject::internal_get_prototype_of() const
}
// 7. Let handlerProto be ? Call(trap, handler, « target »).
- auto handler_proto = vm.call(*trap, &m_handler, &m_target);
- if (vm.exception())
- return {};
+ auto handler_proto = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target));
// 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
if (!handler_proto.is_object() && !handler_proto.is_null()) {
@@ -137,12 +135,10 @@ bool ProxyObject::internal_set_prototype_of(Object* prototype)
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, V »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, prototype);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, prototype)).to_boolean();
// 9. If booleanTrapResult is false, return false.
- if (!trap_result.to_boolean())
+ if (!trap_result)
return false;
// 10. Let extensibleTarget be ? IsExtensible(target).
@@ -198,9 +194,7 @@ bool ProxyObject::internal_is_extensible() const
}
// 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target)).to_boolean();
// 8. Let targetResult be ? IsExtensible(target).
auto target_result = m_target.is_extensible();
@@ -208,13 +202,13 @@ bool ProxyObject::internal_is_extensible() const
return {};
// 9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception.
- if (trap_result.to_boolean() != target_result) {
+ if (trap_result != target_result) {
vm.throw_exception<TypeError>(global_object, ErrorType::ProxyIsExtensibleReturn);
return {};
}
// 10. Return booleanTrapResult.
- return trap_result.to_boolean();
+ return trap_result;
}
// 10.5.4 [[PreventExtensions]] ( ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-preventextensions
@@ -246,12 +240,10 @@ bool ProxyObject::internal_prevent_extensions()
}
// 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target)).to_boolean();
// 8. If booleanTrapResult is true, then
- if (trap_result.to_boolean()) {
+ if (trap_result) {
// a. Let extensibleTarget be ? IsExtensible(target).
auto extensible_target = m_target.is_extensible();
if (vm.exception())
@@ -265,7 +257,7 @@ bool ProxyObject::internal_prevent_extensions()
}
// 9. Return booleanTrapResult.
- return trap_result.to_boolean();
+ return trap_result;
}
// 10.5.5 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
@@ -300,9 +292,7 @@ Optional<PropertyDescriptor> ProxyObject::internal_get_own_property(const Proper
}
// 8. Let trapResultObj be ? Call(trap, handler, « target, P »).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name)));
// 9. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
if (!trap_result.is_object() && !trap_result.is_undefined()) {
@@ -421,12 +411,10 @@ bool ProxyObject::internal_define_own_property(PropertyName const& property_name
auto descriptor_object = from_property_descriptor(global_object, property_descriptor);
// 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), descriptor_object);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), descriptor_object)).to_boolean();
// 10. If booleanTrapResult is false, return false.
- if (!trap_result.to_boolean())
+ if (!trap_result)
return false;
// 11. Let targetDesc be ? target.[[GetOwnProperty]](P).
@@ -519,12 +507,10 @@ bool ProxyObject::internal_has_property(PropertyName const& property_name) const
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name))).to_boolean();
// 9. If booleanTrapResult is false, then
- if (!trap_result.to_boolean()) {
+ if (!trap_result) {
// a. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = m_target.internal_get_own_property(property_name);
if (vm.exception())
@@ -552,7 +538,7 @@ bool ProxyObject::internal_has_property(PropertyName const& property_name) const
}
// 10. Return booleanTrapResult.
- return trap_result.to_boolean();
+ return trap_result;
}
// 10.5.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
@@ -607,9 +593,7 @@ Value ProxyObject::internal_get(PropertyName const& property_name, Value receive
}
// 8. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), receiver);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), receiver));
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
auto target_descriptor = m_target.internal_get_own_property(property_name);
@@ -675,12 +659,10 @@ bool ProxyObject::internal_set(PropertyName const& property_name, Value value, V
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), value, receiver);
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), value, receiver)).to_boolean();
// 9. If booleanTrapResult is false, return false.
- if (!trap_result.to_boolean())
+ if (!trap_result)
return false;
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
@@ -744,12 +726,10 @@ bool ProxyObject::internal_delete(PropertyName const& property_name)
}
// 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
- auto trap_result = vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name));
- if (vm.exception())
- return {};
+ auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name))).to_boolean();
// 9. If booleanTrapResult is false, return false.
- if (!trap_result.to_boolean())
+ if (!trap_result)
return false;
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
@@ -811,9 +791,10 @@ MarkedValueList ProxyObject::internal_own_property_keys() const
}
// 7. Let trapResultArray be ? Call(trap, handler, « target »).
- auto trap_result_array = vm.call(*trap, &m_handler, &m_target);
- if (vm.exception())
+ auto trap_result_array_or_error = vm.call(*trap, &m_handler, &m_target);
+ if (trap_result_array_or_error.is_error())
return MarkedValueList { heap() };
+ auto trap_result_array = trap_result_array_or_error.release_value();
// 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
HashTable<StringOrSymbol> unique_keys;
@@ -967,7 +948,7 @@ Value ProxyObject::call()
});
// 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
- return vm.call(*trap, &m_handler, &m_target, this_argument, arguments_array);
+ return TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, this_argument, arguments_array));
}
// 10.5.13 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget
@@ -1012,7 +993,7 @@ Value ProxyObject::construct(FunctionObject& new_target)
});
// 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
- auto result = vm.call(*trap, &m_handler, &m_target, arguments_array, &new_target);
+ auto result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, arguments_array, &new_target));
// 10. If Type(newObj) is not Object, throw a TypeError exception.
if (!result.is_object()) {
diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
index b15131a6d4..ed2694fdee 100644
--- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp
@@ -65,7 +65,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::apply)
// 3. Perform PrepareForTailCall().
// 4. Return ? Call(target, thisArgument, args).
- return vm.call(target.as_function(), this_argument, move(args));
+ return TRY_OR_DISCARD(vm.call(target.as_function(), this_argument, move(args)));
}
// 28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] ), https://tc39.es/ecma262/#sec-reflect.construct
diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
index c848fc28cb..340dfc492e 100644
--- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
@@ -292,9 +292,7 @@ Value regexp_exec(GlobalObject& global_object, Object& regexp_object, Utf16Strin
return {};
if (exec.is_function()) {
- auto result = vm.call(exec.as_function(), &regexp_object, js_string(vm, move(string)));
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(exec.as_function(), &regexp_object, js_string(vm, move(string))));
if (!result.is_object() && !result.is_null())
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOrNull, result.to_string_without_side_effects());
@@ -685,9 +683,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
replacer_args.append(move(named_captures));
}
- auto replace_result = vm.call(replace_value.as_function(), js_undefined(), move(replacer_args));
- if (vm.exception())
- return {};
+ auto replace_result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), move(replacer_args)));
replacement = replace_result.to_string(global_object);
if (vm.exception())
diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
index 5f52af546d..e22ef1f45d 100644
--- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
@@ -714,7 +714,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
if (vm.exception())
return {};
if (splitter)
- return vm.call(*splitter, separator_argument, object, limit_argument);
+ return TRY_OR_DISCARD(vm.call(*splitter, separator_argument, object, limit_argument));
}
auto string = object.to_utf16_string(global_object);
@@ -861,7 +861,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match)
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* matcher = regexp.get_method(global_object, *vm.well_known_symbol_match()))
- return vm.call(*matcher, regexp, this_object);
+ return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object));
if (vm.exception())
return {};
}
@@ -873,7 +873,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match)
auto rx = regexp_create(global_object, regexp, js_undefined());
if (!rx)
return {};
- return Value(rx).invoke(global_object, *vm.well_known_symbol_match(), js_string(vm, move(string)));
+ return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_match(), js_string(vm, move(string))));
}
// 22.1.3.12 String.prototype.matchAll ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.matchall
@@ -897,7 +897,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
}
}
if (auto* matcher = regexp.get_method(global_object, *vm.well_known_symbol_match_all()))
- return vm.call(*matcher, regexp, this_object);
+ return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object));
if (vm.exception())
return {};
}
@@ -909,7 +909,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
auto rx = regexp_create(global_object, regexp, js_string(vm, "g"));
if (!rx)
return {};
- return Value(rx).invoke(global_object, *vm.well_known_symbol_match_all(), js_string(vm, move(string)));
+ return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_match_all(), js_string(vm, move(string))));
}
// 22.1.3.17 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
@@ -921,7 +921,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
if (!search_value.is_nullish()) {
if (auto* replacer = search_value.get_method(global_object, *vm.well_known_symbol_replace()))
- return vm.call(*replacer, search_value, this_object, replace_value);
+ return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value));
if (vm.exception())
return {};
}
@@ -950,9 +950,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
String replacement;
if (replace_value.is_function()) {
- auto result = vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string));
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string)));
replacement = result.to_string(global_object);
if (vm.exception())
@@ -996,12 +994,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
auto* replacer = search_value.get_method(global_object, *vm.well_known_symbol_replace());
if (vm.exception())
return {};
- if (replacer) {
- auto result = vm.call(*replacer, search_value, this_object, replace_value);
- if (vm.exception())
- return {};
- return result;
- }
+ if (replacer)
+ return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value));
}
auto string = this_object.to_utf16_string(global_object);
@@ -1040,9 +1034,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
String replacement;
if (replace_value.is_function()) {
- auto result = vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string));
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string)));
replacement = result.to_string(global_object);
if (vm.exception())
@@ -1070,7 +1062,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search)
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* searcher = regexp.get_method(global_object, *vm.well_known_symbol_search()))
- return vm.call(*searcher, regexp, this_object);
+ return TRY_OR_DISCARD(vm.call(*searcher, regexp, this_object));
if (vm.exception())
return {};
}
@@ -1082,7 +1074,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search)
auto rx = regexp_create(global_object, regexp, js_undefined());
if (!rx)
return {};
- return Value(rx).invoke(global_object, *vm.well_known_symbol_search(), js_string(vm, move(string)));
+ return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_search(), js_string(vm, move(string))));
}
// B.2.3.2.1 CreateHTML ( string, tag, attribute, value ), https://tc39.es/ecma262/#sec-createhtml
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp
index 69698655bf..b691651ba2 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp
@@ -103,9 +103,7 @@ ThrowCompletionOr<Vector<String>> calendar_fields(GlobalObject& global_object, O
// 3. If fields is not undefined, then
if (fields) {
// a. Set fieldsArray to ? Call(fields, calendar, « fieldsArray »).
- fields_array = vm.call(*fields, &calendar, fields_array);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ fields_array = TRY(vm.call(*fields, &calendar, fields_array));
}
// 4. Return ? IterableToListOfType(fieldsArray, « String »).
@@ -124,9 +122,7 @@ ThrowCompletionOr<double> calendar_year(GlobalObject& global_object, Object& cal
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "year", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.year, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.year, &date_like));
// 3. If result is undefined, throw a RangeError exception.
if (result.is_undefined())
@@ -143,9 +139,7 @@ ThrowCompletionOr<double> calendar_month(GlobalObject& global_object, Object& ca
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "month", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.month, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.month, &date_like));
// 3. If result is undefined, throw a RangeError exception.
if (result.is_undefined())
@@ -162,9 +156,7 @@ ThrowCompletionOr<String> calendar_month_code(GlobalObject& global_object, Objec
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "monthCode", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.monthCode, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.monthCode, &date_like));
// 3. If result is undefined, throw a RangeError exception.
if (result.is_undefined())
@@ -181,9 +173,7 @@ ThrowCompletionOr<double> calendar_day(GlobalObject& global_object, Object& cale
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "day", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.day, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.day, &date_like));
// 3. If result is undefined, throw a RangeError exception.
if (result.is_undefined())
@@ -200,10 +190,7 @@ ThrowCompletionOr<Value> calendar_day_of_week(GlobalObject& global_object, Objec
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "dayOfWeek", « dateLike »).
- auto day_of_week = Value(&calendar).invoke(global_object, vm.names.dayOfWeek, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return day_of_week;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.dayOfWeek, &date_like));
}
// 12.1.14 CalendarDayOfYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardayofyear
@@ -213,10 +200,7 @@ ThrowCompletionOr<Value> calendar_day_of_year(GlobalObject& global_object, Objec
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "dayOfYear", « dateLike »).
- auto day_of_year = Value(&calendar).invoke(global_object, vm.names.dayOfYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return day_of_year;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.dayOfYear, &date_like));
}
// 12.1.15 CalendarWeekOfYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarweekofyear
@@ -226,10 +210,7 @@ ThrowCompletionOr<Value> calendar_week_of_year(GlobalObject& global_object, Obje
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "weekOfYear", « dateLike »).
- auto week_of_year = Value(&calendar).invoke(global_object, vm.names.weekOfYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return week_of_year;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.weekOfYear, &date_like));
}
// 12.1.16 CalendarDaysInWeek ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinweek
@@ -239,10 +220,7 @@ ThrowCompletionOr<Value> calendar_days_in_week(GlobalObject& global_object, Obje
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "daysInWeek", « dateLike »).
- auto days_in_week = Value(&calendar).invoke(global_object, vm.names.daysInWeek, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return days_in_week;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.daysInWeek, &date_like));
}
// 12.1.17 CalendarDaysInMonth ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinmonth
@@ -252,10 +230,7 @@ ThrowCompletionOr<Value> calendar_days_in_month(GlobalObject& global_object, Obj
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "daysInMonth", « dateLike »).
- auto days_in_month = Value(&calendar).invoke(global_object, vm.names.daysInMonth, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return days_in_month;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.daysInMonth, &date_like));
}
// 12.1.18 CalendarDaysInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinyear
@@ -265,10 +240,7 @@ ThrowCompletionOr<Value> calendar_days_in_year(GlobalObject& global_object, Obje
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "daysInYear", « dateLike »).
- auto days_in_year = Value(&calendar).invoke(global_object, vm.names.daysInYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return days_in_year;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.daysInYear, &date_like));
}
// 12.1.19 CalendarMonthsInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthsinyear
@@ -278,10 +250,7 @@ ThrowCompletionOr<Value> calendar_months_in_year(GlobalObject& global_object, Ob
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "monthsInYear", « dateLike »).
- auto months_in_year = Value(&calendar).invoke(global_object, vm.names.monthsInYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return months_in_year;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.monthsInYear, &date_like));
}
// 12.1.20 CalendarInLeapYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarinleapyear
@@ -291,10 +260,7 @@ ThrowCompletionOr<Value> calendar_in_leap_year(GlobalObject& global_object, Obje
// 1. Assert: Type(calendar) is Object.
// 2. Return ? Invoke(calendar, "inLeapYear", « dateLike »).
- auto in_leap_year = Value(&calendar).invoke(global_object, vm.names.inLeapYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
- return in_leap_year;
+ return TRY(Value(&calendar).invoke(global_object, vm.names.inLeapYear, &date_like));
}
// 15.6.1.2 CalendarEra ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarera
@@ -305,9 +271,7 @@ ThrowCompletionOr<Value> calendar_era(GlobalObject& global_object, Object& calen
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "era", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.era, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.era, &date_like));
// 3. If result is not undefined, set result to ? ToString(result).
if (!result.is_undefined()) {
@@ -329,9 +293,7 @@ ThrowCompletionOr<Value> calendar_era_year(GlobalObject& global_object, Object&
// 1. Assert: Type(calendar) is Object.
// 2. Let result be ? Invoke(calendar, "eraYear", « dateLike »).
- auto result = Value(&calendar).invoke(global_object, vm.names.eraYear, &date_like);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto result = TRY(Value(&calendar).invoke(global_object, vm.names.eraYear, &date_like));
// 3. If result is not undefined, set result to ? ToIntegerThrowOnInfinity(result).
if (!result.is_undefined())
@@ -451,9 +413,7 @@ ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Obje
// 2. Assert: Type(fields) is Object.
// 3. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »).
- auto date = Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, &options);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, &options));
// 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
auto* date_object = date.to_object(global_object);
@@ -479,9 +439,7 @@ ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject& global_o
// a. Assert: Type(options) is Object.
// 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »).
- auto year_month = Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined());
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(yearMonth, [[InitializedTemporalYearMonth]]).
auto* year_month_object = year_month.to_object(global_object);
@@ -507,9 +465,7 @@ ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_obj
// a. Assert: Type(options) is Object.
// 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »).
- auto month_day = Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined());
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
// 6. Perform ? RequireInternalSlot(monthDay, [[InitializedTemporalMonthDay]]).
auto* month_day_object = month_day.to_object(global_object);
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp
index 1c677f4a2c..6c91304ec8 100644
--- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp
@@ -374,9 +374,7 @@ ThrowCompletionOr<double> get_offset_nanoseconds_for(GlobalObject& global_object
get_offset_nanoseconds_for = global_object.temporal_time_zone_prototype_get_offset_nanoseconds_for_function();
// 3. Let offsetNanoseconds be ? Call(getOffsetNanosecondsFor, timeZone, « instant »).
- auto offset_nanoseconds_value = vm.call(*get_offset_nanoseconds_for, time_zone, &instant);
- if (auto* exception = vm.exception())
- return throw_completion(exception->value());
+ auto offset_nanoseconds_value = TRY(vm.call(*get_offset_nanoseconds_for, time_zone, &instant));
// 4. If Type(offsetNanoseconds) is not Number, throw a TypeError exception.
if (!offset_nanoseconds_value.is_number())
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp
index f2f09b50f2..35567fb22e 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp
@@ -94,13 +94,10 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
for (size_t k = 0; k < values.size(); ++k) {
auto k_value = values[k];
Value mapped_value;
- if (map_fn) {
- mapped_value = vm.call(*map_fn, this_arg, k_value, Value(k));
- if (vm.exception())
- return {};
- } else {
+ if (map_fn)
+ mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k)));
+ else
mapped_value = k_value;
- }
target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes);
if (vm.exception())
return {};
@@ -121,13 +118,10 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
for (size_t k = 0; k < length; ++k) {
auto k_value = array_like->get(k);
Value mapped_value;
- if (map_fn) {
- mapped_value = vm.call(*map_fn, this_arg, k_value, Value(k));
- if (vm.exception())
- return {};
- } else {
+ if (map_fn)
+ mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k)));
+ else
mapped_value = k_value;
- }
target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes);
if (vm.exception())
return {};
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
index 6ad432e772..379f76db72 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
@@ -122,9 +122,10 @@ static void for_each_item(VM& vm, GlobalObject& global_object, const String& nam
if (vm.exception())
return;
- auto callback_result = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
- if (vm.exception())
+ auto callback_result_or_error = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
+ if (callback_result_or_error.is_error())
return;
+ auto callback_result = callback_result_or_error.release_value();
if (callback(i, value, callback_result) == IterationDecision::Break)
break;
@@ -150,9 +151,10 @@ static void for_each_item_from_last(VM& vm, GlobalObject& global_object, const S
if (vm.exception())
return;
- auto callback_result = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
- if (vm.exception())
+ auto callback_result_or_error = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
+ if (callback_result_or_error.is_error())
return;
+ auto callback_result = callback_result_or_error.release_value();
if (callback(i, value, callback_result) == IterationDecision::Break)
break;
@@ -535,9 +537,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce)
for (; k < length; ++k) {
auto k_value = typed_array->get(k);
- accumulator = vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array);
- if (vm.exception())
- return {};
+ accumulator = TRY_OR_DISCARD(vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
}
return accumulator;
@@ -573,9 +573,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce_right)
for (; k >= 0; --k) {
auto k_value = typed_array->get(k);
- accumulator = vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array);
- if (vm.exception())
- return {};
+ accumulator = TRY_OR_DISCARD(vm.call(*callback_function, js_undefined(), accumulator, k_value, Value(k), typed_array));
}
return accumulator;
@@ -996,9 +994,10 @@ static void typed_array_merge_sort(GlobalObject& global_object, FunctionObject*
double comparison_result;
if (compare_function) {
- auto result = vm.call(*compare_function, js_undefined(), x, y);
- if (vm.exception())
+ auto result_or_error = vm.call(*compare_function, js_undefined(), x, y);
+ if (result_or_error.is_error())
return;
+ auto result = result_or_error.release_value();
auto value = result.to_number(global_object);
if (vm.exception())
@@ -1410,12 +1409,10 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
auto value = typed_array->get(i);
// c. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
- auto callback_result = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
- if (vm.exception())
- return {};
+ auto callback_result = TRY_OR_DISCARD(vm.call(*callback_function, this_value, value, Value((i32)i), typed_array)).to_boolean();
// d. If selected is true, then
- if (callback_result.to_boolean()) {
+ if (callback_result) {
// i. Append kValue to the end of kept.
kept.append(value);
@@ -1483,9 +1480,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map)
auto value = typed_array->get(i);
// c. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
- auto mapped_value = vm.call(*callback_function, this_value, value, Value((i32)i), typed_array);
- if (vm.exception())
- return {};
+ auto mapped_value = TRY_OR_DISCARD(vm.call(*callback_function, this_value, value, Value((i32)i), typed_array));
// d. Perform ? Set(A, Pk, mappedValue, true).
return_array->set(i, mapped_value, Object::ShouldThrowExceptions::Yes);
@@ -1517,9 +1512,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_locale_string)
return {};
if (value.is_nullish())
continue;
- auto locale_string_result = value.invoke(global_object, vm.names.toLocaleString);
- if (vm.exception())
- return {};
+ auto locale_string_result = TRY_OR_DISCARD(value.invoke(global_object, vm.names.toLocaleString));
auto string = locale_string_result.to_string(global_object);
if (vm.exception())
return {};
diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp
index 9902b57612..55d7b7e53a 100644
--- a/Userland/Libraries/LibJS/Runtime/VM.cpp
+++ b/Userland/Libraries/LibJS/Runtime/VM.cpp
@@ -662,7 +662,7 @@ void VM::ordinary_call_bind_this(FunctionObject& function, ExecutionContext& cal
callee_context.this_value = this_value;
}
-Value VM::call_internal(FunctionObject& function, Value this_value, Optional<MarkedValueList> arguments)
+ThrowCompletionOr<Value> VM::call_internal(FunctionObject& function, Value this_value, Optional<MarkedValueList> arguments)
{
VERIFY(!exception());
VERIFY(!this_value.is_empty());
@@ -680,8 +680,8 @@ Value VM::call_internal(FunctionObject& function, Value this_value, Optional<Mar
// This needs to be moved to NativeFunction/OrdinaryFunctionObject's construct() (10.2.2 [[Construct]])
ExecutionContext callee_context(heap());
prepare_for_ordinary_call(function, callee_context, nullptr);
- if (exception())
- return {};
+ if (auto* exception = this->exception())
+ return JS::throw_completion(exception->value());
ScopeGuard pop_guard = [&] {
pop_execution_context();
@@ -696,10 +696,13 @@ Value VM::call_internal(FunctionObject& function, Value this_value, Optional<Mar
if (callee_context.lexical_environment)
ordinary_call_bind_this(function, callee_context, this_value);
- if (exception())
- return {};
+ if (auto* exception = this->exception())
+ return JS::throw_completion(exception->value());
- return function.call();
+ auto result = function.call();
+ if (auto* exception = this->exception())
+ return JS::throw_completion(exception->value());
+ return result;
}
bool VM::in_strict_mode() const
diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h
index f666344b7c..4fa6d89e48 100644
--- a/Userland/Libraries/LibJS/Runtime/VM.h
+++ b/Userland/Libraries/LibJS/Runtime/VM.h
@@ -255,7 +255,7 @@ public:
Value get_new_target();
template<typename... Args>
- [[nodiscard]] ALWAYS_INLINE Value call(FunctionObject& function, Value this_value, Args... args)
+ [[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> call(FunctionObject& function, Value this_value, Args... args)
{
if constexpr (sizeof...(Args) > 0) {
MarkedValueList arglist { heap() };
@@ -289,7 +289,7 @@ private:
void ordinary_call_bind_this(FunctionObject&, ExecutionContext&, Value this_argument);
- [[nodiscard]] Value call_internal(FunctionObject&, Value this_value, Optional<MarkedValueList> arguments);
+ [[nodiscard]] ThrowCompletionOr<Value> call_internal(FunctionObject&, Value this_value, Optional<MarkedValueList> arguments);
void prepare_for_ordinary_call(FunctionObject&, ExecutionContext& callee_context, Object* new_target);
Exception* m_exception { nullptr };
@@ -327,13 +327,13 @@ private:
};
template<>
-[[nodiscard]] ALWAYS_INLINE Value VM::call(FunctionObject& function, Value this_value, MarkedValueList arguments) { return call_internal(function, this_value, move(arguments)); }
+[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> VM::call(FunctionObject& function, Value this_value, MarkedValueList arguments) { return call_internal(function, this_value, move(arguments)); }
template<>
-[[nodiscard]] ALWAYS_INLINE Value VM::call(FunctionObject& function, Value this_value, Optional<MarkedValueList> arguments) { return call_internal(function, this_value, move(arguments)); }
+[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> VM::call(FunctionObject& function, Value this_value, Optional<MarkedValueList> arguments) { return call_internal(function, this_value, move(arguments)); }
template<>
-[[nodiscard]] ALWAYS_INLINE Value VM::call(FunctionObject& function, Value this_value) { return call(function, this_value, Optional<MarkedValueList> {}); }
+[[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> VM::call(FunctionObject& function, Value this_value) { return call(function, this_value, Optional<MarkedValueList> {}); }
ALWAYS_INLINE Heap& Cell::heap() const
{
diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp
index 0016c75c50..4c98b30faa 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Value.cpp
@@ -423,9 +423,7 @@ Value Value::to_primitive(GlobalObject& global_object, PreferredType preferred_t
return {};
if (to_primitive_method) {
auto hint = get_hint_for_preferred_type();
- auto result = vm.call(*to_primitive_method, *this, js_string(vm, hint));
- if (vm.exception())
- return {};
+ auto result = TRY_OR_DISCARD(vm.call(*to_primitive_method, *this, js_string(vm, hint)));
if (!result.is_object())
return result;
vm.throw_exception<TypeError>(global_object, ErrorType::ToPrimitiveReturnedObject, to_string_without_side_effects(), hint);
@@ -1298,9 +1296,7 @@ Value instance_of(GlobalObject& global_object, Value lhs, Value rhs)
if (vm.exception())
return {};
if (has_instance_method) {
- auto has_instance_result = vm.call(*has_instance_method, rhs, lhs);
- if (vm.exception())
- return {};
+ auto has_instance_result = TRY_OR_DISCARD(vm.call(*has_instance_method, rhs, lhs));
return Value(has_instance_result.to_boolean());
}
if (!rhs.is_function()) {
@@ -1618,16 +1614,14 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l
}
// 7.3.20 Invoke ( V, P [ , argumentsList ] ), https://tc39.es/ecma262/#sec-invoke
-Value Value::invoke_internal(GlobalObject& global_object, JS::PropertyName const& property_name, Optional<MarkedValueList> arguments)
+ThrowCompletionOr<Value> Value::invoke_internal(GlobalObject& global_object, JS::PropertyName const& property_name, Optional<MarkedValueList> arguments)
{
auto& vm = global_object.vm();
auto property = get(global_object, property_name);
- if (vm.exception())
- return {};
- if (!property.is_function()) {
- vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, property.to_string_without_side_effects());
- return {};
- }
+ if (auto* exception = vm.exception())
+ return throw_completion(exception->value());
+ if (!property.is_function())
+ return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, property.to_string_without_side_effects());
return vm.call(property.as_function(), *this, move(arguments));
}
diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h
index a3dd6ca38b..c8e4528795 100644
--- a/Userland/Libraries/LibJS/Runtime/Value.h
+++ b/Userland/Libraries/LibJS/Runtime/Value.h
@@ -292,12 +292,12 @@ public:
bool operator==(Value const&) const;
template<typename... Args>
- [[nodiscard]] ALWAYS_INLINE Value invoke(GlobalObject& global_object, PropertyName const& property_name, Args... args);
+ [[nodiscard]] ALWAYS_INLINE ThrowCompletionOr<Value> invoke(GlobalObject& global_object, PropertyName const& property_name, Args... args);
private:
Type m_type { Type::Empty };
- [[nodiscard]] Value invoke_internal(GlobalObject& global_object, PropertyName const&, Optional<MarkedValueList> arguments);
+ [[nodiscard]] ThrowCompletionOr<Value> invoke_internal(GlobalObject& global_object, PropertyName const&, Optional<MarkedValueList> arguments);
i32 to_i32_slow_case(GlobalObject&) const;
diff --git a/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp b/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp
index 83af5b3e6c..23655100e7 100644
--- a/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp
@@ -72,8 +72,8 @@ Value WeakMapConstructor::construct(FunctionObject& new_target)
auto value = iterator_value.as_object().get(1);
if (vm.exception())
return IterationDecision::Break;
- (void)vm.call(adder.as_function(), Value(weak_map), key, value);
- return vm.exception() ? IterationDecision::Break : IterationDecision::Continue;
+ auto result = vm.call(adder.as_function(), Value(weak_map), key, value);
+ return result.is_error() ? IterationDecision::Break : IterationDecision::Continue;
});
if (vm.exception())
return {};
diff --git a/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp b/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp
index 803db74d88..d095528abc 100644
--- a/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/WeakSetConstructor.cpp
@@ -64,8 +64,8 @@ Value WeakSetConstructor::construct(FunctionObject& new_target)
get_iterator_values(global_object, vm.argument(0), [&](Value iterator_value) {
if (vm.exception())
return IterationDecision::Break;
- (void)vm.call(adder.as_function(), Value(weak_set), iterator_value);
- return vm.exception() ? IterationDecision::Break : IterationDecision::Continue;
+ auto result = vm.call(adder.as_function(), Value(weak_set), iterator_value);
+ return result.is_error() ? IterationDecision::Break : IterationDecision::Continue;
});
if (vm.exception())
return {};