LibJS: Convert Object::set() to ThrowCompletionOr

This commit is contained in:
Linus Groh 2021-10-03 00:32:43 +01:00
parent b7e5f08e56
commit 1d45541278
Notes: sideshowbarker 2024-07-18 03:07:37 +09:00
18 changed files with 89 additions and 188 deletions

View File

@ -249,7 +249,7 @@ void GetById::execute_impl(Bytecode::Interpreter& interpreter) const
void PutById::execute_impl(Bytecode::Interpreter& interpreter) const void PutById::execute_impl(Bytecode::Interpreter& interpreter) const
{ {
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object()))
object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes); MUST(object->set(interpreter.current_executable().get_string(m_property), interpreter.accumulator(), Object::ShouldThrowExceptions::Yes));
} }
void Jump::execute_impl(Bytecode::Interpreter& interpreter) const void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
@ -447,7 +447,7 @@ void PutByValue::execute_impl(Bytecode::Interpreter& interpreter) const
auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object()); auto property_key = interpreter.reg(m_property).to_property_key(interpreter.global_object());
if (interpreter.vm().exception()) if (interpreter.vm().exception())
return; return;
object->set(property_key, interpreter.accumulator(), Object::ShouldThrowExceptions::Yes); MUST(object->set(property_key, interpreter.accumulator(), Object::ShouldThrowExceptions::Yes));
} }
} }

View File

@ -71,7 +71,8 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_set(PropertyName const& proper
// 3. If isMapped is true, then // 3. If isMapped is true, then
if (is_mapped) { if (is_mapped) {
// a. Let setStatus be Set(map, P, V, false). // a. Let setStatus be Set(map, P, V, false).
auto set_status = m_parameter_map->set(property_name, value, Object::ShouldThrowExceptions::No); auto set_status = MUST(m_parameter_map->set(property_name, value, Object::ShouldThrowExceptions::No));
// b. Assert: setStatus is true because formal parameters mapped by argument objects are always writable. // b. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
VERIFY(set_status); VERIFY(set_status);
} }
@ -163,7 +164,8 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyNa
// i. If Desc.[[Value]] is present, then // i. If Desc.[[Value]] is present, then
if (descriptor.value.has_value()) { if (descriptor.value.has_value()) {
// 1. Let setStatus be Set(map, P, Desc.[[Value]], false). // 1. Let setStatus be Set(map, P, Desc.[[Value]], false).
bool set_status = map.set(property_name, descriptor.value.value(), Object::ShouldThrowExceptions::No); bool set_status = MUST(map.set(property_name, descriptor.value.value(), Object::ShouldThrowExceptions::No));
// 2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable. // 2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
VERIFY(set_status); VERIFY(set_status);
} }

View File

@ -74,9 +74,7 @@ Value ArrayConstructor::construct(FunctionObject& new_target)
return {}; return {};
} }
} }
array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return array; return array;
} }
@ -137,9 +135,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
return {}; return {};
if (!next) { if (!next) {
array_object.set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(array_object.set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return array; return array;
} }
@ -198,9 +194,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
array_object.create_data_property_or_throw(k, mapped_value); array_object.create_data_property_or_throw(k, mapped_value);
} }
array_object.set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(array_object.set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return array; return array;
} }
@ -234,9 +228,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::of)
if (vm.exception()) if (vm.exception())
return {}; return {};
} }
array_object.set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(array_object.set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return array; return array;
} }

View File

@ -338,15 +338,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
vm.throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize); vm.throw_exception<TypeError>(global_object, ErrorType::ArrayMaxSize);
return {}; return {};
} }
for (size_t i = 0; i < argument_count; ++i) { for (size_t i = 0; i < argument_count; ++i)
this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
auto new_length_value = Value(new_length); auto new_length_value = Value(new_length);
this_object->set(vm.names.length, new_length_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, new_length_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return new_length_value; return new_length_value;
} }
@ -374,9 +369,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
return {}; return {};
if (from_present) { if (from_present) {
auto from_value = TRY_OR_DISCARD(this_object->get(from)); auto from_value = TRY_OR_DISCARD(this_object->get(from));
this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} else { } else {
this_object->delete_property_or_throw(to); this_object->delete_property_or_throw(to);
if (vm.exception()) if (vm.exception())
@ -384,16 +377,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
} }
} }
for (size_t j = 0; j < arg_count; j++) { for (size_t j = 0; j < arg_count; j++)
this_object->set(j, vm.argument(j), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(j, vm.argument(j), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
} }
this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return Value(new_length); return Value(new_length);
} }
@ -405,7 +393,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
return {}; return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
if (length == 0) { if (length == 0) {
this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
return js_undefined(); return js_undefined();
} }
auto index = length - 1; auto index = length - 1;
@ -413,9 +401,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
this_object->delete_property_or_throw(index); this_object->delete_property_or_throw(index);
if (vm.exception()) if (vm.exception())
return {}; return {};
this_object->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return element; return element;
} }
@ -427,9 +413,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
return {}; return {};
auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object)); auto length = TRY_OR_DISCARD(length_of_array_like(global_object, *this_object));
if (length == 0) { if (length == 0) {
this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return js_undefined(); return js_undefined();
} }
auto first = TRY_OR_DISCARD(this_object->get(0)); auto first = TRY_OR_DISCARD(this_object->get(0));
@ -441,9 +425,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
return {}; return {};
if (from_present) { if (from_present) {
auto from_value = TRY_OR_DISCARD(this_object->get(from)); auto from_value = TRY_OR_DISCARD(this_object->get(from));
this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} else { } else {
this_object->delete_property_or_throw(to); this_object->delete_property_or_throw(to);
if (vm.exception()) if (vm.exception())
@ -455,9 +437,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
if (vm.exception()) if (vm.exception())
return {}; return {};
this_object->set(vm.names.length, Value(length - 1), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(length - 1), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return first; return first;
} }
@ -631,9 +611,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::concat)
return {}; return {};
} }
new_array->set(vm.names.length, Value(n), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(new_array->set(vm.names.length, Value(n), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return Value(new_array); return Value(new_array);
} }
@ -703,10 +681,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::slice)
++index; ++index;
} }
new_array->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(new_array->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return new_array; return new_array;
} }
@ -1001,16 +976,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
upper_value = TRY_OR_DISCARD(this_object->get(upper)); upper_value = TRY_OR_DISCARD(this_object->get(upper));
if (lower_exists && upper_exists) { if (lower_exists && upper_exists) {
this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception()) TRY_OR_DISCARD(this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes));
return {};
this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes);
if (vm.exception())
return {};
} else if (!lower_exists && upper_exists) { } else if (!lower_exists && upper_exists) {
this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
this_object->delete_property_or_throw(upper); this_object->delete_property_or_throw(upper);
if (vm.exception()) if (vm.exception())
return {}; return {};
@ -1018,9 +987,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
this_object->delete_property_or_throw(lower); this_object->delete_property_or_throw(lower);
if (vm.exception()) if (vm.exception())
return {}; return {};
this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
} }
@ -1172,11 +1139,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
if (vm.exception()) if (vm.exception())
return {}; return {};
for (size_t j = 0; j < items.size(); ++j) { for (size_t j = 0; j < items.size(); ++j)
object->set(j, items[j], Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(object->set(j, items[j], Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
// The empty parts of the array are always sorted to the end, regardless of the // The empty parts of the array are always sorted to the end, regardless of the
// compare function. FIXME: For performance, a similar process could be used // compare function. FIXME: For performance, a similar process could be used
@ -1636,9 +1600,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
} }
} }
removed_elements->set(vm.names.length, Value(actual_delete_count), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(removed_elements->set(vm.names.length, Value(actual_delete_count), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
if (insert_count < actual_delete_count) { if (insert_count < actual_delete_count) {
for (u64 i = actual_start; i < initial_length - actual_delete_count; ++i) { for (u64 i = actual_start; i < initial_length - actual_delete_count; ++i) {
@ -1651,12 +1613,12 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
if (from_present) { if (from_present) {
auto from_value = TRY_OR_DISCARD(this_object->get(from)); auto from_value = TRY_OR_DISCARD(this_object->get(from));
this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
} else { } else {
this_object->delete_property_or_throw(to); this_object->delete_property_or_throw(to);
if (vm.exception())
return {};
} }
if (vm.exception())
return {};
} }
for (u64 i = initial_length; i > new_length; --i) { for (u64 i = initial_length; i > new_length; --i) {
@ -1675,24 +1637,19 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
if (from_present) { if (from_present) {
auto from_value = TRY_OR_DISCARD(this_object->get(from_index)); auto from_value = TRY_OR_DISCARD(this_object->get(from_index));
this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(to, from_value, Object::ShouldThrowExceptions::Yes));
} else { } else {
this_object->delete_property_or_throw(to); this_object->delete_property_or_throw(to);
if (vm.exception())
return {};
} }
if (vm.exception())
return {};
} }
} }
for (u64 i = 0; i < insert_count; ++i) { for (u64 i = 0; i < insert_count; ++i)
this_object->set(actual_start + i, vm.argument(i + 2), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(actual_start + i, vm.argument(i + 2), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return removed_elements; return removed_elements;
} }
@ -1738,11 +1695,8 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
else else
to = min(relative_end, length); to = min(relative_end, length);
for (u64 i = from; i < to; i++) { for (u64 i = from; i < to; i++)
this_object->set(i, vm.argument(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(i, vm.argument(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
return this_object; return this_object;
} }
@ -1946,9 +1900,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::copy_within)
if (from_present) { if (from_present) {
auto from_value = TRY_OR_DISCARD(this_object->get(from_i)); auto from_value = TRY_OR_DISCARD(this_object->get(from_i));
this_object->set(to_i, from_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(this_object->set(to_i, from_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} else { } else {
this_object->delete_property_or_throw(to_i); this_object->delete_property_or_throw(to_i);
if (vm.exception()) if (vm.exception())

View File

@ -201,8 +201,8 @@ void GlobalEnvironment::create_global_function_binding(FlyString const& name, Va
global_object.define_property_or_throw(name, desc); global_object.define_property_or_throw(name, desc);
if (vm.exception()) if (vm.exception())
return; return;
global_object.set(name, value, Object::ShouldThrowExceptions::Yes); auto result_or_error = global_object.set(name, value, Object::ShouldThrowExceptions::Yes);
if (vm.exception()) if (result_or_error.is_error())
return; return;
if (!m_var_names.contains_slow(name)) if (!m_var_names.contains_slow(name))
m_var_names.append(name); m_var_names.append(name);

View File

@ -91,7 +91,7 @@ ThrowCompletionOr<Value> Object::get(PropertyName const& property_name) const
// 7.3.3 GetV ( V, P ) is defined as Value::get(). // 7.3.3 GetV ( V, P ) is defined as Value::get().
// 7.3.4 Set ( O, P, V, Throw ), https://tc39.es/ecma262/#sec-set-o-p-v-throw // 7.3.4 Set ( O, P, V, Throw ), https://tc39.es/ecma262/#sec-set-o-p-v-throw
bool Object::set(PropertyName const& property_name, Value value, ShouldThrowExceptions throw_exceptions) ThrowCompletionOr<bool> Object::set(PropertyName const& property_name, Value value, ShouldThrowExceptions throw_exceptions)
{ {
VERIFY(!value.is_empty()); VERIFY(!value.is_empty());
auto& vm = this->vm(); auto& vm = this->vm();
@ -104,13 +104,12 @@ bool Object::set(PropertyName const& property_name, Value value, ShouldThrowExce
// 3. Assert: Type(Throw) is Boolean. // 3. Assert: Type(Throw) is Boolean.
// 4. Let success be ? O.[[Set]](P, V, O). // 4. Let success be ? O.[[Set]](P, V, O).
auto success = TRY_OR_DISCARD(internal_set(property_name, value, this)); auto success = TRY(internal_set(property_name, value, this));
// 5. If success is false and Throw is true, throw a TypeError exception. // 5. If success is false and Throw is true, throw a TypeError exception.
if (!success && throw_exceptions == ShouldThrowExceptions::Yes) { if (!success && throw_exceptions == ShouldThrowExceptions::Yes) {
// FIXME: Improve/contextualize error message // FIXME: Improve/contextualize error message
vm.throw_exception<TypeError>(global_object(), ErrorType::ObjectSetReturnedFalse); return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectSetReturnedFalse);
return {};
} }
// 6. Return success. // 6. Return success.

View File

@ -76,7 +76,7 @@ public:
// 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects // 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects
ThrowCompletionOr<Value> get(PropertyName const&) const; ThrowCompletionOr<Value> get(PropertyName const&) const;
bool set(PropertyName const&, Value, ShouldThrowExceptions); ThrowCompletionOr<bool> set(PropertyName const&, Value, ShouldThrowExceptions);
bool create_data_property(PropertyName const&, Value); bool create_data_property(PropertyName const&, Value);
bool create_method_property(PropertyName const&, Value); bool create_method_property(PropertyName const&, Value);
bool create_data_property_or_throw(PropertyName const&, Value); bool create_data_property_or_throw(PropertyName const&, Value);

View File

@ -489,9 +489,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign)
auto prop_value = TRY_OR_DISCARD(from->get(property_name)); auto prop_value = TRY_OR_DISCARD(from->get(property_name));
// b. Perform ? Set(to, nextKey, propValue, true). // b. Perform ? Set(to, nextKey, propValue, true).
to->set(property_name, prop_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(to->set(property_name, prop_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
} }

View File

@ -77,10 +77,10 @@ void ObjectEnvironment::set_mutable_binding(GlobalObject& global_object, FlyStri
return; return;
} }
auto result = m_binding_object.set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No); auto result_or_error = m_binding_object.set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No);
// Note: Nothing like this in the spec, this is here to produce nicer errors instead of the generic one thrown by Object::set(). // Note: Nothing like this in the spec, this is here to produce nicer errors instead of the generic one thrown by Object::set().
if (!result && strict) { if (result_or_error.is_error() && strict) {
auto property_or_error = m_binding_object.internal_get_own_property(name); auto property_or_error = m_binding_object.internal_get_own_property(name);
if (property_or_error.is_error()) if (property_or_error.is_error())
return; return;

View File

@ -71,7 +71,7 @@ static void set_iterator_record_complete(GlobalObject& global_object, Object& it
// FIXME: Create a native iterator structure with the [[Done]] internal slot. For now, temporarily clear // FIXME: Create a native iterator structure with the [[Done]] internal slot. For now, temporarily clear
// the exception so we can access the "done" property on the iterator object. // the exception so we can access the "done" property on the iterator object.
TemporaryClearException clear_exception(vm); TemporaryClearException clear_exception(vm);
iterator_record.set(vm.names.done, Value(true), Object::ShouldThrowExceptions::No); MUST(iterator_record.set(vm.names.done, Value(true), Object::ShouldThrowExceptions::No));
} }
using EndOfElementsCallback = Function<Value(PromiseValueList&)>; using EndOfElementsCallback = Function<Value(PromiseValueList&)>;

View File

@ -26,7 +26,7 @@ void Reference::put_value(GlobalObject& global_object, Value value)
throw_reference_error(global_object); throw_reference_error(global_object);
return; return;
} }
global_object.set(m_name, value, Object::ShouldThrowExceptions::No); MUST(global_object.set(m_name, value, Object::ShouldThrowExceptions::No));
return; return;
} }

View File

@ -183,9 +183,7 @@ RegExpObject* RegExpObject::regexp_initialize(GlobalObject& global_object, Value
m_flags = move(f); m_flags = move(f);
m_regex = move(regex); m_regex = move(regex);
set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return this; return this;
} }

View File

@ -87,9 +87,7 @@ static ThrowCompletionOr<void> increment_last_index(GlobalObject& global_object,
return throw_completion(exception->value()); return throw_completion(exception->value());
last_index = advance_string_index(string, last_index, unicode); last_index = advance_string_index(string, last_index, unicode);
regexp_object.set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes); TRY(regexp_object.set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
return {}; return {};
} }
@ -190,11 +188,8 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege
while (true) { while (true) {
if (last_index > string.length_in_code_units()) { if (last_index > string.length_in_code_units()) {
if (global || sticky) { if (global || sticky)
regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
return js_null(); return js_null();
} }
@ -206,9 +201,7 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege
break; break;
if (sticky) { if (sticky) {
regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return js_null(); return js_null();
} }
@ -228,11 +221,8 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege
end_index = string_view.code_unit_offset_of(end_index); end_index = string_view.code_unit_offset_of(end_index);
} }
if (global || sticky) { if (global || sticky)
regexp_object.set(vm.names.lastIndex, Value(end_index), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(end_index), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
auto* array = Array::create(global_object, result.n_named_capture_groups + 1); auto* array = Array::create(global_object, result.n_named_capture_groups + 1);
if (vm.exception()) if (vm.exception())
@ -437,9 +427,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match)
return result; return result;
} }
regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
auto* array = Array::create(global_object, 0); auto* array = Array::create(global_object, 0);
if (vm.exception()) if (vm.exception())
@ -513,9 +501,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
if (vm.exception()) if (vm.exception())
return {}; return {};
matcher->set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(matcher->set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
return RegExpStringIterator::create(global_object, *matcher, move(string), global, unicode); return RegExpStringIterator::create(global_object, *matcher, move(string), global, unicode);
} }
@ -550,9 +536,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
if (global) { if (global) {
unicode = TRY_OR_DISCARD(regexp_object->get(vm.names.unicode)).to_boolean(); unicode = TRY_OR_DISCARD(regexp_object->get(vm.names.unicode)).to_boolean();
regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
MarkedValueList results(vm.heap()); MarkedValueList results(vm.heap());
@ -678,22 +662,16 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search)
return {}; return {};
auto previous_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)); auto previous_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex));
if (!same_value(previous_last_index, Value(0))) { if (!same_value(previous_last_index, Value(0)))
regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
auto result = regexp_exec(global_object, *regexp_object, move(string)); auto result = regexp_exec(global_object, *regexp_object, move(string));
if (vm.exception()) if (vm.exception())
return {}; return {};
auto current_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex)); auto current_last_index = TRY_OR_DISCARD(regexp_object->get(vm.names.lastIndex));
if (!same_value(current_last_index, previous_last_index)) { if (!same_value(current_last_index, previous_last_index))
regexp_object->set(vm.names.lastIndex, previous_last_index, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, previous_last_index, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
if (result.is_null()) if (result.is_null())
return Value(-1); return Value(-1);
@ -762,9 +740,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
size_t next_search_from = 0; // 'q' in the spec. size_t next_search_from = 0; // 'q' in the spec.
while (next_search_from < string_view.length_in_code_units()) { while (next_search_from < string_view.length_in_code_units()) {
splitter->set(vm.names.lastIndex, Value(next_search_from), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(splitter->set(vm.names.lastIndex, Value(next_search_from), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
auto result = regexp_exec(global_object, *splitter, string); auto result = regexp_exec(global_object, *splitter, string);
if (vm.exception()) if (vm.exception())

View File

@ -69,9 +69,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpStringIteratorPrototype::next)
last_index = advance_string_index(iterator->string().view(), last_index, iterator->unicode()); last_index = advance_string_index(iterator->string().view(), last_index, iterator->unicode());
iterator->regexp_object().set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(iterator->regexp_object().set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
return create_iterator_result_object(global_object, match, false); return create_iterator_result_object(global_object, match, false);

View File

@ -196,8 +196,8 @@ static void initialize_typed_array_from_array_like(GlobalObject& global_object,
if (value_or_error.is_error()) if (value_or_error.is_error())
return; return;
auto value = value_or_error.release_value(); auto value = value_or_error.release_value();
typed_array.set(k, value, Object::ShouldThrowExceptions::Yes); auto result_or_error = typed_array.set(k, value, Object::ShouldThrowExceptions::Yes);
if (vm.exception()) if (result_or_error.is_error())
return; return;
} }
} }
@ -230,8 +230,8 @@ static void initialize_typed_array_from_list(GlobalObject& global_object, TypedA
for (size_t k = 0; k < list.size(); k++) { for (size_t k = 0; k < list.size(); k++) {
auto value = list[k]; auto value = list[k];
typed_array.set(k, value, Object::ShouldThrowExceptions::Yes); auto result_or_error = typed_array.set(k, value, Object::ShouldThrowExceptions::Yes);
if (vm.exception()) if (result_or_error.is_error())
return; return;
} }
} }

View File

@ -96,9 +96,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k))); mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k)));
else else
mapped_value = k_value; mapped_value = k_value;
target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
return target_object; return target_object;
@ -120,9 +118,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k))); mapped_value = TRY_OR_DISCARD(vm.call(*map_fn, this_arg, k_value, Value(k)));
else else
mapped_value = k_value; mapped_value = k_value;
target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
} }
return target_object; return target_object;
@ -143,9 +139,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::of)
if (vm.exception()) if (vm.exception())
return {}; return {};
for (size_t k = 0; k < length; ++k) { for (size_t k = 0; k < length; ++k) {
auto success = new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes); auto success = TRY_OR_DISCARD(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
if (!success) { if (!success) {
vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayFailedSettingIndex, k); vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayFailedSettingIndex, k);
return {}; return {};

View File

@ -298,11 +298,8 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::fill)
return {}; return {};
} }
for (; k < final; ++k) { for (; k < final; ++k)
typed_array->set(k, value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(typed_array->set(k, value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
return typed_array; return typed_array;
} }
@ -918,7 +915,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice)
if (typed_array->element_name() != new_array->element_name()) { if (typed_array->element_name() != new_array->element_name()) {
for (i32 n = 0; k < final; ++k, ++n) { for (i32 n = 0; k < final; ++k, ++n) {
auto k_value = MUST(typed_array->get(k)); auto k_value = MUST(typed_array->get(k));
new_array->set(n, k_value, Object::ShouldThrowExceptions::Yes); MUST(new_array->set(n, k_value, Object::ShouldThrowExceptions::Yes));
} }
} else { } else {
auto element_size = typed_array->element_size(); auto element_size = typed_array->element_size();
@ -1080,11 +1077,8 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::sort)
return {}; return {};
u32 j; u32 j;
for (j = 0; j < items.size(); ++j) { for (j = 0; j < items.size(); ++j)
typed_array->set(j, items[j], Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(typed_array->set(j, items[j], Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
}
for (; j < length; ++j) { for (; j < length; ++j) {
typed_array->delete_property_or_throw(j); typed_array->delete_property_or_throw(j);
@ -1180,10 +1174,10 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reverse)
auto upper_value = MUST(typed_array->get(upper)); auto upper_value = MUST(typed_array->get(upper));
// f. Perform ! Set(O, lowerP, upperValue, true). // f. Perform ! Set(O, lowerP, upperValue, true).
typed_array->set(lower, upper_value, Object::ShouldThrowExceptions::Yes); MUST(typed_array->set(lower, upper_value, Object::ShouldThrowExceptions::Yes));
// g. Perform ! Set(O, upperP, lowerValue, true). // g. Perform ! Set(O, upperP, lowerValue, true).
typed_array->set(upper, lower_value, Object::ShouldThrowExceptions::Yes); MUST(typed_array->set(upper, lower_value, Object::ShouldThrowExceptions::Yes));
// h. Set lower to lower + 1. // h. Set lower to lower + 1.
} }
@ -1431,7 +1425,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
// 11. For each element e of kept, do // 11. For each element e of kept, do
for (auto& value : kept) { for (auto& value : kept) {
// a. Perform ! Set(A, ! ToString(𝔽(n)), e, true). // a. Perform ! Set(A, ! ToString(𝔽(n)), e, true).
filter_array->set(index, value, Object::ShouldThrowExceptions::Yes); MUST(filter_array->set(index, value, Object::ShouldThrowExceptions::Yes));
// b. Set n to n + 1. // b. Set n to n + 1.
++index; ++index;
@ -1478,9 +1472,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map)
auto mapped_value = TRY_OR_DISCARD(vm.call(*callback_function, this_value, value, Value((i32)i), typed_array)); 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). // d. Perform ? Set(A, Pk, mappedValue, true).
return_array->set(i, mapped_value, Object::ShouldThrowExceptions::Yes); TRY_OR_DISCARD(return_array->set(i, mapped_value, Object::ShouldThrowExceptions::Yes));
if (vm.exception())
return {};
// e. Set k to k + 1. // e. Set k to k + 1.
} }

View File

@ -673,9 +673,9 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::scroll_by)
} else if (vm.argument_count() >= 2) { } else if (vm.argument_count() >= 2) {
// We ignore arguments 2+ in line with behavior of Chrome and Firefox // We ignore arguments 2+ in line with behavior of Chrome and Firefox
options = JS::Object::create(global_object, nullptr); options = JS::Object::create(global_object, nullptr);
options->set("left", vm.argument(0), ShouldThrowExceptions::No); MUST(options->set("left", vm.argument(0), ShouldThrowExceptions::No));
options->set("top", vm.argument(1), ShouldThrowExceptions::No); MUST(options->set("top", vm.argument(1), ShouldThrowExceptions::No));
options->set("behavior", JS::js_string(vm, "auto"), ShouldThrowExceptions::No); MUST(options->set("behavior", JS::js_string(vm, "auto"), ShouldThrowExceptions::No));
} }
auto left_value = TRY_OR_DISCARD(options->get("left")); auto left_value = TRY_OR_DISCARD(options->get("left"));