ソースを参照

LibJS: Convert Object::set() to ThrowCompletionOr

Linus Groh 3 年 前
コミット
1d45541278

+ 2 - 2
Userland/Libraries/LibJS/Bytecode/Op.cpp

@@ -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));
     }
     }
 }
 }
 
 

+ 4 - 2
Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp

@@ -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);
             }
             }

+ 4 - 12
Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp

@@ -74,9 +74,7 @@ Value ArrayConstructor::construct(FunctionObject& new_target)
                 return {};
                 return {};
             }
             }
         }
         }
-        array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(array->set(vm.names.length, Value(int_length), Object::ShouldThrowExceptions::Yes));
         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);
-                if (vm.exception())
-                    return {};
+                TRY_OR_DISCARD(array_object.set(vm.names.length, Value(k), Object::ShouldThrowExceptions::Yes));
                 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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(array_object.set(vm.names.length, Value(length), Object::ShouldThrowExceptions::Yes));
 
 
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(array_object.set(vm.names.length, Value(vm.argument_count()), Object::ShouldThrowExceptions::Yes));
     return array;
     return array;
 }
 }
 
 

+ 33 - 81
Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp

@@ -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) {
-        this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (size_t i = 0; i < argument_count; ++i)
+        TRY_OR_DISCARD(this_object->set(length + i, vm.argument(i), Object::ShouldThrowExceptions::Yes));
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_object->set(vm.names.length, new_length_value, Object::ShouldThrowExceptions::Yes));
     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);
-                if (vm.exception())
-                    return {};
+                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())
                 if (vm.exception())
@@ -384,16 +377,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::unshift)
             }
             }
         }
         }
 
 
-        for (size_t j = 0; j < arg_count; j++) {
-            this_object->set(j, vm.argument(j), Object::ShouldThrowExceptions::Yes);
-            if (vm.exception())
-                return {};
-        }
+        for (size_t j = 0; j < arg_count; j++)
+            TRY_OR_DISCARD(this_object->set(j, vm.argument(j), Object::ShouldThrowExceptions::Yes));
     }
     }
 
 
-    this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes));
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_object->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes));
     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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(this_object->set(vm.names.length, Value(0), Object::ShouldThrowExceptions::Yes));
         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);
-            if (vm.exception())
-                return {};
+            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())
             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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_object->set(vm.names.length, Value(length - 1), Object::ShouldThrowExceptions::Yes));
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(new_array->set(vm.names.length, Value(n), Object::ShouldThrowExceptions::Yes));
     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);
-    if (vm.exception())
-        return {};
-
+    TRY_OR_DISCARD(new_array->set(vm.names.length, Value(index), Object::ShouldThrowExceptions::Yes));
     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);
-            if (vm.exception())
-                return {};
-            this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes));
+            TRY_OR_DISCARD(this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes));
         } else if (!lower_exists && upper_exists) {
         } else if (!lower_exists && upper_exists) {
-            this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(this_object->set(lower, upper_value, Object::ShouldThrowExceptions::Yes));
             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);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(this_object->set(upper, lower_value, Object::ShouldThrowExceptions::Yes));
         }
         }
     }
     }
 
 
@@ -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) {
-        object->set(j, items[j], Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (size_t j = 0; j < items.size(); ++j)
+        TRY_OR_DISCARD(object->set(j, items[j], Object::ShouldThrowExceptions::Yes));
 
 
     // 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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(removed_elements->set(vm.names.length, Value(actual_delete_count), Object::ShouldThrowExceptions::Yes));
 
 
     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) {
-        this_object->set(actual_start + i, vm.argument(i + 2), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (u64 i = 0; i < insert_count; ++i)
+        TRY_OR_DISCARD(this_object->set(actual_start + i, vm.argument(i + 2), Object::ShouldThrowExceptions::Yes));
 
 
-    this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_object->set(vm.names.length, Value(new_length), Object::ShouldThrowExceptions::Yes));
 
 
     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++) {
-        this_object->set(i, vm.argument(0), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (u64 i = from; i < to; i++)
+        TRY_OR_DISCARD(this_object->set(i, vm.argument(0), Object::ShouldThrowExceptions::Yes));
 
 
     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);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(this_object->set(to_i, from_value, Object::ShouldThrowExceptions::Yes));
         } else {
         } else {
             this_object->delete_property_or_throw(to_i);
             this_object->delete_property_or_throw(to_i);
             if (vm.exception())
             if (vm.exception())

+ 2 - 2
Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp

@@ -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);
-    if (vm.exception())
+    auto result_or_error = global_object.set(name, value, Object::ShouldThrowExceptions::Yes);
+    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);

+ 3 - 4
Userland/Libraries/LibJS/Runtime/Object.cpp

@@ -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 {};
+        return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectSetReturnedFalse);
     }
     }
 
 
     // 6. Return success.
     // 6. Return success.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Object.h

@@ -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);

+ 1 - 3
Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp

@@ -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);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(to->set(property_name, prop_value, Object::ShouldThrowExceptions::Yes));
         }
         }
     }
     }
 
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp

@@ -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;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp

@@ -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&)>;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Reference.cpp

@@ -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;
     }
     }
 
 

+ 1 - 3
Userland/Libraries/LibJS/Runtime/RegExpObject.cpp

@@ -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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
 
 
     return this;
     return this;
 }
 }

+ 14 - 38
Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp

@@ -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);
-    if (auto* exception = vm.exception())
-        return throw_completion(exception->value());
+    TRY(regexp_object.set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
     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) {
-                regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes);
-                if (vm.exception())
-                    return {};
-            }
+            if (global || sticky)
+                TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
 
 
             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);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
 
 
             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) {
-        regexp_object.set(vm.names.lastIndex, Value(end_index), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    if (global || sticky)
+        TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(end_index), Object::ShouldThrowExceptions::Yes));
 
 
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
 
 
     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);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(matcher->set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
 
 
     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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
     }
     }
 
 
     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))) {
-        regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    if (!same_value(previous_last_index, Value(0)))
+        TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
 
 
     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)) {
-        regexp_object->set(vm.names.lastIndex, previous_last_index, Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    if (!same_value(current_last_index, previous_last_index))
+        TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, previous_last_index, Object::ShouldThrowExceptions::Yes));
 
 
     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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(splitter->set(vm.names.lastIndex, Value(next_search_from), Object::ShouldThrowExceptions::Yes));
 
 
         auto result = regexp_exec(global_object, *splitter, string);
         auto result = regexp_exec(global_object, *splitter, string);
         if (vm.exception())
         if (vm.exception())

+ 1 - 3
Userland/Libraries/LibJS/Runtime/RegExpStringIteratorPrototype.cpp

@@ -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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(iterator->regexp_object().set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
     }
     }
 
 
     return create_iterator_result_object(global_object, match, false);
     return create_iterator_result_object(global_object, match, false);

+ 4 - 4
Userland/Libraries/LibJS/Runtime/TypedArray.cpp

@@ -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);
-        if (vm.exception())
+        auto result_or_error = typed_array.set(k, value, Object::ShouldThrowExceptions::Yes);
+        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);
-        if (vm.exception())
+        auto result_or_error = typed_array.set(k, value, Object::ShouldThrowExceptions::Yes);
+        if (result_or_error.is_error())
             return;
             return;
     }
     }
 }
 }

+ 3 - 9
Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp

@@ -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);
-            if (vm.exception())
-                return {};
+            TRY_OR_DISCARD(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));
         }
         }
 
 
         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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(target_object->set(k, mapped_value, Object::ShouldThrowExceptions::Yes));
     }
     }
 
 
     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);
-        if (vm.exception())
-            return {};
+        auto success = TRY_OR_DISCARD(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes));
         if (!success) {
         if (!success) {
             vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayFailedSettingIndex, k);
             vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayFailedSettingIndex, k);
             return {};
             return {};

+ 9 - 17
Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp

@@ -298,11 +298,8 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::fill)
         return {};
         return {};
     }
     }
 
 
-    for (; k < final; ++k) {
-        typed_array->set(k, value, Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (; k < final; ++k)
+        TRY_OR_DISCARD(typed_array->set(k, value, Object::ShouldThrowExceptions::Yes));
 
 
     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) {
-        typed_array->set(j, items[j], Object::ShouldThrowExceptions::Yes);
-        if (vm.exception())
-            return {};
-    }
+    for (j = 0; j < items.size(); ++j)
+        TRY_OR_DISCARD(typed_array->set(j, items[j], Object::ShouldThrowExceptions::Yes));
 
 
     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);
-        if (vm.exception())
-            return {};
+        TRY_OR_DISCARD(return_array->set(i, mapped_value, Object::ShouldThrowExceptions::Yes));
 
 
         // e. Set k to k + 1.
         // e. Set k to k + 1.
     }
     }

+ 3 - 3
Userland/Libraries/LibWeb/Bindings/WindowObject.cpp

@@ -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);
-        options->set("top", vm.argument(1), ShouldThrowExceptions::No);
-        options->set("behavior", JS::js_string(vm, "auto"), ShouldThrowExceptions::No);
+        MUST(options->set("left", vm.argument(0), ShouldThrowExceptions::No));
+        MUST(options->set("top", vm.argument(1), 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"));