소스 검색

LibJS: Remove implicit wrapping/unwrapping of completion records

This is an editorial change in the ECMA-262 spec, with similar changes
in some proposals.

See:
- https://github.com/tc39/ecma262/commit/7575f74
- https://github.com/tc39/proposal-array-grouping/commit/df899eb
- https://github.com/tc39/proposal-shadowrealm/commit/9eb5a12
- https://github.com/tc39/proposal-shadowrealm/commit/c81f527
Linus Groh 3 년 전
부모
커밋
9f3f3b0864
88개의 변경된 파일792개의 추가작업 그리고 735개의 파일을 삭제
  1. 3 2
      Tests/LibJS/test-js.cpp
  2. 109 110
      Userland/Libraries/LibJS/AST.cpp
  3. 1 1
      Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
  4. 3 2
      Userland/Libraries/LibJS/Contrib/Test262/$262Object.cpp
  5. 48 48
      Userland/Libraries/LibJS/CyclicModule.cpp
  6. 6 6
      Userland/Libraries/LibJS/CyclicModule.h
  7. 3 3
      Userland/Libraries/LibJS/Interpreter.cpp
  8. 1 1
      Userland/Libraries/LibJS/Interpreter.h
  9. 1 1
      Userland/Libraries/LibJS/Module.cpp
  10. 28 31
      Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
  11. 2 2
      Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp
  12. 20 21
      Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp
  13. 8 8
      Userland/Libraries/LibJS/Runtime/Array.cpp
  14. 3 3
      Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp
  15. 4 5
      Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
  16. 15 15
      Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp
  17. 35 36
      Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp
  18. 1 1
      Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.h
  19. 1 1
      Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp
  20. 1 1
      Userland/Libraries/LibJS/Runtime/BoundFunction.cpp
  21. 6 6
      Userland/Libraries/LibJS/Runtime/Completion.cpp
  22. 6 1
      Userland/Libraries/LibJS/Runtime/Completion.h
  23. 3 1
      Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
  24. 13 12
      Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp
  25. 34 25
      Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp
  26. 4 4
      Userland/Libraries/LibJS/Runtime/Error.cpp
  27. 5 5
      Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp
  28. 1 1
      Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp
  29. 8 8
      Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp
  30. 6 2
      Userland/Libraries/LibJS/Runtime/FunctionObject.cpp
  31. 2 2
      Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp
  32. 19 16
      Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp
  33. 1 1
      Userland/Libraries/LibJS/Runtime/GlobalObject.cpp
  34. 9 9
      Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp
  35. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/CollatorConstructor.cpp
  36. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp
  37. 6 6
      Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
  38. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp
  39. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp
  40. 3 3
      Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp
  41. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp
  42. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp
  43. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp
  44. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp
  45. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp
  46. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp
  47. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp
  48. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp
  49. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp
  50. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp
  51. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/Segmenter.cpp
  52. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp
  53. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp
  54. 11 11
      Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp
  55. 1 1
      Userland/Libraries/LibJS/Runtime/ModuleEnvironment.cpp
  56. 12 12
      Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp
  57. 5 5
      Userland/Libraries/LibJS/Runtime/NativeFunction.cpp
  58. 4 4
      Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp
  59. 31 22
      Userland/Libraries/LibJS/Runtime/Object.cpp
  60. 13 10
      Userland/Libraries/LibJS/Runtime/Object.h
  61. 11 11
      Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp
  62. 14 7
      Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp
  63. 38 21
      Userland/Libraries/LibJS/Runtime/Promise.cpp
  64. 3 3
      Userland/Libraries/LibJS/Runtime/Promise.h
  65. 33 33
      Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp
  66. 13 17
      Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp
  67. 5 5
      Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
  68. 2 2
      Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp
  69. 21 15
      Userland/Libraries/LibJS/Runtime/PromiseReaction.h
  70. 6 6
      Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
  71. 3 3
      Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp
  72. 3 3
      Userland/Libraries/LibJS/Runtime/ProxyConstructor.cpp
  73. 10 10
      Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
  74. 2 2
      Userland/Libraries/LibJS/Runtime/Realm.cpp
  75. 6 4
      Userland/Libraries/LibJS/Runtime/Reference.cpp
  76. 14 14
      Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
  77. 7 7
      Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp
  78. 4 4
      Userland/Libraries/LibJS/Runtime/StringObject.cpp
  79. 3 3
      Userland/Libraries/LibJS/Runtime/StringPrototype.cpp
  80. 13 13
      Userland/Libraries/LibJS/Runtime/TypedArray.h
  81. 3 6
      Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp
  82. 2 2
      Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
  83. 20 15
      Userland/Libraries/LibJS/Runtime/VM.cpp
  84. 12 12
      Userland/Libraries/LibJS/Runtime/Value.cpp
  85. 1 1
      Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp
  86. 24 27
      Userland/Libraries/LibJS/SourceTextModule.cpp
  87. 2 2
      Userland/Libraries/LibJS/SourceTextModule.h
  88. 1 2
      Userland/Libraries/LibJS/SyntheticModule.cpp

+ 3 - 2
Tests/LibJS/test-js.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -84,7 +84,8 @@ TESTJS_GLOBAL_FUNCTION(detach_array_buffer, detachArrayBuffer)
         return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "ArrayBuffer");
 
     auto& array_buffer_object = static_cast<JS::ArrayBuffer&>(array_buffer.as_object());
-    return JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1));
+    TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
+    return JS::js_null();
 }
 
 TESTJS_RUN_FILE_FUNCTION(String const& test_file, JS::Interpreter& interpreter, JS::ExecutionContext&)

+ 109 - 110
Userland/Libraries/LibJS/AST.cpp

@@ -105,7 +105,7 @@ Completion ScopeNode::evaluate_statements(Interpreter& interpreter, GlobalObject
 // BreakableStatement : IterationStatement
 static Completion labelled_evaluation(Interpreter& interpreter, GlobalObject& global_object, IterationStatement const& statement, Vector<FlyString> const& label_set)
 {
-    // 1. Let stmtResult be LoopEvaluation of IterationStatement with argument labelSet.
+    // 1. Let stmtResult be Completion(LoopEvaluation of IterationStatement with argument labelSet).
     auto result = statement.loop_evaluation(interpreter, global_object, label_set);
 
     // 2. If stmtResult.[[Type]] is break, then
@@ -118,7 +118,7 @@ static Completion labelled_evaluation(Interpreter& interpreter, GlobalObject& gl
         }
     }
 
-    // 3. Return Completion(stmtResult).
+    // 3. Return ? stmtResult.
     return result;
 }
 
@@ -139,7 +139,7 @@ static Completion labelled_evaluation(Interpreter& interpreter, GlobalObject& gl
         }
     }
 
-    // 3. Return Completion(stmtResult).
+    // 3. Return ? stmtResult.
     return result;
 }
 
@@ -160,7 +160,7 @@ static Completion labelled_evaluation(Interpreter& interpreter, GlobalObject& gl
         new_label_set->append(label);
     }
 
-    // 3. Let stmtResult be LabelledEvaluation of LabelledItem with argument newLabelSet.
+    // 3. Let stmtResult be Completion(LabelledEvaluation of LabelledItem with argument newLabelSet).
     Completion result;
     if (is<IterationStatement>(labelled_item))
         result = labelled_evaluation(interpreter, global_object, static_cast<IterationStatement const&>(labelled_item), *new_label_set);
@@ -177,7 +177,7 @@ static Completion labelled_evaluation(Interpreter& interpreter, GlobalObject& gl
         result = normal_completion(result.value());
     }
 
-    // 5. Return Completion(stmtResult).
+    // 5. Return ? stmtResult.
     return result;
 }
 
@@ -187,7 +187,7 @@ Completion LabelledStatement::execute(Interpreter& interpreter, GlobalObject& gl
     InterpreterNodeScope node_scope { interpreter, *this };
 
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return LabelledEvaluation of this LabelledStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this LabelledStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -267,12 +267,12 @@ Completion FunctionDeclaration::execute(Interpreter& interpreter, GlobalObject&
         // iv. Perform ? genv.SetMutableBinding(F, fobj, false).
         TRY(variable_environment->set_mutable_binding(global_object, name(), function_object, false));
 
-        // v. Return NormalCompletion(empty).
-        return normal_completion({});
+        // v. Return unused.
+        return Optional<Value> {};
     }
 
-    // 1. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 1. Return unused.
+    return Optional<Value> {};
 }
 
 // 15.2.6 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-evaluation
@@ -315,8 +315,8 @@ Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter&
 // 14.4.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-empty-statement-runtime-semantics-evaluation
 Completion EmptyStatement::execute(Interpreter&, GlobalObject&) const
 {
-    // 1. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 1. Return empty.
+    return Optional<Value> {};
 }
 
 // 14.5.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-expression-statement-runtime-semantics-evaluation
@@ -452,7 +452,7 @@ Completion SuperCall::execute(Interpreter& interpreter, GlobalObject& global_obj
     // 2. Assert: Type(newTarget) is Object.
     VERIFY(new_target.is_function());
 
-    // 3. Let func be ! GetSuperConstructor().
+    // 3. Let func be GetSuperConstructor().
     auto* func = get_super_constructor(interpreter.vm());
 
     // 4. Let argList be ? ArgumentListEvaluation of Arguments.
@@ -521,7 +521,7 @@ Completion ReturnStatement::execute(Interpreter& interpreter, GlobalObject& glob
     auto value = TRY(m_argument->execute(interpreter, global_object));
 
     // NOTE: Generators are not supported in the AST interpreter
-    // 3. If ! GetGeneratorKind() is async, set exprValue to ? Await(exprValue).
+    // 3. If GetGeneratorKind() is async, set exprValue to ? Await(exprValue).
 
     // 4. Return Completion Record { [[Type]]: return, [[Value]]: exprValue, [[Target]]: empty }.
     return { Completion::Type::Return, value, {} };
@@ -534,27 +534,27 @@ Completion IfStatement::execute(Interpreter& interpreter, GlobalObject& global_o
 
     // IfStatement : if ( Expression ) Statement else Statement
     // 1. Let exprRef be the result of evaluating Expression.
-    // 2. Let exprValue be ! ToBoolean(? GetValue(exprRef)).
+    // 2. Let exprValue be ToBoolean(? GetValue(exprRef)).
     auto predicate_result = TRY(m_predicate->execute(interpreter, global_object)).release_value();
 
     // 3. If exprValue is true, then
     if (predicate_result.to_boolean()) {
         // a. Let stmtCompletion be the result of evaluating the first Statement.
-        // 5. Return Completion(UpdateEmpty(stmtCompletion, undefined)).
+        // 5. Return ? UpdateEmpty(stmtCompletion, undefined).
         return m_consequent->execute(interpreter, global_object).update_empty(js_undefined());
     }
 
     // 4. Else,
     if (m_alternate) {
         // a. Let stmtCompletion be the result of evaluating the second Statement.
-        // 5. Return Completion(UpdateEmpty(stmtCompletion, undefined)).
+        // 5. Return ? UpdateEmpty(stmtCompletion, undefined).
         return m_alternate->execute(interpreter, global_object).update_empty(js_undefined());
     }
 
     // IfStatement : if ( Expression ) Statement
     // 3. If exprValue is false, then
-    //    a. Return NormalCompletion(undefined).
-    return normal_completion(js_undefined());
+    //    a. Return undefined.
+    return js_undefined();
 }
 
 // 14.11.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-with-statement-runtime-semantics-evaluation
@@ -584,7 +584,7 @@ Completion WithStatement::execute(Interpreter& interpreter, GlobalObject& global
     // 7. Set the running execution context's LexicalEnvironment to oldEnv.
     interpreter.vm().running_execution_context().lexical_environment = old_environment;
 
-    // 8. Return Completion(UpdateEmpty(C, undefined)).
+    // 8. Return ? UpdateEmpty(C, undefined).
     return result.update_empty(js_undefined());
 }
 
@@ -616,7 +616,7 @@ static bool loop_continues(Completion const& completion, Vector<FlyString> const
 Completion WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -634,14 +634,14 @@ Completion WhileStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
         // b. Let exprValue be ? GetValue(exprRef).
         auto test_result = TRY(m_test->execute(interpreter, global_object)).release_value();
 
-        // c. If ! ToBoolean(exprValue) is false, return NormalCompletion(V).
+        // c. If ToBoolean(exprValue) is false, return V.
         if (!test_result.to_boolean())
-            return normal_completion(last_value);
+            return last_value;
 
         // d. Let stmtResult be the result of evaluating Statement.
         auto body_result = m_body->execute(interpreter, global_object);
 
-        // e. If LoopContinues(stmtResult, labelSet) is false, return Completion(UpdateEmpty(stmtResult, V)).
+        // e. If LoopContinues(stmtResult, labelSet) is false, return ? UpdateEmpty(stmtResult, V).
         if (!loop_continues(body_result, label_set))
             return body_result.update_empty(last_value);
 
@@ -658,7 +658,7 @@ Completion WhileStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
 Completion DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -675,7 +675,7 @@ Completion DoWhileStatement::loop_evaluation(Interpreter& interpreter, GlobalObj
         // a. Let stmtResult be the result of evaluating Statement.
         auto body_result = m_body->execute(interpreter, global_object);
 
-        // b. If LoopContinues(stmtResult, labelSet) is false, return Completion(UpdateEmpty(stmtResult, V)).
+        // b. If LoopContinues(stmtResult, labelSet) is false, return ? UpdateEmpty(stmtResult, V).
         if (!loop_continues(body_result, label_set))
             return body_result.update_empty(last_value);
 
@@ -687,9 +687,9 @@ Completion DoWhileStatement::loop_evaluation(Interpreter& interpreter, GlobalObj
         // e. Let exprValue be ? GetValue(exprRef).
         auto test_result = TRY(m_test->execute(interpreter, global_object)).release_value();
 
-        // f. If ! ToBoolean(exprValue) is false, return NormalCompletion(V).
+        // f. If ToBoolean(exprValue) is false, return V.
         if (!test_result.to_boolean())
-            return normal_completion(last_value);
+            return last_value;
     }
 
     VERIFY_NOT_REACHED();
@@ -700,7 +700,7 @@ Completion DoWhileStatement::loop_evaluation(Interpreter& interpreter, GlobalObj
 Completion ForStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -767,7 +767,7 @@ Completion ForStatement::loop_evaluation(Interpreter& interpreter, GlobalObject&
         // f. Set the running execution context's LexicalEnvironment to thisIterationEnv.
         interpreter.vm().running_execution_context().lexical_environment = this_iteration_env;
 
-        // 2. Return undefined.
+        // 2. Return unused.
     };
 
     // 14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet ), https://tc39.es/ecma262/#sec-forbodyevaluation
@@ -786,15 +786,15 @@ Completion ForStatement::loop_evaluation(Interpreter& interpreter, GlobalObject&
             // ii. Let testValue be ? GetValue(testRef).
             auto test_value = TRY(m_test->execute(interpreter, global_object)).release_value();
 
-            // iii. If ! ToBoolean(testValue) is false, return NormalCompletion(V).
+            // iii. If ToBoolean(testValue) is false, return V.
             if (!test_value.to_boolean())
-                return normal_completion(last_value);
+                return last_value;
         }
 
         // b. Let result be the result of evaluating stmt.
         auto result = m_body->execute(interpreter, global_object);
 
-        // c. If LoopContinues(result, labelSet) is false, return Completion(UpdateEmpty(result, V)).
+        // c. If LoopContinues(result, labelSet) is false, return ? UpdateEmpty(result, V).
         if (!loop_continues(result, label_set))
             return result.update_empty(last_value);
 
@@ -987,7 +987,7 @@ static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& i
 Completion ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -1033,7 +1033,7 @@ Completion ForInStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
 
         // n. If LoopContinues(result, labelSet) is false, then
         if (!loop_continues(result, label_set)) {
-            // 1. Return Completion(UpdateEmpty(result, V)).
+            // 1. Return UpdateEmpty(result, V).
             return result.update_empty(last_value);
         }
 
@@ -1052,7 +1052,7 @@ Completion ForInStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
 Completion ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -1106,8 +1106,8 @@ Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
     }));
 
     // Return `status` set during step n.2. in the callback, or...
-    // e. If done is true, return NormalCompletion(V).
-    return status.value_or(normal_completion(last_value));
+    // e. If done is true, return V.
+    return status.value_or(last_value);
 }
 
 // 14.1.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-statement-semantics-runtime-semantics-evaluation
@@ -1115,7 +1115,7 @@ Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, GlobalObjec
 Completion ForAwaitOfStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -1164,7 +1164,7 @@ Completion ForAwaitOfStatement::loop_evaluation(Interpreter& interpreter, Global
         // d. Let done be ? IteratorComplete(nextResult).
         auto done = TRY(iterator_complete(global_object, next_result.as_object()));
 
-        // e. If done is true, return NormalCompletion(V).
+        // e. If done is true, return V.
         if (done)
             return last_value;
 
@@ -1289,7 +1289,7 @@ Completion LogicalExpression::execute(Interpreter& interpreter, GlobalObject& gl
     switch (m_op) {
     // LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
     case LogicalOp::And:
-        // 3. Let lbool be ! ToBoolean(lval).
+        // 3. Let lbool be ToBoolean(lval).
         // 4. If lbool is false, return lval.
         if (!lhs_result.to_boolean())
             return lhs_result;
@@ -1300,7 +1300,7 @@ Completion LogicalExpression::execute(Interpreter& interpreter, GlobalObject& gl
 
     // LogicalORExpression : LogicalORExpression || LogicalANDExpression
     case LogicalOp::Or:
-        // 3. Let lbool be ! ToBoolean(lval).
+        // 3. Let lbool be ToBoolean(lval).
         // 4. If lbool is true, return lval.
         if (lhs_result.to_boolean())
             return lhs_result;
@@ -1594,7 +1594,7 @@ public:
         VERIFY(!m_class_field_identifier_name.is_empty());
 
         // 3. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
-        //    a. Let value be NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]].
+        //    a. Let value be ? NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]].
         // 4. Else,
         //    a. Let rhs be the result of evaluating AssignmentExpression.
         //    b. Let value be ? GetValue(rhs).
@@ -1746,8 +1746,8 @@ Completion ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& glo
     // 1. Perform ? BindingClassDeclarationEvaluation of this ClassDeclaration.
     (void)TRY(binding_class_declaration_evaluation(interpreter, global_object, m_class_expression));
 
-    // 2. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 2. Return empty.
+    return Optional<Value> {};
 }
 
 // 15.7.14 Runtime Semantics: ClassDefinitionEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation
@@ -2550,7 +2550,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
 
                 // c. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
                 if (lhs->is_identifier()) {
-                    // i. Let rval be NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
+                    // i. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
                     auto& identifier_name = static_cast<Identifier const&>(*lhs).string();
                     rhs_result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(global_object, m_rhs, identifier_name));
                 }
@@ -2594,7 +2594,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
         switch (m_op) {
         // AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
         case AssignmentOp::AndAssignment:
-            // 3. Let lbool be ! ToBoolean(lval).
+            // 3. Let lbool be ToBoolean(lval).
             // 4. If lbool is false, return lval.
             if (!lhs_result.to_boolean())
                 return lhs_result;
@@ -2602,7 +2602,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
 
         // AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
         case AssignmentOp::OrAssignment:
-            // 3. Let lbool be ! ToBoolean(lval).
+            // 3. Let lbool be ToBoolean(lval).
             // 4. If lbool is true, return lval.
             if (lhs_result.to_boolean())
                 return lhs_result;
@@ -2623,7 +2623,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
 
         // 5. If IsAnonymousFunctionDefinition(AssignmentExpression) is true and IsIdentifierRef of LeftHandSideExpression is true, then
         if (lhs_expression.is_identifier()) {
-            // a. Let rval be NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
+            // a. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
             auto& identifier_name = static_cast<Identifier const&>(lhs_expression).string();
             rhs_result = TRY(interpreter.vm().named_evaluation_if_anonymous_function(global_object, m_rhs, identifier_name));
         }
@@ -2649,7 +2649,7 @@ Completion AssignmentExpression::execute(Interpreter& interpreter, GlobalObject&
 
     // 5. Let assignmentOpText be the source text matched by AssignmentOperator.
     // 6. Let opText be the sequence of Unicode code points associated with assignmentOpText in the following table:
-    // 7. Let r be ApplyStringOrNumericBinaryOperator(lval, opText, rval).
+    // 7. Let r be ? ApplyStringOrNumericBinaryOperator(lval, opText, rval).
     switch (m_op) {
     case AssignmentOp::AdditionAssignment:
         rhs_result = TRY(add(global_object, lhs_result, rhs_result));
@@ -2721,26 +2721,26 @@ Completion UpdateExpression::execute(Interpreter& interpreter, GlobalObject& glo
     case UpdateOp::Increment:
         // 3. If Type(oldValue) is Number, then
         if (old_value.is_number()) {
-            // a. Let newValue be ! Number::add(oldValue, 1𝔽).
+            // a. Let newValue be Number::add(oldValue, 1𝔽).
             new_value = Value(old_value.as_double() + 1);
         }
         // 4. Else,
         else {
             // a. Assert: Type(oldValue) is BigInt.
-            // b. Let newValue be ! BigInt::add(oldValue, 1ℤ).
+            // b. Let newValue be BigInt::add(oldValue, 1ℤ).
             new_value = js_bigint(interpreter.heap(), old_value.as_bigint().big_integer().plus(Crypto::SignedBigInteger { 1 }));
         }
         break;
     case UpdateOp::Decrement:
         // 3. If Type(oldValue) is Number, then
         if (old_value.is_number()) {
-            // a. Let newValue be ! Number::subtract(oldValue, 1𝔽).
+            // a. Let newValue be Number::subtract(oldValue, 1𝔽).
             new_value = Value(old_value.as_double() - 1);
         }
         // 4. Else,
         else {
             // a. Assert: Type(oldValue) is BigInt.
-            // b. Let newValue be ! BigInt::subtract(oldValue, 1ℤ).
+            // b. Let newValue be BigInt::subtract(oldValue, 1ℤ).
             new_value = js_bigint(interpreter.heap(), old_value.as_bigint().big_integer().minus(Crypto::SignedBigInteger { 1 }));
         }
         break;
@@ -2974,7 +2974,7 @@ Completion ObjectExpression::execute(Interpreter& interpreter, GlobalObject& glo
 {
     InterpreterNodeScope node_scope { interpreter, *this };
 
-    // 1. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
     auto* object = Object::create(global_object, global_object.object_prototype());
 
     // 2. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with argument obj.
@@ -2983,8 +2983,10 @@ Completion ObjectExpression::execute(Interpreter& interpreter, GlobalObject& glo
 
         // PropertyDefinition : ... AssignmentExpression
         if (property.type() == ObjectProperty::Type::Spread) {
-            // 4. Return ? CopyDataProperties(object, fromValue, excludedNames).
+            // 4. Perform ? CopyDataProperties(object, fromValue, excludedNames).
             TRY(object->copy_data_properties(key, {}, global_object));
+
+            // 5. Return unused.
             continue;
         }
 
@@ -3191,7 +3193,7 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
 
     // ImportMeta : import . meta
     if (m_type == MetaProperty::Type::ImportMeta) {
-        // 1. Let module be ! GetActiveScriptOrModule().
+        // 1. Let module be GetActiveScriptOrModule().
         auto script_or_module = interpreter.vm().get_active_script_or_module();
 
         // 2. Assert: module is a Source Text Module Record.
@@ -3205,10 +3207,10 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
 
         // 4. If importMeta is empty, then
         if (import_meta == nullptr) {
-            // a. Set importMeta to ! OrdinaryObjectCreate(null).
+            // a. Set importMeta to OrdinaryObjectCreate(null).
             import_meta = Object::create(global_object, nullptr);
 
-            // b. Let importMetaValues be ! HostGetImportMetaProperties(module).
+            // b. Let importMetaValues be HostGetImportMetaProperties(module).
             auto import_meta_values = interpreter.vm().host_get_import_meta_properties(module);
 
             // c. For each Record { [[Key]], [[Value]] } p of importMetaValues, do
@@ -3217,7 +3219,7 @@ Completion MetaProperty::execute(Interpreter& interpreter, GlobalObject& global_
                 MUST(import_meta->create_data_property_or_throw(entry.key, entry.value));
             }
 
-            // d. Perform ! HostFinalizeImportMeta(importMeta, module).
+            // d. Perform HostFinalizeImportMeta(importMeta, module).
             interpreter.vm().host_finalize_import_meta(import_meta, module);
 
             // e. Set module.[[ImportMeta]] to importMeta.
@@ -3258,7 +3260,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
     InterpreterNodeScope node_scope { interpreter, *this };
 
     // 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ), https://tc39.es/proposal-import-assertions/#sec-evaluate-import-call
-    //  1. Let referencingScriptOrModule be ! GetActiveScriptOrModule().
+    //  1. Let referencingScriptOrModule be GetActiveScriptOrModule().
     auto referencing_script_or_module = interpreter.vm().get_active_script_or_module();
 
     // 2. Let specifierRef be the result of evaluating specifierExpression.
@@ -3279,7 +3281,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
     // 6. Let promiseCapability be ! NewPromiseCapability(%Promise%).
     auto promise_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
 
-    // 7. Let specifierString be ToString(specifier).
+    // 7. Let specifierString be Completion(ToString(specifier)).
     // 8. IfAbruptRejectPromise(specifierString, promiseCapability).
     auto specifier_string = TRY_OR_REJECT_WITH_VALUE(global_object, promise_capability, specifier->to_string(global_object));
 
@@ -3353,7 +3355,7 @@ Completion ImportCall::execute(Interpreter& interpreter, GlobalObject& global_ob
     // 11. Let moduleRequest be a new ModuleRequest Record { [[Specifier]]: specifierString, [[Assertions]]: assertions }.
     ModuleRequest request { specifier_string, assertions };
 
-    // 12. Perform ! HostImportModuleDynamically(referencingScriptOrModule, moduleRequest, promiseCapability).
+    // 12. Perform HostImportModuleDynamically(referencingScriptOrModule, moduleRequest, promiseCapability).
     interpreter.vm().host_import_module_dynamically(referencing_script_or_module, move(request), promise_capability);
 
     // 13. Return promiseCapability.[[Promise]].
@@ -3427,13 +3429,13 @@ Completion RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global
 {
     InterpreterNodeScope node_scope { interpreter, *this };
 
-    // 1. Let pattern be ! CodePointsToString(BodyText of RegularExpressionLiteral).
+    // 1. Let pattern be CodePointsToString(BodyText of RegularExpressionLiteral).
     auto pattern = this->pattern();
 
-    // 2. Let flags be ! CodePointsToString(FlagText of RegularExpressionLiteral).
+    // 2. Let flags be CodePointsToString(FlagText of RegularExpressionLiteral).
     auto flags = this->flags();
 
-    // 3. Return RegExpCreate(pattern, flags).
+    // 3. Return ! RegExpCreate(pattern, flags).
     Regex<ECMA262> regex(parsed_regex(), parsed_pattern(), parsed_flags());
     return Value { RegExpObject::create(global_object, move(regex), move(pattern), move(flags)) };
 }
@@ -3459,8 +3461,7 @@ Completion ArrayExpression::execute(Interpreter& interpreter, GlobalObject& glob
     // 1. Let array be ! ArrayCreate(0).
     auto* array = MUST(Array::create(global_object, 0));
 
-    // 2. Let len be the result of performing ArrayAccumulation of ElementList with arguments array and 0.
-    // 3. ReturnIfAbrupt(len).
+    // 2. Perform ? ArrayAccumulation of ElementList with arguments array and 0.
 
     array->indexed_properties();
     size_t index = 0;
@@ -3480,7 +3481,7 @@ Completion ArrayExpression::execute(Interpreter& interpreter, GlobalObject& glob
         array->indexed_properties().put(index++, value, default_attributes);
     }
 
-    // 4. Return array.
+    // 3. Return array.
     return Value { array };
 }
 
@@ -3637,7 +3638,7 @@ Completion TryStatement::execute(Interpreter& interpreter, GlobalObject& global_
         // 4. Set the running execution context's LexicalEnvironment to catchEnv.
         vm.running_execution_context().lexical_environment = catch_environment;
 
-        // 5. Let status be BindingInitialization of CatchParameter with arguments thrownValue and catchEnv.
+        // 5. Let status be Completion(BindingInitialization of CatchParameter with arguments thrownValue and catchEnv).
         auto status = m_handler->parameter().visit(
             [&](FlyString const& parameter) {
                 return catch_environment->initialize_binding(global_object, parameter, thrown_value);
@@ -3651,7 +3652,7 @@ Completion TryStatement::execute(Interpreter& interpreter, GlobalObject& global_
             // a. Set the running execution context's LexicalEnvironment to oldEnv.
             vm.running_execution_context().lexical_environment = old_environment;
 
-            // b. Return Completion(status).
+            // b. Return ? status.
             return status.release_error();
         }
 
@@ -3661,7 +3662,7 @@ Completion TryStatement::execute(Interpreter& interpreter, GlobalObject& global_
         // 8. Set the running execution context's LexicalEnvironment to oldEnv.
         vm.running_execution_context().lexical_environment = old_environment;
 
-        // 9. Return Completion(B).
+        // 9. Return ? B.
         return handler_result;
     };
 
@@ -3673,7 +3674,7 @@ Completion TryStatement::execute(Interpreter& interpreter, GlobalObject& global_
     // TryStatement : try Block Catch
     // TryStatement : try Block Catch Finally
     if (m_handler) {
-        // 2. If B.[[Type]] is throw, let C be CatchClauseEvaluation of Catch with argument B.[[Value]].
+        // 2. If B.[[Type]] is throw, let C be Completion(CatchClauseEvaluation of Catch with argument B.[[Value]]).
         if (block_result.type() == Completion::Type::Throw)
             result = catch_clause_evaluation(*block_result.value());
         // 3. Else, let C be B.
@@ -3695,11 +3696,11 @@ Completion TryStatement::execute(Interpreter& interpreter, GlobalObject& global_
         if (finalizer_result.type() == Completion::Type::Normal)
             finalizer_result = move(result);
 
-        // 6. Return Completion(UpdateEmpty(F, undefined)).
+        // 6. Return ? UpdateEmpty(F, undefined).
         return finalizer_result.update_empty(js_undefined());
     }
 
-    // 4. Return Completion(UpdateEmpty(C, undefined)).
+    // 4. Return ? UpdateEmpty(C, undefined).
     return result.update_empty(js_undefined());
 }
 
@@ -3730,7 +3731,7 @@ Completion ThrowStatement::execute(Interpreter& interpreter, GlobalObject& globa
 Completion SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
     // 1. Let newLabelSet be a new empty List.
-    // 2. Return the result of performing LabelledEvaluation of this BreakableStatement with argument newLabelSet.
+    // 2. Return ? LabelledEvaluation of this BreakableStatement with argument newLabelSet.
     return labelled_evaluation(interpreter, global_object, *this, {});
 }
 
@@ -3757,11 +3758,11 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
     };
 
     // 14.12.2 Runtime Semantics: CaseBlockEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-caseblockevaluation
-    auto case_block_evaluation = [&](auto input) {
+    auto case_block_evaluation = [&](auto input) -> Completion {
         // CaseBlock : { }
         if (m_cases.is_empty()) {
-            // 1. Return NormalCompletion(undefined).
-            return normal_completion(js_undefined());
+            // 1. Return undefined.
+            return js_undefined();
         }
 
         NonnullRefPtrVector<SwitchCase> case_clauses_1;
@@ -3807,14 +3808,14 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
                     if (result.value().has_value())
                         last_value = *result.value();
 
-                    // iii. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
+                    // iii. If R is an abrupt completion, return ? UpdateEmpty(R, V).
                     if (result.is_abrupt())
                         return result.update_empty(last_value);
                 }
             }
 
-            // 5. Return NormalCompletion(V).
-            return normal_completion(last_value);
+            // 5. Return V.
+            return last_value;
         }
         // CaseBlock : { CaseClauses[opt] DefaultClause CaseClauses[opt] }
         else {
@@ -3847,7 +3848,7 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
                     if (result.value().has_value())
                         last_value = *result.value();
 
-                    // iii. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
+                    // iii. If R is an abrupt completion, return ? UpdateEmpty(R, V).
                     if (result.is_abrupt())
                         return result.update_empty(last_value);
                 }
@@ -3881,16 +3882,16 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
                         if (result.value().has_value())
                             last_value = *result.value();
 
-                        // 3. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
+                        // 3. If R is an abrupt completion, return ? UpdateEmpty(R, V).
                         if (result.is_abrupt())
                             return result.update_empty(last_value);
                     }
                 }
             }
 
-            // 10. If foundInB is true, return NormalCompletion(V).
+            // 10. If foundInB is true, return V.
             if (found_in_b)
-                return normal_completion(last_value);
+                return last_value;
 
             // 11. Let R be the result of evaluating DefaultClause.
             auto result = default_clause->evaluate_statements(interpreter, global_object);
@@ -3899,7 +3900,7 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
             if (result.value().has_value())
                 last_value = *result.value();
 
-            // 13. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
+            // 13. If R is an abrupt completion, return ? UpdateEmpty(R, V).
             if (result.is_abrupt())
                 return result.update_empty(last_value);
 
@@ -3913,13 +3914,13 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
                 if (result.value().has_value())
                     last_value = *result.value();
 
-                // c. If R is an abrupt completion, return Completion(UpdateEmpty(R, V)).
+                // c. If R is an abrupt completion, return ? UpdateEmpty(R, V).
                 if (result.is_abrupt())
                     return result.update_empty(last_value);
             }
 
-            // 16. Return NormalCompletion(V).
-            return normal_completion(last_value);
+            // 16. Return V.
+            return last_value;
         }
 
         VERIFY_NOT_REACHED();
@@ -3945,7 +3946,7 @@ Completion SwitchStatement::execute_impl(Interpreter& interpreter, GlobalObject&
         vm.running_execution_context().lexical_environment = block_environment;
     }
 
-    // 7. Let R be CaseBlockEvaluation of CaseBlock with argument switchValue.
+    // 7. Let R be Completion(CaseBlockEvaluation of CaseBlock with argument switchValue).
     auto result = case_block_evaluation(switch_value);
 
     // 8. Set the running execution context's LexicalEnvironment to oldEnv.
@@ -4027,7 +4028,7 @@ Completion ConditionalExpression::execute(Interpreter& interpreter, GlobalObject
     InterpreterNodeScope node_scope { interpreter, *this };
 
     // 1. Let lref be the result of evaluating ShortCircuitExpression.
-    // 2. Let lval be ! ToBoolean(? GetValue(lref)).
+    // 2. Let lval be ToBoolean(? GetValue(lref)).
     auto test_result = TRY(m_test->execute(interpreter, global_object)).release_value();
 
     // 3. If lval is true, then
@@ -4091,17 +4092,15 @@ Completion DebuggerStatement::execute(Interpreter& interpreter, GlobalObject&) c
     // 1. If an implementation-defined debugging facility is available and enabled, then
     if (false) {
         // a. Perform an implementation-defined debugging action.
-        // b. Let result be an implementation-defined Completion value.
+        // b. Return a new implementation-defined Completion Record.
     }
     // 2. Else,
     else {
-        // a. Let result be NormalCompletion(empty).
-        result = normal_completion({});
+        // a. Return empty.
+        return Optional<Value> {};
     }
-
-    // 3. Return result.
-    return result;
 }
+
 ThrowCompletionOr<void> ScopeNode::for_each_lexically_scoped_declaration(ThrowCompletionOrVoidCallback<Declaration const&>&& callback) const
 {
     for (auto& declaration : m_lexical_declarations)
@@ -4180,8 +4179,8 @@ Completion ImportStatement::execute(Interpreter& interpreter, GlobalObject&) con
 {
     InterpreterNodeScope node_scope { interpreter, *this };
 
-    // 1. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 1. Return empty.
+    return Optional<Value> {};
 }
 
 FlyString ExportStatement::local_name_for_default = "*default*";
@@ -4197,8 +4196,8 @@ Completion ExportStatement::execute(Interpreter& interpreter, GlobalObject& glob
             return m_statement->execute(interpreter, global_object);
         }
 
-        // 1. Return NormalCompletion(empty).
-        return normal_completion({});
+        // 1. Return empty.
+        return Optional<Value> {};
     }
 
     VERIFY(m_statement);
@@ -4222,8 +4221,8 @@ Completion ExportStatement::execute(Interpreter& interpreter, GlobalObject& glob
         // Note: We never go into step 3. since a ClassDeclaration always has a name and "*default*" is not a class name.
         (void)value;
 
-        // 4. Return NormalCompletion(empty).
-        return normal_completion({});
+        // 4. Return empty.
+        return Optional<Value> {};
     }
 
     // ExportDeclaration : export default ClassDeclaration
@@ -4246,8 +4245,8 @@ Completion ExportStatement::execute(Interpreter& interpreter, GlobalObject& glob
             TRY(initialize_bound_name(global_object, ExportStatement::local_name_for_default, value, env));
         }
 
-        // 4. Return NormalCompletion(empty).
-        return normal_completion({});
+        // 4. Return empty.
+        return Optional<Value> {};
     }
 
     // ExportDeclaration : export default AssignmentExpression ;
@@ -4265,8 +4264,8 @@ Completion ExportStatement::execute(Interpreter& interpreter, GlobalObject& glob
     // 4. Perform ? InitializeBoundName("*default*", value, env).
     TRY(initialize_bound_name(global_object, ExportStatement::local_name_for_default, value, env));
 
-    // 5. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 5. Return empty.
+    return Optional<Value> {};
 }
 
 static void dump_assert_clauses(ModuleRequest const& request)
@@ -4516,7 +4515,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
             //     ii. Let benv be the running execution context's LexicalEnvironment.
             //     iii. Let fobj be ! benv.GetBindingValue(F, false).
             //     iv. Perform ? genv.SetMutableBinding(F, fobj, false).
-            //     v. Return NormalCompletion(empty).
+            //     v. Return unused.
             function_declaration.set_should_do_additional_annexB_steps();
 
             return {};
@@ -4566,7 +4565,7 @@ ThrowCompletionOr<void> Program::global_declaration_instantiation(Interpreter& i
         TRY(global_environment.create_global_var_binding(var_name, false));
     }
 
-    // 18. Return NormalCompletion(empty).
+    // 18. Return unused.
     return {};
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp

@@ -194,7 +194,7 @@ Bytecode::CodeGenerationErrorOr<void> ScopeNode::generate_bytecode(Bytecode::Gen
                 //     ii. Let benv be the running execution context's LexicalEnvironment.
                 //     iii. Let fobj be ! benv.GetBindingValue(F, false).
                 //     iv. Perform ? genv.SetMutableBinding(F, fobj, false).
-                //     v. Return NormalCompletion(empty).
+                //     v. Return unused.
                 function_declaration.set_should_do_additional_annexB_steps();
             });
         }

+ 3 - 2
Userland/Libraries/LibJS/Contrib/Test262/$262Object.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -69,7 +69,8 @@ JS_DEFINE_NATIVE_FUNCTION($262Object::detach_array_buffer)
         return vm.throw_completion<TypeError>(global_object);
 
     auto& array_buffer_object = static_cast<ArrayBuffer&>(array_buffer.as_object());
-    return JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1));
+    TRY(JS::detach_array_buffer(global_object, array_buffer_object, vm.argument(1)));
+    return js_null();
 }
 
 JS_DEFINE_NATIVE_FUNCTION($262Object::eval_script)

+ 48 - 48
Userland/Libraries/LibJS/CyclicModule.cpp

@@ -26,11 +26,11 @@ ThrowCompletionOr<void> CyclicModule::link(VM& vm)
     // 2. Let stack be a new empty List.
     Vector<Module*> stack;
 
-    // 3. Let result be InnerModuleLinking(module, stack, 0).
-    auto inner_module_linked_or_error = inner_module_linking(vm, stack, 0);
+    // 3. Let result be Completion(InnerModuleLinking(module, stack, 0)).
+    auto result = inner_module_linking(vm, stack, 0);
 
     // 4. If result is an abrupt completion, then
-    if (inner_module_linked_or_error.is_error()) {
+    if (result.is_throw_completion()) {
         // a. For each Cyclic Module Record m of stack, do
         for (auto* module : stack) {
             if (is<CyclicModule>(module)) {
@@ -46,7 +46,7 @@ ThrowCompletionOr<void> CyclicModule::link(VM& vm)
         VERIFY(m_status == ModuleStatus::Unlinked);
 
         // c. Return result.
-        return inner_module_linked_or_error.release_error();
+        return result.release_error();
     }
 
     // 5. Assert: module.[[Status]] is linked, evaluating-async, or evaluated.
@@ -54,8 +54,7 @@ ThrowCompletionOr<void> CyclicModule::link(VM& vm)
     // 6. Assert: stack is empty.
     VERIFY(stack.is_empty());
 
-    // 7. Return undefined.
-    // Note: We return void since the result of this is never used.
+    // 7. Return unused.
     return {};
 }
 
@@ -130,7 +129,7 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_linking(VM& vm, Vector<Module*
     }
 
     // 10. Perform ? module.InitializeEnvironment().
-    (void)TRY(initialize_environment(vm));
+    TRY(initialize_environment(vm));
 
     // 11. Assert: module occurs exactly once in stack.
     size_t count = 0;
@@ -204,7 +203,7 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
     // 7. Set module.[[TopLevelCapability]] to capability.
     m_top_level_capability = MUST(new_promise_capability(global_object, global_object.promise_constructor()));
 
-    // 8. Let result be InnerModuleEvaluation(module, stack, 0).
+    // 8. Let result be Completion(InnerModuleEvaluation(module, stack, 0)).
     auto result = inner_module_evaluation(vm, stack, 0);
 
     // 9. If result is an abrupt completion, then
@@ -273,7 +272,7 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
         if (!m_evaluation_error.is_error())
             return index;
 
-        // b. Otherwise, return module.[[EvaluationError]].
+        // b. Otherwise, return ? module.[[EvaluationError]].
         return m_evaluation_error.throw_completion();
     }
 
@@ -336,7 +335,7 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
             // 2. Assert: requiredModule.[[Status]] is evaluating-async or evaluated.
             VERIFY(cyclic_module->m_status == ModuleStatus::EvaluatingAsync || cyclic_module->m_status == ModuleStatus::Evaluated);
 
-            // 3. If requiredModule.[[EvaluationError]] is not empty, return requiredModule.[[EvaluationError]].
+            // 3. If requiredModule.[[EvaluationError]] is not empty, return ? requiredModule.[[EvaluationError]].
             if (cyclic_module->m_evaluation_error.is_error())
                 return cyclic_module->m_evaluation_error.throw_completion();
         }
@@ -361,13 +360,13 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
         m_async_evaluation = true;
         // c. NOTE: The order in which module records have their [[AsyncEvaluation]] fields transition to true is significant. (See 16.2.1.5.2.4.)
 
-        // d. If module.[[PendingAsyncDependencies]] is 0, perform ! ExecuteAsyncModule(module).
+        // d. If module.[[PendingAsyncDependencies]] is 0, perform ExecuteAsyncModule(module).
         if (m_pending_async_dependencies.value() == 0)
-            MUST(execute_async_module(vm));
+            execute_async_module(vm);
     }
     // 13. Otherwise, perform ? module.ExecuteModule().
     else {
-        (void)TRY(execute_module(vm));
+        TRY(execute_module(vm));
     }
 
     // 14. Assert: module occurs exactly once in stack.
@@ -417,24 +416,22 @@ ThrowCompletionOr<u32> CyclicModule::inner_module_evaluation(VM& vm, Vector<Modu
     return index;
 }
 
-Completion CyclicModule::initialize_environment(VM&)
+ThrowCompletionOr<void> CyclicModule::initialize_environment(VM&)
 {
     // Note: In ecma262 this is never called on a cyclic module only on SourceTextModules.
     //       So this check is to make sure we don't accidentally call this.
     VERIFY_NOT_REACHED();
-    return normal_completion({});
 }
 
-Completion CyclicModule::execute_module(VM&, Optional<PromiseCapability>)
+ThrowCompletionOr<void> CyclicModule::execute_module(VM&, Optional<PromiseCapability>)
 {
     // Note: In ecma262 this is never called on a cyclic module only on SourceTextModules.
     //       So this check is to make sure we don't accidentally call this.
     VERIFY_NOT_REACHED();
-    return js_undefined();
 }
 
 // 16.2.1.5.2.2 ExecuteAsyncModule ( module ), https://tc39.es/ecma262/#sec-execute-async-module
-ThrowCompletionOr<void> CyclicModule::execute_async_module(VM& vm)
+void CyclicModule::execute_async_module(VM& vm)
 {
     dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] executing async module {}", filename());
     // 1. Assert: module.[[Status]] is evaluating or evaluating-async.
@@ -449,43 +446,43 @@ ThrowCompletionOr<void> CyclicModule::execute_async_module(VM& vm)
 
     // 4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
     auto fulfilled_closure = [&](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
-        // a. Perform ! AsyncModuleExecutionFulfilled(module).
-        MUST(async_module_execution_fulfilled(vm));
+        // a. Perform AsyncModuleExecutionFulfilled(module).
+        async_module_execution_fulfilled(vm);
 
         // b. Return undefined.
         return js_undefined();
     };
 
-    // 5. Let onFulfilled be ! CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
+    // 5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
     auto* on_fulfilled = NativeFunction::create(global_object, move(fulfilled_closure), 0, "");
 
     // 6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
     auto rejected_closure = [&](VM& vm, GlobalObject&) -> ThrowCompletionOr<Value> {
         auto error = vm.argument(0);
 
-        // a. Perform ! AsyncModuleExecutionRejected(module, error).
-        MUST(async_module_execution_rejected(vm, error));
+        // a. Perform AsyncModuleExecutionRejected(module, error).
+        async_module_execution_rejected(vm, error);
 
         // b. Return undefined.
         return js_undefined();
     };
 
-    // 7. Let onRejected be ! CreateBuiltinFunction(rejectedClosure, 0, "", « »).
+    // 7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
     auto* on_rejected = NativeFunction::create(global_object, move(rejected_closure), 0, "");
 
     VERIFY(is<Promise>(*capability.promise));
 
-    // 8. Perform ! PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
+    // 8. Perform PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
     static_cast<Promise*>(capability.promise)->perform_then(on_fulfilled, on_rejected, {});
 
     // 9. Perform ! module.ExecuteModule(capability).
-    (void)MUST(execute_module(vm, capability));
+    MUST(execute_module(vm, capability));
 
-    return {};
+    // 10. Return unused.
 }
 
 // 16.2.1.5.2.3 GatherAvailableAncestors ( module, execList ), https://tc39.es/ecma262/#sec-gather-available-ancestors
-ThrowCompletionOr<void> CyclicModule::gather_available_ancestors(Vector<CyclicModule*>& exec_list)
+void CyclicModule::gather_available_ancestors(Vector<CyclicModule*>& exec_list)
 {
     // 1. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
     for (auto* module : m_async_parent_modules) {
@@ -511,25 +508,26 @@ ThrowCompletionOr<void> CyclicModule::gather_available_ancestors(Vector<CyclicMo
                 // 1. Append m to execList.
                 exec_list.append(module);
 
-                // 2. If m.[[HasTLA]] is false, perform ! GatherAvailableAncestors(m, execList).
+                // 2. If m.[[HasTLA]] is false, perform GatherAvailableAncestors(m, execList).
                 if (!module->m_has_top_level_await)
-                    MUST(module->gather_available_ancestors(exec_list));
+                    module->gather_available_ancestors(exec_list);
             }
         }
     }
 
-    return {};
+    // 2. Return unused.
 }
 
 // 16.2.1.5.2.4 AsyncModuleExecutionFulfilled ( module ), https://tc39.es/ecma262/#sec-async-module-execution-fulfilled
-ThrowCompletionOr<void> CyclicModule::async_module_execution_fulfilled(VM& vm)
+void CyclicModule::async_module_execution_fulfilled(VM& vm)
 {
     // 1. If module.[[Status]] is evaluated, then
     if (m_status == ModuleStatus::Evaluated) {
         // a. Assert: module.[[EvaluationError]] is not empty.
         VERIFY(m_evaluation_error.is_error());
-        // b. Return.
-        return {};
+
+        // b. Return unused.
+        return;
     }
 
     // 2. Assert: module.[[Status]] is evaluating-async.
@@ -560,8 +558,8 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_fulfilled(VM& vm)
     // 8. Let execList be a new empty List.
     Vector<CyclicModule*> exec_list;
 
-    // 9. Perform ! GatherAvailableAncestors(module, execList).
-    MUST(gather_available_ancestors(exec_list));
+    // 9. Perform GatherAvailableAncestors(module, execList).
+    gather_available_ancestors(exec_list);
 
     // 10. Let sortedExecList be a List whose elements are the elements of execList, in the order in which they had their [[AsyncEvaluation]] fields set to true in InnerModuleEvaluation.
     // FIXME: Sort the list. To do this we need to use more than an Optional<bool> to track [[AsyncEvaluation]].
@@ -578,8 +576,8 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_fulfilled(VM& vm)
         }
         // b. Else if m.[[HasTLA]] is true, then
         else if (module->m_has_top_level_await) {
-            // i. Perform ! ExecuteAsyncModule(m).
-            MUST(module->execute_async_module(vm));
+            // i. Perform ExecuteAsyncModule(m).
+            module->execute_async_module(vm);
         }
         // c. Else,
         else {
@@ -587,9 +585,9 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_fulfilled(VM& vm)
             auto result = module->execute_module(vm);
 
             // ii. If result is an abrupt completion, then
-            if (result.is_abrupt()) {
-                // 1. Perform ! AsyncModuleExecutionRejected(m, result.[[Value]]).
-                module->async_module_execution_rejected(vm, *result.value());
+            if (result.is_throw_completion()) {
+                // 1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]).
+                module->async_module_execution_rejected(vm, *result.throw_completion().value());
             }
             // iii. Else,
             else {
@@ -608,18 +606,20 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_fulfilled(VM& vm)
             }
         }
     }
-    return {};
+
+    // 13. Return unused.
 }
 
 // 16.2.1.5.2.5 AsyncModuleExecutionRejected ( module, error ), https://tc39.es/ecma262/#sec-async-module-execution-rejected
-ThrowCompletionOr<void> CyclicModule::async_module_execution_rejected(VM& vm, Value error)
+void CyclicModule::async_module_execution_rejected(VM& vm, Value error)
 {
     // 1. If module.[[Status]] is evaluated, then
     if (m_status == ModuleStatus::Evaluated) {
         // a. Assert: module.[[EvaluationError]] is not empty.
         VERIFY(m_evaluation_error.is_error());
-        // b. Return.
-        return {};
+
+        // b. Return unused.
+        return;
     }
 
     // 2. Assert: module.[[Status]] is evaluating-async.
@@ -640,8 +640,8 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_rejected(VM& vm, Va
     // 7. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
     for (auto* module : m_async_parent_modules) {
 
-        // a. Perform ! AsyncModuleExecutionRejected(m, error).
-        MUST(module->async_module_execution_rejected(vm, error));
+        // a. Perform AsyncModuleExecutionRejected(m, error).
+        module->async_module_execution_rejected(vm, error);
     }
 
     // 8. If module.[[TopLevelCapability]] is not empty, then
@@ -654,7 +654,7 @@ ThrowCompletionOr<void> CyclicModule::async_module_execution_rejected(VM& vm, Va
         MUST(call(vm.current_realm()->global_object(), m_top_level_capability->reject, js_undefined(), error));
     }
 
-    return {};
+    // 9. Return unused.
 }
 
 }

+ 6 - 6
Userland/Libraries/LibJS/CyclicModule.h

@@ -37,13 +37,13 @@ protected:
     virtual ThrowCompletionOr<u32> inner_module_linking(VM& vm, Vector<Module*>& stack, u32 index) override;
     virtual ThrowCompletionOr<u32> inner_module_evaluation(VM& vm, Vector<Module*>& stack, u32 index) override;
 
-    virtual Completion initialize_environment(VM& vm);
-    virtual Completion execute_module(VM& vm, Optional<PromiseCapability> capability = {});
+    virtual ThrowCompletionOr<void> initialize_environment(VM& vm);
+    virtual ThrowCompletionOr<void> execute_module(VM& vm, Optional<PromiseCapability> capability = {});
 
-    ThrowCompletionOr<void> execute_async_module(VM& vm);
-    ThrowCompletionOr<void> gather_available_ancestors(Vector<CyclicModule*>& exec_list);
-    ThrowCompletionOr<void> async_module_execution_fulfilled(VM& vm);
-    ThrowCompletionOr<void> async_module_execution_rejected(VM& vm, Value error);
+    void execute_async_module(VM& vm);
+    void gather_available_ancestors(Vector<CyclicModule*>& exec_list);
+    void async_module_execution_fulfilled(VM& vm);
+    void async_module_execution_rejected(VM& vm, Value error);
 
     ModuleStatus m_status { ModuleStatus::Unlinked };   // [[Status]]
     ThrowCompletionOr<void> m_evaluation_error;         // [[EvaluationError]]

+ 3 - 3
Userland/Libraries/LibJS/Interpreter.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -80,7 +80,7 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record)
     // 11. Let script be scriptRecord.[[ECMAScriptCode]].
     auto& script = script_record.parse_node();
 
-    // 12. Let result be GlobalDeclarationInstantiation(script, globalEnv).
+    // 12. Let result be Completion(GlobalDeclarationInstantiation(script, globalEnv)).
     auto instantiation_result = script.global_declaration_instantiation(*this, global_object, global_environment);
     Completion result = instantiation_result.is_throw_completion() ? instantiation_result.throw_completion() : normal_completion({});
 
@@ -116,7 +116,7 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record)
 
     vm.finish_execution_generation();
 
-    // 18. Return Completion(result).
+    // 18. Return ? result.
     if (result.is_abrupt()) {
         VERIFY(result.type() == Completion::Type::Throw);
         return result.release_error();

+ 1 - 1
Userland/Libraries/LibJS/Interpreter.h

@@ -90,7 +90,7 @@ public:
         // 11. Create any host-defined global object properties on globalObj.
         static_cast<GlobalObjectType*>(global_object)->initialize_global_object();
 
-        // 12. Return NormalCompletion(empty).
+        // 12. Return unused.
         return interpreter;
     }
 

+ 1 - 1
Userland/Libraries/LibJS/Module.cpp

@@ -91,7 +91,7 @@ Object* Module::module_namespace_create(VM& vm, Vector<FlyString> unambiguous_na
     VERIFY(m_namespace.is_null());
 
     // 2. Let internalSlotsList be the internal slots listed in Table 34.
-    // 3. Let M be ! MakeBasicObject(internalSlotsList).
+    // 3. Let M be MakeBasicObject(internalSlotsList).
     // 4. Set M's essential internal methods to the definitions specified in 10.4.6.
     // 5. Set M.[[Module]] to module.
     // 6. Let sortedExports be a List whose elements are the elements of exports ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn.

+ 28 - 31
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp

@@ -217,17 +217,16 @@ ThrowCompletionOr<void> initialize_bound_name(GlobalObject& global_object, FlySt
 
     // 1. If environment is not undefined, then
     if (environment) {
-        // a. Perform environment.InitializeBinding(name, value).
+        // a. Perform ! environment.InitializeBinding(name, value).
         MUST(environment->initialize_binding(global_object, name, value));
 
-        // b. Return NormalCompletion(undefined).
+        // b. Return unused.
         return {};
     }
     // 2. Else,
     else {
-        // a. Let lhs be ResolveBinding(name).
-        // NOTE: Although the spec pretends resolve_binding cannot fail it can just not in this case.
-        auto lhs = MUST(vm.resolve_binding(name));
+        // a. Let lhs be ? ResolveBinding(name).
+        auto lhs = TRY(vm.resolve_binding(name));
 
         // b. Return ? PutValue(lhs, value).
         return TRY(lhs.put_value(global_object, value));
@@ -246,7 +245,7 @@ bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const
 // 10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ), https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor
 bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& property_key, bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> const& current)
 {
-    // 1. Assert: ! IsPropertyKey(P) is true.
+    // 1. Assert: IsPropertyKey(P) is true.
     VERIFY(property_key.is_valid());
 
     // 2. If current is undefined, then
@@ -288,21 +287,21 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
         if (descriptor.configurable.has_value() && *descriptor.configurable)
             return false;
 
-        // b. If Desc has an [[Enumerable]] field and ! SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return false.
+        // b. If Desc has an [[Enumerable]] field and SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return false.
         if (descriptor.enumerable.has_value() && *descriptor.enumerable != *current->enumerable)
             return false;
 
-        // c. If ! IsGenericDescriptor(Desc) is false and ! SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current)) is false, return false.
+        // c. If IsGenericDescriptor(Desc) is false and SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current)) is false, return false.
         if (!descriptor.is_generic_descriptor() && (descriptor.is_accessor_descriptor() != current->is_accessor_descriptor()))
             return false;
 
-        // d. If ! IsAccessorDescriptor(Desc) is true, then
+        // d. If IsAccessorDescriptor(Desc) is true, then
         if (descriptor.is_accessor_descriptor()) {
-            // i. If Desc has a [[Get]] field and ! SameValue(Desc.[[Get]], current.[[Get]]) is false, return false.
+            // i. If Desc has a [[Get]] field and SameValue(Desc.[[Get]], current.[[Get]]) is false, return false.
             if (descriptor.get.has_value() && *descriptor.get != *current->get)
                 return false;
 
-            // ii. If Desc has a [[Set]] field and ! SameValue(Desc.[[Set]], current.[[Set]]) is false, return false.
+            // ii. If Desc has a [[Set]] field and SameValue(Desc.[[Set]], current.[[Set]]) is false, return false.
             if (descriptor.set.has_value() && *descriptor.set != *current->set)
                 return false;
         }
@@ -313,7 +312,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
             if (descriptor.writable.has_value() && *descriptor.writable)
                 return false;
 
-            // ii. If Desc has a [[Value]] field and ! SameValue(Desc.[[Value]], current.[[Value]]) is false, return false.
+            // ii. If Desc has a [[Value]] field and SameValue(Desc.[[Value]], current.[[Value]]) is false, return false.
             if (descriptor.value.has_value() && (*descriptor.value != *current->value))
                 return false;
         }
@@ -321,7 +320,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
 
     // 6. If O is not undefined, then
     if (object != nullptr) {
-        // a. If ! IsDataDescriptor(current) is true and ! IsAccessorDescriptor(Desc) is true, then
+        // a. If IsDataDescriptor(current) is true and IsAccessorDescriptor(Desc) is true, then
         if (current->is_data_descriptor() && descriptor.is_accessor_descriptor()) {
             // i. If Desc has a [[Configurable]] field, let configurable be Desc.[[Configurable]], else let configurable be current.[[Configurable]].
             auto configurable = descriptor.configurable.value_or(*current->configurable);
@@ -336,7 +335,7 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
             attributes.set_configurable(configurable);
             object->storage_set(property_key, { accessor, attributes });
         }
-        // b. Else if ! IsAccessorDescriptor(current) is true and ! IsDataDescriptor(Desc) is true, then
+        // b. Else if IsAccessorDescriptor(current) is true and IsDataDescriptor(Desc) is true, then
         else if (current->is_accessor_descriptor() && descriptor.is_data_descriptor()) {
             // i. If Desc has a [[Configurable]] field, let configurable be Desc.[[Configurable]], else let configurable be current.[[Configurable]].
             auto configurable = descriptor.configurable.value_or(*current->configurable);
@@ -488,7 +487,6 @@ ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject& global_
     // 4. Let bv be ? RequireObjectCoercible(baseValue).
     auto bv = TRY(require_object_coercible(global_object, base_value));
     // 5. Return the Reference Record { [[Base]]: bv, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }.
-    // 6. NOTE: This returns a Super Reference Record.
     return Reference { bv, property_key, actual_this, strict };
 }
 
@@ -730,7 +728,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
                 // 1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts.
                 // 2. For each element name of varNames, do
                 TRY(program.for_each_var_declared_name([&](auto const& name) -> ThrowCompletionOr<void> {
-                    // a. If thisEnv.HasBinding(name) is true, then
+                    // a. If ! thisEnv.HasBinding(name) is true, then
                     if (MUST(this_environment->has_binding(name))) {
                         // i. Throw a SyntaxError exception.
                         return vm.throw_completion<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
@@ -821,8 +819,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
             while (this_environment != variable_environment) {
                 // a. If thisEnv is not an object Environment Record, then
                 if (!is<ObjectEnvironment>(*this_environment)) {
-                    // i. If thisEnv.HasBinding(F) is true, then
-
+                    // i. If ! thisEnv.HasBinding(F) is true, then
                     if (MUST(this_environment->has_binding(function_name))) {
                         // i. Let bindingExists be true.
                         // Note: When bindingExists is true we skip all the other steps.
@@ -866,7 +863,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
                 // ii. Else,
                 else {
 
-                    // i. Let bindingExists be varEnv.HasBinding(F).
+                    // i. Let bindingExists be ! varEnv.HasBinding(F).
                     // ii. If bindingExists is false, then
                     if (!MUST(variable_environment->has_binding(function_name))) {
                         // i. Perform ! varEnv.CreateMutableBinding(F, true).
@@ -885,7 +882,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
             //     ii. Let benv be the running execution context's LexicalEnvironment.
             //     iii. Let fobj be ! benv.GetBindingValue(F, false).
             //     iv. Perform ? genv.SetMutableBinding(F, fobj, false).
-            //     v. Return NormalCompletion(empty).
+            //     v. Return unused.
             function_declaration.set_should_do_additional_annexB_steps();
 
             return {};
@@ -958,13 +955,13 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
         }
         // d. Else,
         else {
-            // i. Let bindingExists be varEnv.HasBinding(fn).
+            // i. Let bindingExists be ! varEnv.HasBinding(fn).
             auto binding_exists = MUST(variable_environment->has_binding(declaration.name()));
 
             // ii. If bindingExists is false, then
             if (!binding_exists) {
-                // 1. Let status be ! varEnv.CreateMutableBinding(fn, true).
-                // 2. Assert: status is not an abrupt completion because of validation preceding step 14.
+                // 1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
+                // 2. Perform ! varEnv.CreateMutableBinding(fn, true).
                 MUST(variable_environment->create_mutable_binding(global_object, declaration.name(), true));
 
                 // 3. Perform ! varEnv.InitializeBinding(fn, fo).
@@ -988,13 +985,13 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
         }
         // b. Else,
         else {
-            // i. Let bindingExists be varEnv.HasBinding(vn).
+            // i. Let bindingExists be ! varEnv.HasBinding(vn).
             auto binding_exists = MUST(variable_environment->has_binding(var_name));
 
             // ii. If bindingExists is false, then
             if (!binding_exists) {
-                // 1. Let status be ! varEnv.CreateMutableBinding(vn, true).
-                // 2. Assert: status is not an abrupt completion because of validation preceding step 14.
+                // 1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
+                // 2. Perform ! varEnv.CreateMutableBinding(vn, true).
                 MUST(variable_environment->create_mutable_binding(global_object, var_name, true));
 
                 // 3. Perform ! varEnv.InitializeBinding(vn, undefined).
@@ -1003,7 +1000,7 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& glo
         }
     }
 
-    // 19. Return NormalCompletion(empty).
+    // 19. Return unused.
     return {};
 }
 
@@ -1015,12 +1012,12 @@ Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value
     // 1. Let len be the number of elements in argumentsList.
     auto length = arguments.size();
 
-    // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
+    // 2. Let obj be OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
     // 3. Set obj.[[ParameterMap]] to undefined.
     auto* object = Object::create(global_object, global_object.object_prototype());
     object->set_has_parameter_map();
 
-    // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
+    // 4. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
     MUST(object->define_property_or_throw(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = true }));
 
     // 5. Let index be 0.
@@ -1058,7 +1055,7 @@ Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObje
     VERIFY(arguments.size() <= NumericLimits<i32>::max());
     i32 length = static_cast<i32>(arguments.size());
 
-    // 3. Let obj be ! MakeBasicObject(« [[Prototype]], [[Extensible]], [[ParameterMap]] »).
+    // 3. Let obj be MakeBasicObject(« [[Prototype]], [[Extensible]], [[ParameterMap]] »).
     // 4. Set obj.[[GetOwnProperty]] as specified in 10.4.4.1.
     // 5. Set obj.[[DefineOwnProperty]] as specified in 10.4.4.2.
     // 6. Set obj.[[Get]] as specified in 10.4.4.3.
@@ -1103,7 +1100,7 @@ Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObje
         if (index < length) {
             // 1. Let g be MakeArgGetter(name, env).
             // 2. Let p be MakeArgSetter(name, env).
-            // 3. Perform map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true }).
+            // 3. Perform ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true }).
             object->parameter_map().define_native_accessor(
                 PropertyKey { index },
                 [&environment, name](VM&, GlobalObject& global_object_getter) -> ThrowCompletionOr<Value> {

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -46,7 +46,7 @@ ThrowCompletionOr<Object*> AggregateErrorConstructor::construct(FunctionObject&
 
     if (!vm.argument(1).is_undefined()) {
         auto message = TRY(vm.argument(1).to_string(global_object));
-        MUST(aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message)));
+        aggregate_error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, message));
     }
 
     TRY(aggregate_error->install_error_cause(vm.argument(2)));

+ 20 - 21
Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp

@@ -41,14 +41,15 @@ ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& proper
 
     // 3. If isMapped is false, then
     if (!is_mapped) {
-        // a. Return ? OrdinaryGet(args, P, Receiver).
+        // a. Return ! OrdinaryGet(args, P, Receiver).
+        // FIXME: Using MUST here breaks one test in test262 (spec issue).
         return Object::internal_get(property_key, receiver);
     }
 
     // FIXME: a. Assert: map contains a formal parameter mapping for P.
 
-    // b. Return Get(map, P).
-    return map.get(property_key);
+    // b. Return ! Get(map, P).
+    return MUST(map.get(property_key));
 }
 
 // 10.4.4.4 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-set-p-v-receiver
@@ -68,11 +69,10 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_set(PropertyKey const& propert
 
     // 3. If isMapped is true, then
     if (is_mapped) {
-        // a. Let setStatus be Set(map, P, V, false).
-        auto set_status = MUST(m_parameter_map->set(property_key, value, Object::ShouldThrowExceptions::No));
+        // a. Assert: The following Set will succeed, since formal parameters mapped by arguments objects are always writable.
 
-        // b. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
-        VERIFY(set_status);
+        // b. Perform ! Set(map, P, V, false).
+        MUST(m_parameter_map->set(property_key, value, Object::ShouldThrowExceptions::No));
     }
 
     // 4. Return ? OrdinarySet(args, P, V, Receiver).
@@ -93,7 +93,7 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_delete(PropertyKey const& prop
 
     // 4. If result is true and isMapped is true, then
     if (result && is_mapped) {
-        // a. Call map.[[Delete]](P).
+        // a. Perform ! map.[[Delete]](P).
         MUST(map.internal_delete(property_key));
     }
 
@@ -117,8 +117,8 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_ow
 
     // 5. If isMapped is true, then
     if (is_mapped) {
-        // a. Set desc.[[Value]] to Get(map, P).
-        desc->value = TRY(m_parameter_map->get(property_key));
+        // a. Set desc.[[Value]] to ! Get(map, P).
+        desc->value = MUST(m_parameter_map->get(property_key));
     }
 
     // 6. Return desc.
@@ -131,7 +131,7 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
     // 1. Let map be args.[[ParameterMap]].
     auto& map = parameter_map();
 
-    // 2. Let isMapped be HasOwnProperty(map, P).
+    // 2. Let isMapped be ! HasOwnProperty(map, P).
     bool is_mapped = MUST(map.has_own_property(property_key));
 
     // 3. Let newArgDesc be Desc.
@@ -143,13 +143,13 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
         if (!descriptor.value.has_value() && descriptor.writable.has_value() && descriptor.writable == false) {
             // i. Set newArgDesc to a copy of Desc.
             new_arg_desc = descriptor;
-            // ii. Set newArgDesc.[[Value]] to Get(map, P).
-            new_arg_desc.value = TRY(map.get(property_key));
+            // ii. Set newArgDesc.[[Value]] to ! Get(map, P).
+            new_arg_desc.value = MUST(map.get(property_key));
         }
     }
 
-    // 5. Let allowed be ? OrdinaryDefineOwnProperty(args, P, newArgDesc).
-    bool allowed = TRY(Object::internal_define_own_property(property_key, new_arg_desc));
+    // 5. Let allowed be ! OrdinaryDefineOwnProperty(args, P, newArgDesc).
+    bool allowed = MUST(Object::internal_define_own_property(property_key, new_arg_desc));
 
     // 6. If allowed is false, return false.
     if (!allowed)
@@ -159,20 +159,19 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
     if (is_mapped) {
         // a. If IsAccessorDescriptor(Desc) is true, then
         if (descriptor.is_accessor_descriptor()) {
-            // i. Call map.[[Delete]](P).
+            // i. Perform ! map.[[Delete]](P).
             MUST(map.internal_delete(property_key));
         } else {
             // i. If Desc has a [[Value]] field, then
             if (descriptor.value.has_value()) {
-                // 1. Let setStatus be Set(map, P, Desc.[[Value]], false).
-                bool set_status = MUST(map.set(property_key, descriptor.value.value(), Object::ShouldThrowExceptions::No));
+                // 1. Assert: The following Set will succeed, since formal parameters mapped by arguments objects are always writable.
 
-                // 2. Assert: setStatus is true because formal parameters mapped by argument objects are always writable.
-                VERIFY(set_status);
+                // 2. Perform ! Set(map, P, Desc.[[Value]], false).
+                MUST(map.set(property_key, descriptor.value.value(), Object::ShouldThrowExceptions::No));
             }
             // ii. If Desc has a [[Writable]] field and Desc.[[Writable]] is false, then
             if (descriptor.writable == false) {
-                // 1. Call map.[[Delete]](P).
+                // 1. Perform ! map.[[Delete]](P).
                 MUST(map.internal_delete(property_key));
             }
         }

+ 8 - 8
Userland/Libraries/LibJS/Runtime/Array.cpp

@@ -57,7 +57,7 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
     auto& vm = this->vm();
 
     // 1. If Desc does not have a [[Value]] field, then
-    // a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
+    // a. Return ! OrdinaryDefineOwnProperty(A, "length", Desc).
     // 2. Let newLenDesc be a copy of Desc.
     // NOTE: Handled by step 16
 
@@ -74,11 +74,11 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
 
     // 6. Set newLenDesc.[[Value]] to newLen.
     // 7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
-    // 8. Assert: ! IsDataDescriptor(oldLenDesc) is true.
+    // 8. Assert: IsDataDescriptor(oldLenDesc) is true.
     // 9. Assert: oldLenDesc.[[Configurable]] is false.
     // 10. Let oldLen be oldLenDesc.[[Value]].
     // 11. If newLen ≥ oldLen, then
-    // a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc).
+    // a. Return ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
     // 12. If oldLenDesc.[[Writable]] is false, return false.
     // NOTE: Handled by step 16
 
@@ -100,10 +100,10 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
     // a. If Desc has a [[Configurable]] field and Desc.[[Configurable]] is true, return false.
     if (property_descriptor.configurable.has_value() && *property_descriptor.configurable)
         return false;
-    // b. If Desc has an [[Enumerable]] field and ! SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return false.
+    // b. If Desc has an [[Enumerable]] field and SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return false.
     if (property_descriptor.enumerable.has_value() && *property_descriptor.enumerable)
         return false;
-    // c. If ! IsGenericDescriptor(Desc) is false and ! SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current)) is false, return false.
+    // c. If IsGenericDescriptor(Desc) is false and SameValue(IsAccessorDescriptor(Desc), IsAccessorDescriptor(current)) is false, return false.
     if (!property_descriptor.is_generic_descriptor() && property_descriptor.is_accessor_descriptor())
         return false;
     // NOTE: Step d. doesn't apply here.
@@ -168,7 +168,7 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
     // 2. Else if P is an array index, then
     if (property_key.is_number()) {
         // a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
-        // b. Assert: ! IsDataDescriptor(oldLenDesc) is true.
+        // b. Assert: IsDataDescriptor(oldLenDesc) is true.
         // c. Assert: oldLenDesc.[[Configurable]] is false.
         // d. Let oldLen be oldLenDesc.[[Value]].
         // e. Assert: oldLen is a non-negative integral Number.
@@ -187,14 +187,14 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
 
         // j. If index ≥ oldLen, then
         // i. Set oldLenDesc.[[Value]] to index + 1𝔽.
-        // ii. Set succeeded to OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
+        // ii. Set succeeded to ! OrdinaryDefineOwnProperty(A, "length", oldLenDesc).
         // iii. Assert: succeeded is true.
 
         // k. Return true.
         return true;
     }
 
-    // 3. Return OrdinaryDefineOwnProperty(A, P, Desc).
+    // 3. Return ? OrdinaryDefineOwnProperty(A, P, Desc).
     return Object::internal_define_own_property(property_key, property_descriptor);
 }
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2022, the SerenityOS developers.
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -98,7 +98,7 @@ ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(GlobalObject& global_objec
 }
 
 // 25.1.2.3 DetachArrayBuffer ( arrayBuffer [ , key ] ), https://tc39.es/ecma262/#sec-detacharraybuffer
-ThrowCompletionOr<Value> detach_array_buffer(GlobalObject& global_object, ArrayBuffer& array_buffer, Optional<Value> key)
+ThrowCompletionOr<void> detach_array_buffer(GlobalObject& global_object, ArrayBuffer& array_buffer, Optional<Value> key)
 {
     auto& vm = global_object.vm();
 
@@ -118,7 +118,7 @@ ThrowCompletionOr<Value> detach_array_buffer(GlobalObject& global_object, ArrayB
     array_buffer.detach_buffer();
 
     // 6. Return unused.
-    return js_null();
+    return {};
 }
 
 // 25.1.2.4 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength, cloneConstructor ), https://tc39.es/ecma262/#sec-clonearraybuffer

+ 4 - 5
Userland/Libraries/LibJS/Runtime/ArrayBuffer.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -57,7 +57,7 @@ public:
     template<typename type>
     Value get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
     template<typename type>
-    Value set_value(size_t byte_index, Value value, bool is_typed_array, Order, bool is_little_endian = true);
+    void set_value(size_t byte_index, Value value, bool is_typed_array, Order, bool is_little_endian = true);
     template<typename T>
     Value get_modify_set_value(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true);
 
@@ -81,7 +81,7 @@ private:
 };
 
 ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(GlobalObject&, FunctionObject& constructor, size_t byte_length, Optional<size_t> max_byte_length = {});
-ThrowCompletionOr<Value> detach_array_buffer(GlobalObject&, ArrayBuffer& array_buffer, Optional<Value> key = {});
+ThrowCompletionOr<void> detach_array_buffer(GlobalObject&, ArrayBuffer& array_buffer, Optional<Value> key = {});
 ThrowCompletionOr<ArrayBuffer*> clone_array_buffer(GlobalObject&, ArrayBuffer& source_buffer, size_t source_byte_offset, size_t source_length);
 
 // 25.1.2.9 RawBytesToNumeric ( type, rawBytes, isLittleEndian ), https://tc39.es/ecma262/#sec-rawbytestonumeric
@@ -201,14 +201,13 @@ static ByteBuffer numeric_to_raw_bytes(GlobalObject& global_object, Value value,
 
 // 25.1.2.12 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-setvalueinbuffer
 template<typename T>
-Value ArrayBuffer::set_value(size_t byte_index, Value value, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
+void ArrayBuffer::set_value(size_t byte_index, Value value, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
 {
     auto raw_bytes = numeric_to_raw_bytes<T>(global_object(), value, is_little_endian);
 
     // FIXME: Check for shared buffer
 
     raw_bytes.span().copy_to(buffer_impl().span().slice(byte_index));
-    return js_undefined();
 }
 
 // 25.1.2.13 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer

+ 15 - 15
Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp

@@ -179,7 +179,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::filter)
             // i. Let kValue be ? Get(O, Pk).
             auto k_value = TRY(object->get(k));
 
-            // ii. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
+            // ii. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
             auto selected = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
 
             // iii. If selected is true, then
@@ -1128,7 +1128,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find)
         // b. Let kValue be ? Get(O, Pk).
         auto k_value = TRY(object->get(property_key));
 
-        // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
+        // c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
         auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
 
         // d. If testResult is true, return kValue.
@@ -1167,7 +1167,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_index)
         // b. Let kValue be ? Get(O, Pk).
         auto k_value = TRY(object->get(property_key));
 
-        // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
+        // c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
         auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
 
         // d. If testResult is true, return 𝔽(k).
@@ -1206,7 +1206,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last)
         // b. Let kValue be ? Get(O, Pk).
         auto k_value = TRY(object->get(property_key));
 
-        // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
+        // c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
         auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
 
         // d. If testResult is true, return kValue.
@@ -1245,7 +1245,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::find_last_index)
         // b. Let kValue be ? Get(O, Pk).
         auto k_value = TRY(object->get(property_key));
 
-        // c. Let testResult be ! ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
+        // c. Let testResult be ToBoolean(? Call(predicate, thisArg, « kValue, 𝔽(k), O »)).
         auto test_result = TRY(call(global_object, predicate.as_function(), this_arg, k_value, Value((double)k), object)).to_boolean();
 
         // d. If testResult is true, return 𝔽(k).
@@ -1289,7 +1289,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::some)
             // i. Let kValue be ? Get(O, Pk).
             auto k_value = TRY(object->get(property_key));
 
-            // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
+            // ii. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
             auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
 
             // iii. If testResult is true, return true.
@@ -1334,7 +1334,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::every)
             // i. Let kValue be ? Get(O, Pk).
             auto k_value = TRY(object->get(property_key));
 
-            // ii. Let testResult be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
+            // ii. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
             auto test_result = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(k), object)).to_boolean();
 
             // iii. If testResult is false, return false.
@@ -1567,7 +1567,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
     // 2. Let sourceLen be ? LengthOfArrayLike(O).
     auto source_length = TRY(length_of_array_like(global_object, *object));
 
-    // 3. If ! IsCallable(mapperFunction) is false, throw a TypeError exception.
+    // 3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
     if (!mapper_function.is_function())
         return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, mapper_function.to_string_without_side_effects());
 
@@ -1672,7 +1672,7 @@ template<typename GroupsType, typename KeyType>
 static void add_value_to_keyed_group(GlobalObject& global_object, GroupsType& groups, KeyType key, Value value)
 {
     // 1. For each Record { [[Key]], [[Elements]] } g of groups, do
-    //      a. If ! SameValue(g.[[Key]], key) is true, then
+    //      a. If SameValue(g.[[Key]], key) is true, then
     //      NOTE: This is performed in KeyedGroupTraits::equals for groupByToMap and Traits<JS::PropertyKey>::equals for groupBy.
     auto existing_elements_iterator = groups.find(key);
     if (existing_elements_iterator != groups.end()) {
@@ -1682,7 +1682,7 @@ static void add_value_to_keyed_group(GlobalObject& global_object, GroupsType& gr
         // ii. Append value as the last element of g.[[Elements]].
         existing_elements_iterator->value.append(value);
 
-        // iii. Return.
+        // iii. Return unused.
         return;
     }
 
@@ -1727,18 +1727,18 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by)
         auto property_key_value = TRY(call(global_object, callback_function.as_function(), this_arg, k_value, Value(index), this_object));
         auto property_key = TRY(property_key_value.to_property_key(global_object));
 
-        // d. Perform ! AddValueToKeyedGroup(groups, propertyKey, kValue).
+        // d. Perform AddValueToKeyedGroup(groups, propertyKey, kValue).
         add_value_to_keyed_group(global_object, groups, property_key, k_value);
 
         // e. Set k to k + 1.
     }
 
-    // 7. Let obj be ! OrdinaryObjectCreate(null).
+    // 7. Let obj be OrdinaryObjectCreate(null).
     auto* object = Object::create(global_object, nullptr);
 
     // 8. For each Record { [[Key]], [[Elements]] } g of groups, do
     for (auto& group : groups) {
-        // a. Let elements be ! CreateArrayFromList(g.[[Elements]]).
+        // a. Let elements be CreateArrayFromList(g.[[Elements]]).
         auto* elements = Array::create_from(global_object, group.value);
 
         // b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
@@ -1797,7 +1797,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by_to_map)
         if (key.is_negative_zero())
             key = Value(0);
 
-        // e. Perform ! AddValueToKeyedGroup(groups, key, kValue).
+        // e. Perform AddValueToKeyedGroup(groups, key, kValue).
         add_value_to_keyed_group(global_object, groups, make_handle(key), k_value);
 
         // f. Set k to k + 1.
@@ -1808,7 +1808,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::group_by_to_map)
 
     // 8. For each Record { [[Key]], [[Elements]] } g of groups, do
     for (auto& group : groups) {
-        // a. Let elements be ! CreateArrayFromList(g.[[Elements]]).
+        // a. Let elements be CreateArrayFromList(g.[[Elements]]).
         auto* elements = Array::create_from(global_object, group.value);
 
         // b. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.

+ 35 - 36
Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp

@@ -31,36 +31,35 @@ void AsyncFromSyncIteratorPrototype::initialize(GlobalObject& global_object)
 }
 
 // 27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability ), https://tc39.es/ecma262/#sec-asyncfromsynciteratorcontinuation
-static ThrowCompletionOr<Object*> async_from_sync_iterator_continuation(GlobalObject& global_object, Object& result, PromiseCapability& promise_capability)
+static Object* async_from_sync_iterator_continuation(GlobalObject& global_object, Object& result, PromiseCapability& promise_capability)
 {
-    // 1. Let done be IteratorComplete(result).
-    // 2. IfAbruptRejectPromise(done, promiseCapability).
-    auto done = TRY_OR_REJECT(global_object, promise_capability, iterator_complete(global_object, result));
+    // 1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
+    // 2. Let done be Completion(IteratorComplete(result)).
+    // 3. IfAbruptRejectPromise(done, promiseCapability).
+    auto done = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_complete(global_object, result));
 
-    // 3. Let value be IteratorValue(result).
-    // 4. IfAbruptRejectPromise(value, promiseCapability).
-    auto value = TRY_OR_REJECT(global_object, promise_capability, iterator_value(global_object, result));
+    // 4. Let value be Completion(IteratorValue(result)).
+    // 5. IfAbruptRejectPromise(value, promiseCapability).
+    auto value = TRY_OR_MUST_REJECT(global_object, promise_capability, iterator_value(global_object, result));
 
-    // 5. Let valueWrapper be PromiseResolve(%Promise%, value).
-    // 6. IfAbruptRejectPromise(valueWrapper, promiseCapability).
-    auto value_wrapper = TRY_OR_REJECT(global_object, promise_capability, promise_resolve(global_object, *global_object.promise_constructor(), value));
+    // 6. Let valueWrapper be PromiseResolve(%Promise%, value).
+    // 7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
+    auto value_wrapper = TRY_OR_MUST_REJECT(global_object, promise_capability, promise_resolve(global_object, *global_object.promise_constructor(), value));
 
-    // 7. Let unwrap be a new Abstract Closure with parameters (value) that captures done and performs the following steps when called:
+    // 8. Let unwrap be a new Abstract Closure with parameters (value) that captures done and performs the following steps when called:
     auto unwrap = [done](VM& vm, GlobalObject& global_object) -> ThrowCompletionOr<Value> {
-        // a. Return ! CreateIterResultObject(value, done).
+        // a. Return CreateIterResultObject(value, done).
         return create_iterator_result_object(global_object, vm.argument(0), done);
     };
 
-    // 8. Let onFulfilled be ! CreateBuiltinFunction(unwrap, 1, "", « »).
+    // 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
+    // 10. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
     auto* on_fulfilled = NativeFunction::create(global_object, move(unwrap), 1, "");
-    // 9. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
-    VERIFY(is<Promise>(value_wrapper));
-    auto* value_wrapper_promise = static_cast<Promise*>(value_wrapper);
 
-    // 10. Perform ! PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
-    value_wrapper_promise->perform_then(move(on_fulfilled), js_undefined(), promise_capability);
+    // 11. Perform PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
+    verify_cast<Promise>(value_wrapper)->perform_then(move(on_fulfilled), js_undefined(), promise_capability);
 
-    // 11. Return promiseCapability.[[Promise]].
+    // 12. Return promiseCapability.[[Promise]].
     return promise_capability.promise;
 }
 
@@ -78,16 +77,16 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::next)
     auto& sync_iterator_record = this_object->sync_iterator_record();
 
     // 5. If value is present, then
-    //     a. Let result be IteratorNext(syncIteratorRecord, value).
+    //     a. Let result be Completion(IteratorNext(syncIteratorRecord, value)).
     // 6. Else,
-    //     a. Let result be IteratorNext(syncIteratorRecord).
+    //     a. Let result be Completion(IteratorNext(syncIteratorRecord)).
     // 7. IfAbruptRejectPromise(result, promiseCapability).
     auto* result = TRY_OR_REJECT(global_object, promise_capability,
         (vm.argument_count() > 0 ? iterator_next(global_object, sync_iterator_record, vm.argument(0))
                                  : iterator_next(global_object, sync_iterator_record)));
 
-    // 8. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).
-    return MUST(async_from_sync_iterator_continuation(global_object, *result, promise_capability));
+    // 8. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
+    return async_from_sync_iterator_continuation(global_object, *result, promise_capability);
 }
 
 // 27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.return
@@ -103,13 +102,13 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
     auto* sync_iterator = this_object->sync_iterator_record().iterator;
 
-    // 5. Let return be GetMethod(syncIterator, "return").
+    // 5. Let return be Completion(GetMethod(syncIterator, "return")).
     // 6. IfAbruptRejectPromise(return, promiseCapability).
     auto* return_method = TRY_OR_REJECT(global_object, promise_capability, Value(sync_iterator).get_method(global_object, vm.names.return_));
 
     // 7. If return is undefined, then
     if (return_method == nullptr) {
-        // a. Let iterResult be ! CreateIterResultObject(value, true).
+        // a. Let iterResult be CreateIterResultObject(value, true).
         auto* iter_result = create_iterator_result_object(global_object, vm.argument(0), true);
 
         // b. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
@@ -120,9 +119,9 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
     }
 
     // 8. If value is present, then
-    //     a. Let result be Call(return, syncIterator, « value »).
+    //     a. Let result be Completion(Call(return, syncIterator, « value »)).
     // 9. Else,
-    //     a. Let result be Call(return, syncIterator).
+    //     a. Let result be Completion(Call(return, syncIterator)).
     // 10. IfAbruptRejectPromise(result, promiseCapability).
     auto result = TRY_OR_REJECT(global_object, promise_capability,
         (vm.argument_count() > 0 ? call(global_object, return_method, sync_iterator, vm.argument(0))
@@ -137,8 +136,8 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
         return promise_capability.promise;
     }
 
-    // 12. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).
-    return MUST(async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability));
+    // 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
+    return async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability);
 }
 
 // 27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] ), https://tc39.es/ecma262/#sec-%asyncfromsynciteratorprototype%.throw
@@ -154,7 +153,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
     auto* sync_iterator = this_object->sync_iterator_record().iterator;
 
-    // 5. Let throw be GetMethod(syncIterator, "throw").
+    // 5. Let throw be Completion(GetMethod(syncIterator, "throw")).
     // 6. IfAbruptRejectPromise(throw, promiseCapability).
     auto* throw_method = TRY_OR_REJECT(global_object, promise_capability, Value(sync_iterator).get_method(global_object, vm.names.throw_));
 
@@ -166,9 +165,9 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
         return promise_capability.promise;
     }
     // 8. If value is present, then
-    //     a. Let result be Call(throw, syncIterator, « value »).
+    //     a. Let result be Completion(Call(throw, syncIterator, « value »)).
     // 9. Else,
-    //     a. Let result be Call(throw, syncIterator).
+    //     a. Let result be Completion(Call(throw, syncIterator)).
     // 10. IfAbruptRejectPromise(result, promiseCapability).
     auto result = TRY_OR_REJECT(global_object, promise_capability,
         (vm.argument_count() > 0 ? call(global_object, throw_method, sync_iterator, vm.argument(0))
@@ -184,16 +183,16 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
         return promise_capability.promise;
     }
 
-    // 12. Return ! AsyncFromSyncIteratorContinuation(result, promiseCapability).
-    return MUST(async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability));
+    // 12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).
+    return async_from_sync_iterator_continuation(global_object, result.as_object(), promise_capability);
 }
 
 // 27.1.4.1 CreateAsyncFromSyncIterator ( syncIteratorRecord ), https://tc39.es/ecma262/#sec-createasyncfromsynciterator
-ThrowCompletionOr<Iterator> create_async_from_sync_iterator(GlobalObject& global_object, Iterator sync_iterator_record)
+Iterator create_async_from_sync_iterator(GlobalObject& global_object, Iterator sync_iterator_record)
 {
     auto& vm = global_object.vm();
 
-    // 1. Let asyncIterator be ! OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
+    // 1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
     // 2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
     auto* async_iterator = AsyncFromSyncIterator::create(global_object, sync_iterator_record);
 

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

@@ -29,6 +29,6 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(throw_);
 };
 
-ThrowCompletionOr<Iterator> create_async_from_sync_iterator(GlobalObject&, Iterator sync_iterator);
+Iterator create_async_from_sync_iterator(GlobalObject&, Iterator sync_iterator);
 
 }

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

@@ -38,7 +38,7 @@ static ThrowCompletionOr<ArrayBuffer*> validate_integer_typed_array(GlobalObject
     // 5. Else,
     else {
         // a. Let type be TypedArrayElementType(typedArray).
-        // b. If ! IsUnclampedIntegerElementType(type) is false and ! IsBigIntElementType(type) is false, throw a TypeError exception.
+        // b. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
         if (!typed_array.is_unclamped_integer_element_type() && !typed_array.is_bigint_element_type())
             return vm.throw_completion<TypeError>(global_object, ErrorType::TypedArrayTypeIsNot, type_name, "an unclamped integer or BigInt"sv);
     }

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

@@ -18,7 +18,7 @@ ThrowCompletionOr<BoundFunction*> BoundFunction::create(GlobalObject& global_obj
     auto* prototype = TRY(target_function.internal_get_prototype_of());
 
     // 2. Let internalSlotsList be the list-concatenation of « [[Prototype]], [[Extensible]] » and the internal slots listed in Table 34.
-    // 3. Let obj be ! MakeBasicObject(internalSlotsList).
+    // 3. Let obj be MakeBasicObject(internalSlotsList).
     // 4. Set obj.[[Prototype]] to proto.
     // 5. Set obj.[[Call]] as described in 10.4.1.1.
     // 6. If IsConstructor(targetFunction) is true, then

+ 6 - 6
Userland/Libraries/LibJS/Runtime/Completion.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -62,7 +62,7 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
         return js_undefined();
     };
 
-    // 4. Let onFulfilled be ! CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
+    // 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
     auto* on_fulfilled = NativeFunction::create(global_object, move(fulfilled_closure), 1, "");
 
     // 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
@@ -86,10 +86,10 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
         return js_undefined();
     };
 
-    // 6. Let onRejected be ! CreateBuiltinFunction(rejectedClosure, 1, "", « »).
+    // 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
     auto* on_rejected = NativeFunction::create(global_object, move(rejected_closure), 1, "");
 
-    // 7. Perform ! PerformPromiseThen(promise, onFulfilled, onRejected).
+    // 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
     auto* promise = verify_cast<Promise>(promise_object);
     promise->perform_then(on_fulfilled, on_rejected, {});
 
@@ -103,8 +103,8 @@ ThrowCompletionOr<Value> await(GlobalObject& global_object, Value value)
     // 8. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
     // NOTE: Since we don't push any EC, this step is not performed.
 
-    // 9. Set the code evaluation state of asyncContext such that when evaluation is resumed with a Completion completion, the following steps of the algorithm that invoked Await will be performed, with completion available.
-    // 10. Return.
+    // 9. Set the code evaluation state of asyncContext such that when evaluation is resumed with a Completion Record completion, the following steps of the algorithm that invoked Await will be performed, with completion available.
+    // 10. Return NormalCompletion(unused).
     // 11. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of asyncContext.
 
     vm.run_queued_promise_jobs();

+ 6 - 1
Userland/Libraries/LibJS/Runtime/Completion.h

@@ -44,6 +44,11 @@ public:
     {
     }
 
+    ALWAYS_INLINE Completion(Optional<Value> value)
+        : Completion(Type::Normal, move(value), {})
+    {
+    }
+
     ALWAYS_INLINE Completion()
         : Completion(js_undefined())
     {
@@ -80,7 +85,7 @@ public:
         if (m_type == Type::Return || m_type == Type::Throw)
             VERIFY(m_value.has_value());
 
-        // 2. If completionRecord.[[Value]] is not empty, return Completion(completionRecord).
+        // 2. If completionRecord.[[Value]] is not empty, return ? completionRecord.
         if (m_value.has_value())
             return *this;
 

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

@@ -114,7 +114,9 @@ static ThrowCompletionOr<Value> set_view_value(GlobalObject& global_object, Valu
     if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
         return vm.throw_completion<RangeError>(global_object, ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
 
-    return buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
+    buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
+
+    return js_undefined();
 }
 
 // 25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getbigint64

+ 13 - 12
Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp

@@ -58,6 +58,9 @@ ThrowCompletionOr<bool> DeclarativeEnvironment::has_binding(FlyString const& nam
 // 9.1.1.1.2 CreateMutableBinding ( N, D ), https://tc39.es/ecma262/#sec-declarative-environment-records-createmutablebinding-n-d
 ThrowCompletionOr<void> DeclarativeEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted)
 {
+    // 1. Assert: envRec does not already have a binding for N.
+    // NOTE: We skip this to avoid O(n) traversal of m_bindings.
+
     // 2. Create a mutable binding in envRec for N and record that it is uninitialized. If D is true, record that the newly created binding may be deleted by a subsequent DeleteBinding call.
     m_bindings.append(Binding {
         .name = name,
@@ -68,16 +71,16 @@ ThrowCompletionOr<void> DeclarativeEnvironment::create_mutable_binding(GlobalObj
         .initialized = false,
     });
 
-    // 1. Assert: envRec does not already have a binding for N.
-    // NOTE: We skip this to avoid O(n) traversal of m_bindings.
-
-    // 3. Return NormalCompletion(empty).
+    // 3. Return unused.
     return {};
 }
 
 // 9.1.1.1.3 CreateImmutableBinding ( N, S ), https://tc39.es/ecma262/#sec-declarative-environment-records-createimmutablebinding-n-s
 ThrowCompletionOr<void> DeclarativeEnvironment::create_immutable_binding(GlobalObject&, FlyString const& name, bool strict)
 {
+    // 1. Assert: envRec does not already have a binding for N.
+    // NOTE: We skip this to avoid O(n) traversal of m_bindings.
+
     // 2. Create an immutable binding in envRec for N and record that it is uninitialized. If S is true, record that the newly created binding is a strict binding.
     m_bindings.append(Binding {
         .name = name,
@@ -88,10 +91,7 @@ ThrowCompletionOr<void> DeclarativeEnvironment::create_immutable_binding(GlobalO
         .initialized = false,
     });
 
-    // 1. Assert: envRec does not already have a binding for N.
-    // NOTE: We skip this to avoid O(n) traversal of m_bindings.
-
-    // 3. Return NormalCompletion(empty).
+    // 3. Return unused.
     return {};
 }
 
@@ -117,7 +117,7 @@ ThrowCompletionOr<void> DeclarativeEnvironment::initialize_binding_direct(Global
     // 3. Record that the binding for N in envRec has been initialized.
     binding.initialized = true;
 
-    // 4. Return NormalCompletion(empty).
+    // 4. Return unused.
     return {};
 }
 
@@ -131,20 +131,21 @@ ThrowCompletionOr<void> DeclarativeEnvironment::set_mutable_binding(GlobalObject
         if (strict)
             return vm().throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);
 
+        // FIXME: Should be `! envRec.CreateMutableBinding(N, true)` (see https://github.com/tc39/ecma262/pull/2764)
         // b. Perform envRec.CreateMutableBinding(N, true).
         MUST(create_mutable_binding(global_object, name, true));
 
-        // c. Perform envRec.InitializeBinding(N, V).
+        // c. Perform ! envRec.InitializeBinding(N, V).
         MUST(initialize_binding(global_object, name, value));
 
-        // d. Return NormalCompletion(empty).
+        // d. Return unused.
         return {};
     }
 
     // 2-5. (extracted into a non-standard function below)
     TRY(set_mutable_binding_direct(global_object, *index, value, strict));
 
-    // 6. Return NormalCompletion(empty).
+    // 6. Return unused.
     return {};
 }
 

+ 34 - 25
Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp

@@ -173,13 +173,13 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
     // 5. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
     ordinary_call_bind_this(callee_context, this_argument);
 
-    // 6. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+    // 6. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
     auto result = ordinary_call_evaluate_body();
 
     // 7. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
     vm.pop_execution_context();
 
-    // 8. If result.[[Type]] is return, return NormalCompletion(result.[[Value]]).
+    // 8. If result.[[Type]] is return, return result.[[Value]].
     if (result.type() == Completion::Type::Return)
         return result.value();
 
@@ -189,7 +189,7 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
         return result;
     }
 
-    // 10. Return NormalCompletion(undefined).
+    // 10. Return undefined.
     return js_undefined();
 }
 
@@ -232,7 +232,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
         // a. Perform OrdinaryCallBindThis(F, calleeContext, thisArgument).
         ordinary_call_bind_this(callee_context, this_argument);
 
-        // b. Let initializeResult be InitializeInstanceElements(thisArgument, F).
+        // b. Let initializeResult be Completion(InitializeInstanceElements(thisArgument, F)).
         auto initialize_result = vm.initialize_instance_elements(*this_argument, *this);
 
         // c. If initializeResult is an abrupt completion, then
@@ -240,7 +240,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
             // i. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
             vm.pop_execution_context();
 
-            // ii. Return Completion(initializeResult).
+            // ii. Return ? initializeResult.
             return initialize_result.throw_completion();
         }
     }
@@ -248,7 +248,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
     // 7. Let constructorEnv be the LexicalEnvironment of calleeContext.
     auto* constructor_env = callee_context.lexical_environment;
 
-    // 8. Let result be OrdinaryCallEvaluateBody(F, argumentsList).
+    // 8. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
     auto result = ordinary_call_evaluate_body();
 
     // 9. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
@@ -265,11 +265,11 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
         }
         // EOF (End of FIXME)
 
-        // a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]).
+        // a. If Type(result.[[Value]]) is Object, return result.[[Value]].
         if (result.value()->is_object())
             return &result.value()->as_object();
 
-        // b. If kind is base, return NormalCompletion(thisArgument).
+        // b. If kind is base, return thisArgument.
         if (kind == ConstructorKind::Base)
             return this_argument;
 
@@ -283,8 +283,13 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVe
         return result;
     }
 
-    // 12. Return ? constructorEnv.GetThisBinding().
+    // 12. Let thisBinding be ? constructorEnv.GetThisBinding().
     auto this_binding = TRY(constructor_env->get_this_binding(global_object));
+
+    // 13. Assert: Type(thisBinding) is Object.
+    VERIFY(this_binding.is_object());
+
+    // 14. Return thisBinding.
     return &this_binding.as_object();
 }
 
@@ -308,7 +313,7 @@ void ECMAScriptFunctionObject::make_method(Object& home_object)
     // 1. Set F.[[HomeObject]] to homeObject.
     m_home_object = &home_object;
 
-    // 2. Return NormalCompletion(undefined).
+    // 2. Return unused.
 }
 
 // 10.2.11 FunctionDeclarationInstantiation ( func, argumentsList ), https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
@@ -638,7 +643,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
     // 1. Let thisMode be F.[[ThisMode]].
     auto this_mode = m_this_mode;
 
-    // If thisMode is lexical, return NormalCompletion(undefined).
+    // If thisMode is lexical, return unused.
     if (this_mode == ThisMode::Lexical)
         return;
 
@@ -685,8 +690,10 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
 
     // 7. Assert: localEnv is a function Environment Record.
     // 8. Assert: The next step never returns an abrupt completion because localEnv.[[ThisBindingStatus]] is not initialized.
-    // 9. Return localEnv.BindThisValue(thisValue).
+    // 9. Perform ! localEnv.BindThisValue(thisValue).
     MUST(verify_cast<FunctionEnvironment>(local_env)->bind_this_value(global_object(), this_value));
+
+    // 10. Return unused.
 }
 
 // 27.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody ), https://tc39.es/ecma262/#sec-async-functions-abstract-operations-async-function-start
@@ -702,8 +709,10 @@ void ECMAScriptFunctionObject::async_function_start(PromiseCapability const& pro
 
     // 3. NOTE: Copying the execution state is required for AsyncBlockStart to resume its execution. It is ill-defined to resume a currently executing context.
 
-    // 4. Perform ! AsyncBlockStart(promiseCapability, asyncFunctionBody, asyncContext).
+    // 4. Perform AsyncBlockStart(promiseCapability, asyncFunctionBody, asyncContext).
     async_block_start(vm, m_ecmascript_code, promise_capability, async_context);
+
+    // 5. Return unused.
 }
 
 // 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ), https://tc39.es/ecma262/#sec-asyncblockstart
@@ -743,7 +752,8 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
             // ii. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
             MUST(call(global_object, promise_capability.reject, js_undefined(), *result.value()));
         }
-        // g. Return.
+        // g. Return unused.
+        // NOTE: We don't support returning an empty/optional/unused value here.
         return js_undefined();
     });
 
@@ -758,10 +768,10 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement> const& async_body, Promi
     // 6. Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.
     VERIFY(&vm.running_execution_context() == &running_context);
 
-    // 7. Assert: result is a normal completion with a value of undefined. The possible sources of completion values are Await or, if the async function doesn't await anything, step 3.g above.
+    // 7. Assert: result is a normal completion with a value of unused. The possible sources of completion values are Await or, if the async function doesn't await anything, step 3.g above.
     VERIFY(result.has_value() && result.value().is_undefined());
 
-    // 8. Return.
+    // 8. Return unused.
 }
 
 // 10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList ), https://tc39.es/ecma262/#sec-ordinarycallevaluatebody
@@ -854,18 +864,18 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
             // 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
             auto promise_capability = MUST(new_promise_capability(global_object(), global_object().promise_constructor()));
 
-            // 2. Let declResult be FunctionDeclarationInstantiation(functionObject, argumentsList).
+            // 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
             auto declaration_result = function_declaration_instantiation(ast_interpreter);
 
-            // 3. If declResult is not an abrupt completion, then
-            if (!declaration_result.is_throw_completion()) {
-                // a. Perform ! AsyncFunctionStart(promiseCapability, FunctionBody).
-                async_function_start(promise_capability);
+            // 3. If declResult is an abrupt completion, then
+            if (declaration_result.is_throw_completion()) {
+                // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
+                MUST(call(global_object(), promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
             }
             // 4. Else,
             else {
-                // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
-                MUST(call(global_object(), promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
+                // a. Perform AsyncFunctionStart(promiseCapability, FunctionBody).
+                async_function_start(promise_capability);
             }
 
             // 5. Return Completion Record { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.
@@ -880,8 +890,7 @@ void ECMAScriptFunctionObject::set_name(FlyString const& name)
     VERIFY(!name.is_null());
     auto& vm = this->vm();
     m_name = name;
-    auto success = MUST(define_property_or_throw(vm.names.name, { .value = js_string(vm, m_name), .writable = false, .enumerable = false, .configurable = true }));
-    VERIFY(success);
+    MUST(define_property_or_throw(vm.names.name, { .value = js_string(vm, m_name), .writable = false, .enumerable = false, .configurable = true }));
 }
 
 }

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

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -44,11 +44,11 @@ ThrowCompletionOr<void> Error::install_error_cause(Value options)
         // a. Let cause be ? Get(options, "cause").
         auto cause = TRY(options.as_object().get(vm.names.cause));
 
-        // b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause).
-        MUST(create_non_enumerable_data_property_or_throw(vm.names.cause, cause));
+        // b. Perform CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause).
+        create_non_enumerable_data_property_or_throw(vm.names.cause, cause);
     }
 
-    // 2. Return NormalCompletion(undefined).
+    // 2. Return unused.
     return {};
 }
 

+ 5 - 5
Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp

@@ -51,8 +51,8 @@ ThrowCompletionOr<Object*> ErrorConstructor::construct(FunctionObject& new_targe
         // a. Let msg be ? ToString(message).
         auto msg = TRY(message.to_string(global_object));
 
-        // b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
-        MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, move(msg))));
+        // b. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
+        error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, move(msg)));
     }
 
     // 4. Perform ? InstallErrorCause(O, options).
@@ -79,7 +79,7 @@ ThrowCompletionOr<Object*> ErrorConstructor::construct(FunctionObject& new_targe
         define_direct_property(vm.names.length, Value(1), Attribute::Configurable);                                                       \
     }                                                                                                                                     \
                                                                                                                                           \
-    ConstructorName::~ConstructorName() { }                                                                                               \
+    ConstructorName::~ConstructorName() = default;                                                                                        \
                                                                                                                                           \
     /* 20.5.6.1.1 NativeError ( message [ , options ] ), https://tc39.es/ecma262/#sec-nativeerror */                                      \
     ThrowCompletionOr<Value> ConstructorName::call()                                                                                      \
@@ -105,8 +105,8 @@ ThrowCompletionOr<Object*> ErrorConstructor::construct(FunctionObject& new_targe
             /* a. Let msg be ? ToString(message). */                                                                                      \
             auto msg = TRY(message.to_string(global_object));                                                                             \
                                                                                                                                           \
-            /* b. Perform ! CreateNonEnumerableDataPropertyOrThrow(O, "message", msg). */                                                 \
-            MUST(error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, move(msg))));                        \
+            /* b. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg). */                                                   \
+            error->create_non_enumerable_data_property_or_throw(vm.names.message, js_string(vm, move(msg)));                              \
         }                                                                                                                                 \
                                                                                                                                           \
         /* 4. Perform ? InstallErrorCause(O, options). */                                                                                 \

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

@@ -76,7 +76,7 @@ ThrowCompletionOr<void> FinalizationRegistry::cleanup(Optional<JobCallback> call
         TRY(vm.host_call_job_callback(global_object, cleanup_callback, js_undefined(), move(arguments)));
     }
 
-    // 4. Return NormalCompletion(empty).
+    // 4. Return unused.
     return {};
 }
 

+ 8 - 8
Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp

@@ -171,7 +171,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
     auto body_string = String::formatted("\n{}\n", body_arg.has_value() ? TRY(body_arg->to_string(global_object)) : "");
 
     // 17. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyString, and "}".
-    // 18. Let sourceText be ! StringToCodePoints(sourceString).
+    // 18. Let sourceText be StringToCodePoints(sourceString).
     auto source_text = String::formatted("{} anonymous({}\n) {{{}}}", prefix, parameters_string, body_string);
 
     u8 parse_options = FunctionNodeParseOptions::CheckForFunctionAndName;
@@ -180,7 +180,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
     if (kind == FunctionKind::Generator || kind == FunctionKind::AsyncGenerator)
         parse_options |= FunctionNodeParseOptions::IsGeneratorFunction;
 
-    // 19. Let parameters be ParseText(! StringToCodePoints(P), parameterSym).
+    // 19. Let parameters be ParseText(StringToCodePoints(P), parameterSym).
     i32 function_length = 0;
     auto parameters_parser = Parser { Lexer { parameters_string } };
     auto parameters = parameters_parser.parse_formal_parameters(function_length, parse_options);
@@ -191,7 +191,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
         return vm.throw_completion<SyntaxError>(global_object, error.to_string());
     }
 
-    // 21. Let body be ParseText(! StringToCodePoints(bodyString), bodySym).
+    // 21. Let body be ParseText(StringToCodePoints(bodyString), bodySym).
     bool contains_direct_call_to_eval = false;
     auto body_parser = Parser { Lexer { body_string } };
     // Set up some parser state to accept things like return await, and yield in the plain function body.
@@ -234,7 +234,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
     // 30. Let privateEnv be null.
     PrivateEnvironment* private_environment = nullptr;
 
-    // 31. Let F be ! OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
+    // 31. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
     auto* function = ECMAScriptFunctionObject::create(global_object, "anonymous", *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), environment, private_environment, expr->kind(), expr->is_strict_mode(), expr->might_need_arguments_object(), contains_direct_call_to_eval);
 
     // FIXME: Remove the name argument from create() and do this instead.
@@ -242,19 +242,19 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
 
     // 33. If kind is generator, then
     if (kind == FunctionKind::Generator) {
-        // a. Let prototype be ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
+        // a. Let prototype be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
         prototype = Object::create(global_object, global_object.generator_prototype());
 
-        // b. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
+        // b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
         function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
     }
     // 34. Else if kind is asyncGenerator, then
     else if (kind == FunctionKind::AsyncGenerator) {
         // FIXME: We only have %AsyncGeneratorFunction.prototype%, not %AsyncGeneratorFunction.prototype.prototype%!
-        // a. Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
+        // a. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
         // prototype = Object::create(global_object, global_object.async_generator_prototype());
 
-        // b. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
+        // b. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
         // function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
     }
     // 35. Else if kind is normal, perform MakeConstructor(F).

+ 6 - 2
Userland/Libraries/LibJS/Runtime/FunctionObject.cpp

@@ -72,8 +72,10 @@ void FunctionObject::set_function_name(Variant<PropertyKey, PrivateName> const&
         }
     }
 
-    // 6. Return ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
+    // 6. Perform ! DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
     MUST(define_property_or_throw(vm.names.name, PropertyDescriptor { .value = js_string(vm, move(name)), .writable = false, .enumerable = false, .configurable = true }));
+
+    // 7. Return unused.
 }
 
 // 10.2.10 SetFunctionLength ( F, length ), https://tc39.es/ecma262/#sec-setfunctionlength
@@ -88,8 +90,10 @@ void FunctionObject::set_function_length(double length)
     VERIFY(m_is_extensible);
     VERIFY(!storage_has(vm.names.length));
 
-    // 2. Return ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
+    // 2. Perform ! DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }).
     MUST(define_property_or_throw(vm.names.length, PropertyDescriptor { .value = Value { length }, .writable = false, .enumerable = false, .configurable = true }));
+
+    // 3. Return unused.
 }
 
 }

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

@@ -144,9 +144,9 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
 
     auto& function = function_value.as_function();
 
-    // 2. If Type(func) is Object and func has a [[SourceText]] internal slot and func.[[SourceText]] is a sequence of Unicode code points and ! HostHasSourceTextAvailable(func) is true, then
+    // 2. If Type(func) is Object and func has a [[SourceText]] internal slot and func.[[SourceText]] is a sequence of Unicode code points and HostHasSourceTextAvailable(func) is true, then
     if (is<ECMAScriptFunctionObject>(function)) {
-        // a. Return ! CodePointsToString(func.[[SourceText]]).
+        // a. Return CodePointsToString(func.[[SourceText]]).
         return js_string(vm, static_cast<ECMAScriptFunctionObject&>(function).source_text());
     }
 

+ 19 - 16
Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -42,7 +42,7 @@ ThrowCompletionOr<Value> GlobalEnvironment::get_this_binding(GlobalObject&) cons
 ThrowCompletionOr<bool> GlobalEnvironment::has_binding(FlyString const& name, Optional<size_t>*) const
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, return true.
+    // 2. If ! DclRec.HasBinding(N) is true, return true.
     if (MUST(m_declarative_record->has_binding(name)))
         return true;
 
@@ -55,7 +55,7 @@ ThrowCompletionOr<bool> GlobalEnvironment::has_binding(FlyString const& name, Op
 ThrowCompletionOr<void> GlobalEnvironment::create_mutable_binding(GlobalObject& global_object, FlyString const& name, bool can_be_deleted)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, throw a TypeError exception.
+    // 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
     if (MUST(m_declarative_record->has_binding(name)))
         return vm().throw_completion<TypeError>(global_object, ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
 
@@ -67,7 +67,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_mutable_binding(GlobalObject&
 ThrowCompletionOr<void> GlobalEnvironment::create_immutable_binding(GlobalObject& global_object, FlyString const& name, bool strict)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, throw a TypeError exception.
+    // 2. If ! DclRec.HasBinding(N) is true, throw a TypeError exception.
     if (MUST(m_declarative_record->has_binding(name)))
         return vm().throw_completion<TypeError>(global_object, ErrorType::GlobalEnvironmentAlreadyHasBinding, name);
 
@@ -79,10 +79,10 @@ ThrowCompletionOr<void> GlobalEnvironment::create_immutable_binding(GlobalObject
 ThrowCompletionOr<void> GlobalEnvironment::initialize_binding(GlobalObject& global_object, FlyString const& name, Value value)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, then
+    // 2. If ! DclRec.HasBinding(N) is true, then
     if (MUST(m_declarative_record->has_binding(name))) {
-        // a. Return DclRec.InitializeBinding(N, V).
-        return m_declarative_record->initialize_binding(global_object, name, value);
+        // a. Return ! DclRec.InitializeBinding(N, V).
+        return MUST(m_declarative_record->initialize_binding(global_object, name, value));
     }
 
     // 3. Assert: If the binding exists, it must be in the object Environment Record.
@@ -95,9 +95,11 @@ ThrowCompletionOr<void> GlobalEnvironment::initialize_binding(GlobalObject& glob
 ThrowCompletionOr<void> GlobalEnvironment::set_mutable_binding(GlobalObject& global_object, FlyString const& name, Value value, bool strict)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, then
+    // 2. If ! DclRec.HasBinding(N) is true, then
     if (MUST(m_declarative_record->has_binding(name))) {
-        // a. Return DclRec.SetMutableBinding(N, V, S).
+        // a. Return ! DclRec.SetMutableBinding(N, V, S).
+        // FIXME: Using MUST here breaks 22 tests in test262 (spec issue).
+        //        Example: `function f() { x = 1; } f(); let x;`
         return m_declarative_record->set_mutable_binding(global_object, name, value, strict);
     }
 
@@ -110,8 +112,9 @@ ThrowCompletionOr<void> GlobalEnvironment::set_mutable_binding(GlobalObject& glo
 ThrowCompletionOr<Value> GlobalEnvironment::get_binding_value(GlobalObject& global_object, FlyString const& name, bool strict)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, then
+    // 2. If ! DclRec.HasBinding(N) is true, then
     if (MUST(m_declarative_record->has_binding(name))) {
+        // FIXME: Should be `! DclRec.GetBindingValue(N, S)` (see https://github.com/tc39/ecma262/pull/2764)
         // a. Return DclRec.GetBindingValue(N, S).
         return m_declarative_record->get_binding_value(global_object, name, strict);
     }
@@ -125,10 +128,10 @@ ThrowCompletionOr<Value> GlobalEnvironment::get_binding_value(GlobalObject& glob
 ThrowCompletionOr<bool> GlobalEnvironment::delete_binding(GlobalObject& global_object, FlyString const& name)
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. If DclRec.HasBinding(N) is true, then
+    // 2. If ! DclRec.HasBinding(N) is true, then
     if (MUST(m_declarative_record->has_binding(name))) {
-        // a. Return DclRec.DeleteBinding(N).
-        return m_declarative_record->delete_binding(global_object, name);
+        // a. Return ! DclRec.DeleteBinding(N).
+        return MUST(m_declarative_record->delete_binding(global_object, name));
     }
 
     // 3. Let ObjRec be envRec.[[ObjectRecord]].
@@ -170,7 +173,7 @@ bool GlobalEnvironment::has_var_declaration(FlyString const& name) const
 bool GlobalEnvironment::has_lexical_declaration(FlyString const& name) const
 {
     // 1. Let DclRec be envRec.[[DeclarativeRecord]].
-    // 2. Return DclRec.HasBinding(N).
+    // 2. Return ! DclRec.HasBinding(N).
     return MUST(m_declarative_record->has_binding(name));
 }
 
@@ -269,7 +272,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_global_var_binding(FlyString c
         m_var_names.append(name);
     }
 
-    // 8. Return NormalCompletion(empty).
+    // 8. Return unused.
     return {};
 }
 
@@ -309,7 +312,7 @@ ThrowCompletionOr<void> GlobalEnvironment::create_global_function_binding(FlyStr
         m_var_names.append(name);
     }
 
-    // 10. Return NormalCompletion(empty).
+    // 10. Return unused.
     return {};
 }
 

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

@@ -521,7 +521,7 @@ static ThrowCompletionOr<String> encode(GlobalObject& global_object, String cons
         }
         // d. Else,
         else {
-            // i. Let cp be ! CodePointAt(string, k).
+            // i. Let cp be CodePointAt(string, k).
             auto code_point = code_point_at(utf16_string.view(), k);
             // ii. If cp.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
             if (code_point.is_unpaired_surrogate)

+ 9 - 9
Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp

@@ -154,10 +154,10 @@ bool is_well_formed_unit_identifier(StringView unit_identifier)
         return true;
     }
 
-    // 2. Let i be ! StringIndexOf(unitIdentifier, "-per-", 0).
+    // 2. Let i be StringIndexOf(unitIdentifier, "-per-", 0).
     auto indices = unit_identifier.find_all("-per-"sv);
 
-    // 3. If i is -1 or ! StringIndexOf(unitIdentifier, "-per-", i + 1) is not -1, then
+    // 3. If i is -1 or StringIndexOf(unitIdentifier, "-per-", i + 1) is not -1, then
     if (indices.size() != 1) {
         // a. Return false.
         return false;
@@ -199,7 +199,7 @@ ThrowCompletionOr<Vector<String>> canonicalize_locale_list(GlobalObject& global_
     Object* object = nullptr;
     // 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, then
     if (locales.is_string() || (locales.is_object() && is<Locale>(locales.as_object()))) {
-        // a. Let O be ! CreateArrayFromList(« locales »).
+        // a. Let O be CreateArrayFromList(« locales »).
         object = Array::create_from(global_object, { locales });
     }
     // 4. Else,
@@ -586,7 +586,7 @@ ThrowCompletionOr<Array*> supported_locales(GlobalObject& global_object, Vector<
         supported_locales = lookup_supported_locales(requested_locales);
     }
 
-    // 5. Return ! CreateArrayFromList(supportedLocales).
+    // 5. Return CreateArrayFromList(supportedLocales).
     return Array::create_from<String>(global_object, supported_locales, [&vm](auto& locale) { return js_string(vm, locale); });
 }
 
@@ -595,7 +595,7 @@ ThrowCompletionOr<Object*> coerce_options_to_object(GlobalObject& global_object,
 {
     // 1. If options is undefined, then
     if (options.is_undefined()) {
-        // a. Return ! OrdinaryObjectCreate(null).
+        // a. Return OrdinaryObjectCreate(null).
         return Object::create(global_object, nullptr);
     }
 
@@ -626,7 +626,7 @@ ThrowCompletionOr<Value> get_option(GlobalObject& global_object, Object const& o
 
     // 5. If type is "boolean", then
     if (type == Value::Type::Boolean) {
-        // a. Set value to ! ToBoolean(value).
+        // a. Set value to ToBoolean(value).
         value = Value(value.to_boolean());
     }
     // 6. If type is "string", then
@@ -685,7 +685,7 @@ Vector<PatternPartition> partition_pattern(StringView pattern)
     // 1. Let result be a new empty List.
     Vector<PatternPartition> result;
 
-    // 2. Let beginIndex be ! StringIndexOf(pattern, "{", 0).
+    // 2. Let beginIndex be StringIndexOf(pattern, "{", 0).
     auto begin_index = pattern.find('{', 0);
 
     // 3. Let endIndex be 0.
@@ -697,7 +697,7 @@ Vector<PatternPartition> partition_pattern(StringView pattern)
     // 5. Let length be the number of code units in pattern.
     // 6. Repeat, while beginIndex is an integer index into pattern,
     while (begin_index.has_value()) {
-        // a. Set endIndex to ! StringIndexOf(pattern, "}", beginIndex).
+        // a. Set endIndex to StringIndexOf(pattern, "}", beginIndex).
         end_index = pattern.find('}', *begin_index).value();
 
         // b. Assert: endIndex is greater than beginIndex.
@@ -721,7 +721,7 @@ Vector<PatternPartition> partition_pattern(StringView pattern)
         // f. Set nextIndex to endIndex + 1.
         next_index = end_index + 1;
 
-        // g. Set beginIndex to ! StringIndexOf(pattern, "{", nextIndex).
+        // g. Set beginIndex to StringIndexOf(pattern, "{", nextIndex).
         begin_index = pattern.find('{', next_index);
     }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/CollatorConstructor.cpp

@@ -89,7 +89,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(GlobalObject& global_obj
 
     // 24. If relevantExtensionKeys contains "kn", then
     if (relevant_extension_keys.span().contains_slow("kn"sv) && result.kn.has_value()) {
-        // a. Set collator.[[Numeric]] to ! SameValue(r.[[kn]], "true").
+        // a. Set collator.[[Numeric]] to SameValue(r.[[kn]], "true").
         collator.set_numeric(same_value(js_string(vm, result.kn.release_value()), js_string(vm, "true"sv)));
     }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp

@@ -59,7 +59,7 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
     auto* collator = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 3, except the header row, in table order, do

+ 6 - 6
Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp

@@ -72,7 +72,7 @@ ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Val
     if (!options_value.is_undefined())
         options = TRY(options_value.to_object(global_object));
 
-    // 2. Let options be ! OrdinaryObjectCreate(options).
+    // 2. Let options be OrdinaryObjectCreate(options).
     options = Object::create(global_object, options);
 
     // 3. Let needDefaults be true.
@@ -524,7 +524,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
         return static_cast<NumberFormat*>(number_format);
     };
 
-    // 4. Let nfOptions be ! OrdinaryObjectCreate(null).
+    // 4. Let nfOptions be OrdinaryObjectCreate(null).
     auto* number_format_options = Object::create(global_object, nullptr);
 
     // 5. Perform ! CreateDataPropertyOrThrow(nfOptions, "useGrouping", false).
@@ -533,7 +533,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
     // 6. Let nf be ? Construct(%NumberFormat%, « locale, nfOptions »).
     auto* number_format = TRY(construct_number_format(number_format_options));
 
-    // 7. Let nf2Options be ! OrdinaryObjectCreate(null).
+    // 7. Let nf2Options be OrdinaryObjectCreate(null).
     auto* number_format_options2 = Object::create(global_object, nullptr);
 
     // 8. Perform ! CreateDataPropertyOrThrow(nf2Options, "minimumIntegerDigits", 2).
@@ -553,7 +553,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec
     if (date_time_format.has_fractional_second_digits()) {
         fractional_second_digits = date_time_format.fractional_second_digits();
 
-        // a. Let nf3Options be ! OrdinaryObjectCreate(null).
+        // a. Let nf3Options be OrdinaryObjectCreate(null).
         auto* number_format_options3 = Object::create(global_object, nullptr);
 
         // b. Perform ! CreateDataPropertyOrThrow(nf3Options, "minimumIntegerDigits", fractionalSecondDigits).
@@ -835,7 +835,7 @@ ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object,
 
     // 4. For each Record { [[Type]], [[Value]] } part in parts, do
     for (auto& part : parts) {
-        // a. Let O be ! OrdinaryObjectCreate(%Object.prototype%).
+        // a. Let O be OrdinaryObjectCreate(%Object.prototype%).
         auto* object = Object::create(global_object, global_object.object_prototype());
 
         // b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
@@ -1155,7 +1155,7 @@ ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_o
 
     // 4. For each Record { [[Type]], [[Value]], [[Source]] } part in parts, do
     for (auto& part : parts) {
-        // a. Let O be ! OrdinaryObjectCreate(%ObjectPrototype%).
+        // a. Let O be OrdinaryObjectCreate(%ObjectPrototype%).
         auto* object = Object::create(global_object, global_object.object_prototype());
 
         // b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp

@@ -146,7 +146,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
     // 3. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
     auto* date_time_format = TRY(typed_this_object(global_object));
 
-    // 4. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 5. For each row of Table 5, except the header row, in table order, do

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp

@@ -128,7 +128,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
     auto* display_names = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 8, except the header row, in table order, do

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -69,7 +69,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::get_canonical_locales)
     for (auto& locale : locale_list)
         marked_locale_list.append(js_string(vm, move(locale)));
 
-    // 2. Return ! CreateArrayFromList(ll).
+    // 2. Return CreateArrayFromList(ll).
     return Array::create_from(global_object, marked_locale_list);
 }
 
@@ -150,7 +150,7 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of)
         return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidKey, key);
     }
 
-    // 9. Return ! CreateArrayFromList( list ).
+    // 9. Return CreateArrayFromList( list ).
     return Array::create_from<StringView>(global_object, list, [&](auto value) { return js_string(vm, value); });
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp

@@ -216,7 +216,7 @@ Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_
 
     // 4. For each Record { [[Type]], [[Value]] } part in parts, do
     for (auto& part : parts) {
-        // a. Let O be ! OrdinaryObjectCreate(%Object.prototype%).
+        // a. Let O be OrdinaryObjectCreate(%Object.prototype%).
         auto* object = Object::create(global_object, global_object.object_prototype());
 
         // b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp

@@ -73,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
     auto* list_format = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 10, except the header row, in table order, do

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp

@@ -349,7 +349,7 @@ ThrowCompletionOr<Object*> LocaleConstructor::construct(FunctionObject& new_targ
 
     // 35. If relevantExtensionKeys contains "kn", then
     if (relevant_extension_keys.span().contains_slow("kn"sv)) {
-        // a. If ! SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
+        // a. If SameValue(r.[[kn]], "true") is true or r.[[kn]] is the empty String, then
         if (result.kn.has_value() && (same_value(js_string(vm, *result.kn), js_string(vm, "true")) || result.kn->is_empty())) {
             // i. Set locale.[[Numeric]] to true.
             locale->set_numeric(true);

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp

@@ -641,7 +641,7 @@ Vector<PatternPartition> partition_notation_sub_pattern(GlobalObject& global_obj
                 // 2. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
                 formatted_string = Unicode::replace_digits_for_number_system(number_format.numbering_system(), formatted_string);
 
-                // 3. Let decimalSepIndex be ! StringIndexOf(n, ".", 0).
+                // 3. Let decimalSepIndex be StringIndexOf(n, ".", 0).
                 auto decimal_sep_index = formatted_string.find('.');
 
                 StringView integer;
@@ -817,7 +817,7 @@ Array* format_numeric_to_parts(GlobalObject& global_object, NumberFormat& number
 
     // 4. For each Record { [[Type]], [[Value]] } part in parts, do
     for (auto& part : parts) {
-        // a. Let O be ! OrdinaryObjectCreate(%Object.prototype%).
+        // a. Let O be OrdinaryObjectCreate(%Object.prototype%).
         auto* object = Object::create(global_object, global_object.object_prototype());
 
         // b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp

@@ -84,7 +84,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
     // 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
     auto* number_format = TRY(typed_this_object(global_object));
 
-    // 4. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 4. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 5. For each row of Table 11, except the header row, in table order, do

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp

@@ -37,7 +37,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
     auto* plural_rules = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 13, except the header row, in table order, do
@@ -61,7 +61,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
     // FIXME: Implement this when the data is available in LibUnicode.
     MarkedVector<Value> plural_categories { vm.heap() };
 
-    // 6. Perform ! CreateDataProperty(options, "pluralCategories", ! CreateArrayFromList(pluralCategories)).
+    // 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
     MUST(options->create_data_property_or_throw(vm.names.pluralCategories, Array::create_from(global_object, plural_categories)));
 
     // 7. Return options.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp

@@ -257,7 +257,7 @@ ThrowCompletionOr<Array*> format_relative_time_to_parts(GlobalObject& global_obj
 
     // 4. For each Record { [[Type]], [[Value]], [[Unit]] } part in parts, do
     for (auto& part : parts) {
-        // a. Let O be ! OrdinaryObjectCreate(%Object.prototype%).
+        // a. Let O be OrdinaryObjectCreate(%Object.prototype%).
         auto* object = Object::create(global_object, global_object.object_prototype());
 
         // b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp

@@ -73,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
     auto* relative_time_format = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 15, except the header row, in table order, do

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp

@@ -14,7 +14,7 @@ namespace JS::Intl {
 SegmentIterator* SegmentIterator::create(GlobalObject& global_object, Segmenter& segmenter, Utf16View const& string, Segments const& segments)
 {
     // 1. Let internalSlotsList be « [[IteratingSegmenter]], [[IteratedString]], [[IteratedStringNextSegmentCodeUnitIndex]] ».
-    // 2. Let iterator be ! OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
+    // 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
     // 3. Set iterator.[[IteratingSegmenter]] to segmenter.
     // 4. Set iterator.[[IteratedString]] to string.
     // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp

@@ -52,7 +52,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
 
     // 7. If endIndex is not finite, then
     if (!Value(end_index).is_finite_number()) {
-        // a. Return ! CreateIterResultObject(undefined, true).
+        // a. Return CreateIterResultObject(undefined, true).
         return create_iterator_result_object(global_object, js_undefined(), true);
     }
 
@@ -62,7 +62,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
     // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex).
     auto* segment_data = create_segment_data_object(global_object, segmenter, string, start_index, end_index);
 
-    // 10. Return ! CreateIterResultObject(segmentData, false).
+    // 10. Return CreateIterResultObject(segmentData, false).
     return create_iterator_result_object(global_object, segment_data, false);
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/Segmenter.cpp

@@ -61,7 +61,7 @@ Object* create_segment_data_object(GlobalObject& global_object, Segmenter const&
     // 4. Assert: startIndex < endIndex.
     VERIFY(start_index < end_index);
 
-    // 5. Let result be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 5. Let result be OrdinaryObjectCreate(%Object.prototype%).
     auto* result = Object::create(global_object, global_object.object_prototype());
 
     // 6. Let segment be the substring of string from startIndex to endIndex.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp

@@ -38,7 +38,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
     // 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]).
     auto* segmenter = TRY(typed_this_object(global_object));
 
-    // 3. Let options be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
     auto* options = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each row of Table 16, except the header row, in table order, do

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp

@@ -14,7 +14,7 @@ namespace JS::Intl {
 Segments* Segments::create(GlobalObject& global_object, Segmenter& segmenter, Utf16String string)
 {
     // 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ».
-    // 2. Let segments be ! OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
+    // 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
     // 3. Set segments.[[SegmentsSegmenter]] to segmenter.
     // 4. Set segments.[[SegmentsString]] to string.
     // 5. Return segments.

+ 11 - 11
Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp

@@ -36,8 +36,8 @@ ThrowCompletionOr<Iterator> get_iterator(GlobalObject& global_object, Value valu
                 // 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
                 auto sync_iterator_record = TRY(get_iterator(global_object, value, IteratorHint::Sync, sync_method));
 
-                // 3. Return ! CreateAsyncFromSyncIterator(syncIteratorRecord).
-                return MUST(create_async_from_sync_iterator(global_object, sync_iterator_record));
+                // 3. Return CreateAsyncFromSyncIterator(syncIteratorRecord).
+                return create_async_from_sync_iterator(global_object, sync_iterator_record);
             }
 
             method = Value(async_method);
@@ -98,7 +98,7 @@ ThrowCompletionOr<bool> iterator_complete(GlobalObject& global_object, Object& i
 {
     auto& vm = global_object.vm();
 
-    // 1. Return ! ToBoolean(? Get(iterResult, "done")).
+    // 1. Return ToBoolean(? Get(iterResult, "done")).
     return TRY(iterator_result.get(vm.names.done)).to_boolean();
 }
 
@@ -140,7 +140,7 @@ static Completion iterator_close_impl(GlobalObject& global_object, Iterator cons
     // 2. Let iterator be iteratorRecord.[[Iterator]].
     auto* iterator = iterator_record.iterator;
 
-    // 3. Let innerResult be GetMethod(iterator, "return").
+    // 3. Let innerResult be Completion(GetMethod(iterator, "return")).
     auto inner_result = ThrowCompletionOr<Value> { js_undefined() };
     auto get_method_result = Value(iterator).get_method(global_object, vm.names.return_);
     if (get_method_result.is_error())
@@ -151,25 +151,25 @@ static Completion iterator_close_impl(GlobalObject& global_object, Iterator cons
         // a. Let return be innerResult.[[Value]].
         auto* return_method = get_method_result.value();
 
-        // b. If return is undefined, return Completion(completion).
+        // b. If return is undefined, return ? completion.
         if (!return_method)
             return completion;
 
-        // c. Set innerResult to Call(return, iterator).
+        // c. Set innerResult to Completion(Call(return, iterator)).
         inner_result = call(global_object, return_method, iterator);
 
         // Note: If this is AsyncIteratorClose perform one extra step.
         if (iterator_hint == IteratorHint::Async && !inner_result.is_error()) {
-            // d. If innerResult.[[Type]] is normal, set innerResult to Await(innerResult.[[Value]]).
+            // d. If innerResult.[[Type]] is normal, set innerResult to Completion(Await(innerResult.[[Value]])).
             inner_result = await(global_object, inner_result.value());
         }
     }
 
-    // 5. If completion.[[Type]] is throw, return Completion(completion).
+    // 5. If completion.[[Type]] is throw, return ? completion.
     if (completion.is_error())
         return completion;
 
-    // 6. If innerResult.[[Type]] is throw, return Completion(innerResult).
+    // 6. If innerResult.[[Type]] is throw, return ? innerResult.
     if (inner_result.is_throw_completion())
         return inner_result;
 
@@ -177,7 +177,7 @@ static Completion iterator_close_impl(GlobalObject& global_object, Iterator cons
     if (!inner_result.value().is_object())
         return vm.throw_completion<TypeError>(global_object, ErrorType::IterableReturnBadReturn);
 
-    // 8. Return Completion(completion).
+    // 8. Return ? completion.
     return completion;
 }
 
@@ -198,7 +198,7 @@ Object* create_iterator_result_object(GlobalObject& global_object, Value value,
 {
     auto& vm = global_object.vm();
 
-    // 1. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 1. Let obj be OrdinaryObjectCreate(%Object.prototype%).
     auto* object = Object::create(global_object, global_object.object_prototype());
 
     // 2. Perform ! CreateDataPropertyOrThrow(obj, "value", value).

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

@@ -87,7 +87,7 @@ ThrowCompletionOr<void> ModuleEnvironment::create_import_binding(FlyString name,
         module,
         move(binding_name) });
 
-    // 4. Return NormalCompletion(empty).
+    // 4. Return unused.
     return {};
 }
 

+ 12 - 12
Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp

@@ -40,8 +40,8 @@ ThrowCompletionOr<Object*> ModuleNamespaceObject::internal_get_prototype_of() co
 // 10.4.6.2 [[SetPrototypeOf]] ( V ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-setprototypeof-v
 ThrowCompletionOr<bool> ModuleNamespaceObject::internal_set_prototype_of(Object* prototype)
 {
-    // 1. Return ? SetImmutablePrototype(O, V).
-    return set_immutable_prototype(prototype);
+    // 1. Return ! SetImmutablePrototype(O, V).
+    return MUST(set_immutable_prototype(prototype));
 }
 
 // 10.4.6.3 [[IsExtensible]] ( ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-isextensible
@@ -81,9 +81,9 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ModuleNamespaceObject::internal_
 // 10.4.6.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-defineownproperty-p-desc
 ThrowCompletionOr<bool> ModuleNamespaceObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor)
 {
-    // 1. If Type(P) is Symbol, return OrdinaryDefineOwnProperty(O, P, Desc).
+    // 1. If Type(P) is Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc).
     if (property_key.is_symbol())
-        return Object::internal_define_own_property(property_key, descriptor);
+        return MUST(Object::internal_define_own_property(property_key, descriptor));
 
     // 2. Let current be ? O.[[GetOwnProperty]](P).
     auto current = TRY(internal_get_own_property(property_key));
@@ -100,7 +100,7 @@ ThrowCompletionOr<bool> ModuleNamespaceObject::internal_define_own_property(Prop
     if (descriptor.enumerable.has_value() && !descriptor.enumerable.value())
         return false;
 
-    // 6. If ! IsAccessorDescriptor(Desc) is true, return false.
+    // 6. If IsAccessorDescriptor(Desc) is true, return false.
     if (descriptor.is_accessor_descriptor())
         return false;
 
@@ -119,9 +119,9 @@ ThrowCompletionOr<bool> ModuleNamespaceObject::internal_define_own_property(Prop
 // 10.4.6.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-hasproperty-p
 ThrowCompletionOr<bool> ModuleNamespaceObject::internal_has_property(PropertyKey const& property_key) const
 {
-    // 1. If Type(P) is Symbol, return OrdinaryHasProperty(O, P).
+    // 1. If Type(P) is Symbol, return ! OrdinaryHasProperty(O, P).
     if (property_key.is_symbol())
-        return Object::internal_has_property(property_key);
+        return MUST(Object::internal_has_property(property_key));
 
     // 2. Let exports be O.[[Exports]].
     // 3. If P is an element of exports, return true.
@@ -138,8 +138,8 @@ ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const&
 {
     // 1. If Type(P) is Symbol, then
     if (property_key.is_symbol()) {
-        // a. Return ? OrdinaryGet(O, P, Receiver).
-        return Object::internal_get(property_key, receiver);
+        // a. Return ! OrdinaryGet(O, P, Receiver).
+        return MUST(Object::internal_get(property_key, receiver));
     }
 
     // 2. Let exports be O.[[Exports]].
@@ -190,8 +190,8 @@ ThrowCompletionOr<bool> ModuleNamespaceObject::internal_delete(PropertyKey const
 {
     // 1. If Type(P) is Symbol, then
     if (property_key.is_symbol()) {
-        // a. Return ? OrdinaryDelete(O, P).
-        return Object::internal_delete(property_key);
+        // a. Return ! OrdinaryDelete(O, P).
+        return MUST(Object::internal_delete(property_key));
     }
 
     // 2. Let exports be O.[[Exports]].
@@ -209,7 +209,7 @@ ThrowCompletionOr<MarkedVector<Value>> ModuleNamespaceObject::internal_own_prope
 {
     // 1. Let exports be O.[[Exports]].
 
-    // 2. Let symbolKeys be ! OrdinaryOwnPropertyKeys(O).
+    // 2. Let symbolKeys be OrdinaryOwnPropertyKeys(O).
     auto symbol_keys = MUST(Object::internal_own_property_keys());
 
     // 3. Return the list-concatenation of exports and symbolKeys.

+ 5 - 5
Userland/Libraries/LibJS/Runtime/NativeFunction.cpp

@@ -38,13 +38,13 @@ NativeFunction* NativeFunction::create(GlobalObject& global_object, Function<Thr
     // 9. Set func.[[InitialName]] to null.
     auto* function = global_object.heap().allocate<NativeFunction>(global_object, global_object, move(behaviour), prototype.value(), *realm.value());
 
-    // 10. Perform ! SetFunctionLength(func, length).
+    // 10. Perform SetFunctionLength(func, length).
     function->set_function_length(length);
 
     // 11. If prefix is not present, then
-    //     a. Perform ! SetFunctionName(func, name).
+    //     a. Perform SetFunctionName(func, name).
     // 12. Else,
-    //     a. Perform ! SetFunctionName(func, name, prefix).
+    //     a. Perform SetFunctionName(func, name, prefix).
     function->set_function_name(name, prefix);
 
     // 13. Return func.
@@ -156,7 +156,7 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Mark
     // 11. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
     vm.pop_execution_context();
 
-    // 12. Return result.
+    // 12. Return ? result.
     return result;
 }
 
@@ -220,7 +220,7 @@ ThrowCompletionOr<Object*> NativeFunction::internal_construct(MarkedVector<Value
     // 11. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
     vm.pop_execution_context();
 
-    // 12. Return result.
+    // 12. Return ? result.
     return result;
 }
 

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

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2022, the SerenityOS developers.
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -136,7 +136,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_exponential)
     // 3. Assert: If fractionDigits is undefined, then f is 0.
     VERIFY(!fraction_digits_value.is_undefined() || (fraction_digits == 0));
 
-    // 4. If x is not finite, return ! Number::toString(x).
+    // 4. If x is not finite, return Number::toString(x).
     if (!number_value.is_finite_number())
         return js_string(vm, MUST(number_value.to_string(global_object)));
 
@@ -261,7 +261,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_fixed)
     if (fraction_digits < 0 || fraction_digits > 100)
         return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidFractionDigits);
 
-    // 6. If x is not finite, return ! Number::toString(x).
+    // 6. If x is not finite, return Number::toString(x).
     if (!number_value.is_finite_number())
         return js_string(vm, TRY(number_value.to_string(global_object)));
 
@@ -350,7 +350,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_precision)
     // 3. Let p be ? ToIntegerOrInfinity(precision).
     auto precision = TRY(precision_value.to_integer_or_infinity(global_object));
 
-    // 4. If x is not finite, return ! Number::toString(x).
+    // 4. If x is not finite, return Number::toString(x).
     if (!number_value.is_finite_number())
         return js_string(vm, MUST(number_value.to_string(global_object)));
 

+ 31 - 22
Userland/Libraries/LibJS/Runtime/Object.cpp

@@ -91,7 +91,7 @@ ThrowCompletionOr<Value> Object::get(PropertyKey const& property_key) const
 // NOTE: 7.3.3 GetV ( V, P ) is implemented as Value::get().
 
 // 7.3.4 Set ( O, P, V, Throw ), https://tc39.es/ecma262/#sec-set-o-p-v-throw
-ThrowCompletionOr<bool> Object::set(PropertyKey const& property_key, Value value, ShouldThrowExceptions throw_exceptions)
+ThrowCompletionOr<void> Object::set(PropertyKey const& property_key, Value value, ShouldThrowExceptions throw_exceptions)
 {
     auto& vm = this->vm();
 
@@ -107,8 +107,8 @@ ThrowCompletionOr<bool> Object::set(PropertyKey const& property_key, Value value
         return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectSetReturnedFalse);
     }
 
-    // 3. Return success.
-    return success;
+    // 3. Return unused.
+    return {};
 }
 
 // 7.3.5 CreateDataProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createdataproperty
@@ -129,12 +129,14 @@ ThrowCompletionOr<bool> Object::create_data_property(PropertyKey const& property
 }
 
 // 7.3.6 CreateMethodProperty ( O, P, V ), https://tc39.es/ecma262/#sec-createmethodproperty
-ThrowCompletionOr<bool> Object::create_method_property(PropertyKey const& property_key, Value value)
+ThrowCompletionOr<void> Object::create_method_property(PropertyKey const& property_key, Value value)
 {
     VERIFY(property_key.is_valid());
     VERIFY(!value.is_empty());
 
-    // 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
+    // 1. Assert: O is an ordinary, extensible object with no non-configurable properties.
+
+    // 2. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
     auto new_descriptor = PropertyDescriptor {
         .value = value,
         .writable = true,
@@ -142,8 +144,11 @@ ThrowCompletionOr<bool> Object::create_method_property(PropertyKey const& proper
         .configurable = true,
     };
 
-    // 2. Return ? O.[[DefineOwnProperty]](P, newDesc).
-    return internal_define_own_property(property_key, new_descriptor);
+    // 3. Perform ! O.[[DefineOwnProperty]](P, newDesc).
+    MUST(internal_define_own_property(property_key, new_descriptor));
+
+    // 4. Return unused.
+    return {};
 }
 
 // 7.3.7 CreateDataPropertyOrThrow ( O, P, V ), https://tc39.es/ecma262/#sec-createdatapropertyorthrow
@@ -168,20 +173,24 @@ ThrowCompletionOr<bool> Object::create_data_property_or_throw(PropertyKey const&
 }
 
 // 7.3.8 CreateNonEnumerableDataPropertyOrThrow ( O, P, V ), https://tc39.es/ecma262/#sec-createnonenumerabledatapropertyorthrow
-ThrowCompletionOr<bool> Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_key, Value value)
+void Object::create_non_enumerable_data_property_or_throw(PropertyKey const& property_key, Value value)
 {
     VERIFY(property_key.is_valid());
     VERIFY(!value.is_empty());
 
-    // 1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
+    // 1. Assert: O is an ordinary, extensible object with no non-configurable properties.
+
+    // 2. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
     auto new_description = PropertyDescriptor { .value = value, .writable = true, .enumerable = false, .configurable = true };
 
-    // 2. Return ? DefinePropertyOrThrow(O, P, newDesc).
-    return define_property_or_throw(property_key, new_description);
+    // 3. Perform ! DefinePropertyOrThrow(O, P, newDesc).
+    MUST(define_property_or_throw(property_key, new_description));
+
+    // 4. Return unused.
 }
 
 // 7.3.9 DefinePropertyOrThrow ( O, P, desc ), https://tc39.es/ecma262/#sec-definepropertyorthrow
-ThrowCompletionOr<bool> Object::define_property_or_throw(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
+ThrowCompletionOr<void> Object::define_property_or_throw(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor)
 {
     auto& vm = this->vm();
 
@@ -196,12 +205,12 @@ ThrowCompletionOr<bool> Object::define_property_or_throw(PropertyKey const& prop
         return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectDefineOwnPropertyReturnedFalse);
     }
 
-    // 3. Return success.
-    return success;
+    // 3. Return unused.
+    return {};
 }
 
 // 7.3.10 DeletePropertyOrThrow ( O, P ), https://tc39.es/ecma262/#sec-deletepropertyorthrow
-ThrowCompletionOr<bool> Object::delete_property_or_throw(PropertyKey const& property_key)
+ThrowCompletionOr<void> Object::delete_property_or_throw(PropertyKey const& property_key)
 {
     auto& vm = this->vm();
 
@@ -216,8 +225,8 @@ ThrowCompletionOr<bool> Object::delete_property_or_throw(PropertyKey const& prop
         return vm.throw_completion<TypeError>(global_object(), ErrorType::ObjectDeleteReturnedFalse);
     }
 
-    // 3. Return success.
-    return success;
+    // 3. Return unused.
+    return {};
 }
 
 // 7.3.12 HasProperty ( O, P ), https://tc39.es/ecma262/#sec-hasproperty
@@ -393,7 +402,7 @@ ThrowCompletionOr<MarkedVector<Value>> Object::enumerable_own_property_names(Pro
             // i. Assert: kind is key+value.
             VERIFY(kind == PropertyKind::KeyAndValue);
 
-            // ii. Let entry be ! CreateArrayFromList(« key, value »).
+            // ii. Let entry be CreateArrayFromList(« key, value »).
             auto entry = Array::create_from(global_object, { key, value });
 
             // iii. Append entry to properties.
@@ -406,10 +415,10 @@ ThrowCompletionOr<MarkedVector<Value>> Object::enumerable_own_property_names(Pro
 }
 
 // 7.3.26 CopyDataProperties ( target, source, excludedItems ), https://tc39.es/ecma262/#sec-copydataproperties
-ThrowCompletionOr<Object*> Object::copy_data_properties(Value source, HashTable<PropertyKey> const& seen_names, GlobalObject& global_object)
+ThrowCompletionOr<void> Object::copy_data_properties(Value source, HashTable<PropertyKey> const& seen_names, GlobalObject& global_object)
 {
     if (source.is_nullish())
-        return this;
+        return {};
 
     auto* from_object = MUST(source.to_object(global_object));
 
@@ -425,7 +434,7 @@ ThrowCompletionOr<Object*> Object::copy_data_properties(Value source, HashTable<
             TRY(create_data_property_or_throw(next_key, prop_value));
         }
     }
-    return this;
+    return {};
 }
 
 // 7.3.27 PrivateElementFind ( O, P ), https://tc39.es/ecma262/#sec-privateelementfind
@@ -753,7 +762,7 @@ ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Va
     // 2. Let ownDesc be ? O.[[GetOwnProperty]](P).
     auto own_descriptor = TRY(internal_get_own_property(property_key));
 
-    // 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
+    // 3. Return ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
     return ordinary_set_with_own_descriptor(property_key, value, receiver, own_descriptor);
 }
 

+ 13 - 10
Userland/Libraries/LibJS/Runtime/Object.h

@@ -25,10 +25,13 @@
 
 namespace JS {
 
-#define JS_OBJECT(class_, base_class) \
-public:                               \
-    using Base = base_class;          \
-    virtual StringView class_name() const override { return #class_; }
+#define JS_OBJECT(class_, base_class)              \
+public:                                            \
+    using Base = base_class;                       \
+    virtual StringView class_name() const override \
+    {                                              \
+        return #class_;                            \
+    }
 
 struct PrivateElement {
     enum class Kind {
@@ -91,19 +94,19 @@ public:
     // 7.3 Operations on Objects, https://tc39.es/ecma262/#sec-operations-on-objects
 
     ThrowCompletionOr<Value> get(PropertyKey const&) const;
-    ThrowCompletionOr<bool> set(PropertyKey const&, Value, ShouldThrowExceptions);
+    ThrowCompletionOr<void> set(PropertyKey const&, Value, ShouldThrowExceptions);
     ThrowCompletionOr<bool> create_data_property(PropertyKey const&, Value);
-    ThrowCompletionOr<bool> create_method_property(PropertyKey const&, Value);
+    ThrowCompletionOr<void> create_method_property(PropertyKey const&, Value);
     ThrowCompletionOr<bool> create_data_property_or_throw(PropertyKey const&, Value);
-    ThrowCompletionOr<bool> create_non_enumerable_data_property_or_throw(PropertyKey const&, Value);
-    ThrowCompletionOr<bool> define_property_or_throw(PropertyKey const&, PropertyDescriptor const&);
-    ThrowCompletionOr<bool> delete_property_or_throw(PropertyKey const&);
+    void create_non_enumerable_data_property_or_throw(PropertyKey const&, Value);
+    ThrowCompletionOr<void> define_property_or_throw(PropertyKey const&, PropertyDescriptor const&);
+    ThrowCompletionOr<void> delete_property_or_throw(PropertyKey const&);
     ThrowCompletionOr<bool> has_property(PropertyKey const&) const;
     ThrowCompletionOr<bool> has_own_property(PropertyKey const&) const;
     ThrowCompletionOr<bool> set_integrity_level(IntegrityLevel);
     ThrowCompletionOr<bool> test_integrity_level(IntegrityLevel) const;
     ThrowCompletionOr<MarkedVector<Value>> enumerable_own_property_names(PropertyKind kind) const;
-    ThrowCompletionOr<Object*> copy_data_properties(Value source, HashTable<PropertyKey> const& seen_names, GlobalObject& global_object);
+    ThrowCompletionOr<void> copy_data_properties(Value source, HashTable<PropertyKey> const& seen_names, GlobalObject& global_object);
 
     PrivateElement* private_element_find(PrivateName const& name);
     ThrowCompletionOr<void> private_field_add(PrivateName const& name, Value value);

+ 11 - 11
Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -83,7 +83,7 @@ enum class GetOwnPropertyKeysType {
 };
 
 // 20.1.2.11.1 GetOwnPropertyKeys ( O, type ), https://tc39.es/ecma262/#sec-getownpropertykeys
-static ThrowCompletionOr<Array*> get_own_property_keys(GlobalObject& global_object, Value value, GetOwnPropertyKeysType type)
+static ThrowCompletionOr<MarkedVector<Value>> get_own_property_keys(GlobalObject& global_object, Value value, GetOwnPropertyKeysType type)
 {
     auto& vm = global_object.vm();
 
@@ -105,22 +105,22 @@ static ThrowCompletionOr<Array*> get_own_property_keys(GlobalObject& global_obje
         }
     }
 
-    // 5. Return CreateArrayFromList(nameList).
-    return Array::create_from(global_object, name_list);
+    // 5. Return nameList.
+    return { move(name_list) };
 }
 
 // 20.1.2.10 Object.getOwnPropertyNames ( O ), https://tc39.es/ecma262/#sec-object.getownpropertynames
 JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
 {
-    // 1. Return ? GetOwnPropertyKeys(O, string).
-    return TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::String));
+    // 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).
+    return Array::create_from(global_object, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::String)));
 }
 
 // 20.1.2.11 Object.getOwnPropertySymbols ( O ), https://tc39.es/ecma262/#sec-object.getownpropertysymbols
 JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_symbols)
 {
-    // 1. Return ? GetOwnPropertyKeys(O, symbol).
-    return TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::Symbol));
+    // 1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).
+    return Array::create_from(global_object, TRY(get_own_property_keys(global_object, vm.argument(0), GetOwnPropertyKeysType::Symbol)));
 }
 
 // 20.1.2.12 Object.getPrototypeOf ( O ), https://tc39.es/ecma262/#sec-object.getprototypeof
@@ -268,7 +268,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
     // 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
     auto own_keys = TRY(object->internal_own_property_keys());
 
-    // 3. Let descriptors be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
     auto* descriptors = Object::create(global_object, global_object.object_prototype());
 
     // 4. For each element key of ownKeys, do
@@ -278,7 +278,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors)
         // a. Let desc be ? obj.[[GetOwnProperty]](key).
         auto desc = TRY(object->internal_get_own_property(property_key));
 
-        // b. Let descriptor be ! FromPropertyDescriptor(desc).
+        // b. Let descriptor be FromPropertyDescriptor(desc).
         auto descriptor = from_property_descriptor(global_object, desc);
 
         // c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
@@ -355,7 +355,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::create)
     if (!proto.is_object() && !proto.is_null())
         return vm.throw_completion<TypeError>(global_object, ErrorType::ObjectPrototypeWrongType);
 
-    // 2. Let obj be ! OrdinaryObjectCreate(O).
+    // 2. Let obj be OrdinaryObjectCreate(O).
     auto* object = Object::create(global_object, proto.is_null() ? nullptr : &proto.as_object());
 
     // 3. If Properties is not undefined, then

+ 14 - 7
Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -47,7 +47,7 @@ ThrowCompletionOr<bool> ObjectEnvironment::has_binding(FlyString const& name, Op
 
     // 6. If Type(unscopables) is Object, then
     if (unscopables.is_object()) {
-        // a. Let blocked be ! ToBoolean(? Get(unscopables, N)).
+        // a. Let blocked be ToBoolean(? Get(unscopables, N)).
         auto blocked = TRY(unscopables.as_object().get(name)).to_boolean();
 
         // b. If blocked is true, return false.
@@ -63,8 +63,10 @@ ThrowCompletionOr<bool> ObjectEnvironment::has_binding(FlyString const& name, Op
 ThrowCompletionOr<void> ObjectEnvironment::create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted)
 {
     // 1. Let bindingObject be envRec.[[BindingObject]].
-    // 2. Return ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
+    // 2. Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
     TRY(m_binding_object.define_property_or_throw(name, { .value = js_undefined(), .writable = true, .enumerable = true, .configurable = can_be_deleted }));
+
+    // 3. Return unused.
     return {};
 }
 
@@ -78,8 +80,11 @@ ThrowCompletionOr<void> ObjectEnvironment::create_immutable_binding(GlobalObject
 // 9.1.1.2.4 InitializeBinding ( N, V ), https://tc39.es/ecma262/#sec-object-environment-records-initializebinding-n-v
 ThrowCompletionOr<void> ObjectEnvironment::initialize_binding(GlobalObject& global_object, FlyString const& name, Value value)
 {
-    // 1. Return ? envRec.SetMutableBinding(N, V, false).
-    return set_mutable_binding(global_object, name, value, false);
+    // 1. Perform ? envRec.SetMutableBinding(N, V, false).
+    TRY(set_mutable_binding(global_object, name, value, false));
+
+    // 2. Return unused.
+    return {};
 }
 
 // 9.1.1.2.5 SetMutableBinding ( N, V, S ), https://tc39.es/ecma262/#sec-object-environment-records-setmutablebinding-n-v-s
@@ -95,7 +100,7 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& glo
     if (!still_exists && strict)
         return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);
 
-    // 4. Return ? Set(bindingObject, N, V, S).
+    // 4. Perform ? Set(bindingObject, N, V, S).
     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().
@@ -112,6 +117,8 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(GlobalObject& glo
 
     if (result_or_error.is_error())
         return result_or_error.release_error();
+
+    // 5. Return unused.
     return {};
 }
 
@@ -126,7 +133,7 @@ ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(GlobalObject& glob
 
     // 3. If value is false, then
     if (!value) {
-        // a. If S is false, return the value undefined; otherwise throw a ReferenceError exception.
+        // a. If S is false, return undefined; otherwise throw a ReferenceError exception.
         if (!strict)
             return js_undefined();
         return vm.throw_completion<ReferenceError>(global_object, ErrorType::UnknownIdentifier, name);

+ 38 - 21
Userland/Libraries/LibJS/Runtime/Promise.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -65,7 +65,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
 
     // 2. Let stepsResolve be the algorithm steps defined in Promise Resolve Functions.
     // 3. Let lengthResolve be the number of non-optional parameters of the function definition in Promise Resolve Functions.
-    // 4. Let resolve be ! CreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »).
+    // 4. Let resolve be CreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »).
     // 5. Set resolve.[[Promise]] to promise.
     // 6. Set resolve.[[AlreadyResolved]] to alreadyResolved.
 
@@ -96,25 +96,34 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
             // a. Let selfResolutionError be a newly created TypeError object.
             auto* self_resolution_error = TypeError::create(global_object, "Cannot resolve promise with itself");
 
-            // b. Return RejectPromise(promise, selfResolutionError).
-            return promise.reject(self_resolution_error);
+            // b. Perform RejectPromise(promise, selfResolutionError).
+            promise.reject(self_resolution_error);
+
+            // c. Return undefined.
+            return js_undefined();
         }
 
         // 8. If Type(resolution) is not Object, then
         if (!resolution.is_object()) {
-            // a. Return FulfillPromise(promise, resolution).
+            // a. Perform FulfillPromise(promise, resolution).
             dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Resolution is not an object, fulfilling with {}", &promise, resolution);
-            return promise.fulfill(resolution);
+            promise.fulfill(resolution);
+
+            // b. Return undefined.
+            return js_undefined();
         }
 
-        // 9. Let then be Get(resolution, "then").
+        // 9. Let then be Completion(Get(resolution, "then")).
         auto then = resolution.as_object().get(vm.names.then);
 
         // 10. If then is an abrupt completion, then
         if (then.is_throw_completion()) {
-            // a. Return RejectPromise(promise, then.[[Value]]).
+            // a. Perform RejectPromise(promise, then.[[Value]]).
             dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Exception while getting 'then' property, rejecting with error", &promise);
-            return promise.reject(*then.throw_completion().value());
+            promise.reject(*then.throw_completion().value());
+
+            // b. Return undefined.
+            return js_undefined();
         }
 
         // 11. Let thenAction be then.[[Value]].
@@ -122,9 +131,12 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
 
         // 12. If IsCallable(thenAction) is false, then
         if (!then_action.is_function()) {
-            // a. Return FulfillPromise(promise, resolution).
+            // a. Perform FulfillPromise(promise, resolution).
             dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Then action is not a function, fulfilling with {}", &promise, resolution);
-            return promise.fulfill(resolution);
+            promise.fulfill(resolution);
+
+            // b. Return undefined.
+            return js_undefined();
         }
 
         // 13. Let thenJobCallback be HostMakeJobCallback(thenAction).
@@ -146,7 +158,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
 
     // 7. Let stepsReject be the algorithm steps defined in Promise Reject Functions.
     // 8. Let lengthReject be the number of non-optional parameters of the function definition in Promise Reject Functions.
-    // 9. Let reject be ! CreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »).
+    // 9. Let reject be CreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »).
     // 10. Set reject.[[Promise]] to promise.
     // 11. Set reject.[[AlreadyResolved]] to alreadyResolved.
 
@@ -168,8 +180,11 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
         // 6. Set alreadyResolved.[[Value]] to true.
         already_resolved.value = true;
 
-        // 7. Return RejectPromise(promise, reason).
-        return promise.reject(reason);
+        // 7. Perform RejectPromise(promise, reason).
+        promise.reject(reason);
+
+        // 8. Return undefined.
+        return js_undefined();
     });
     reject_function->define_direct_property(vm.names.name, js_string(vm, String::empty()), Attribute::Configurable);
 
@@ -178,7 +193,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
 }
 
 // 27.2.1.4 FulfillPromise ( promise, value ), https://tc39.es/ecma262/#sec-fulfillpromise
-Value Promise::fulfill(Value value)
+void Promise::fulfill(Value value)
 {
     dbgln_if(PROMISE_DEBUG, "[Promise @ {} / fulfill()]: Fulfilling promise with value {}", this, value);
 
@@ -198,15 +213,16 @@ Value Promise::fulfill(Value value)
     // 6. Set promise.[[PromiseState]] to fulfilled.
     m_state = State::Fulfilled;
 
-    // 7. Return TriggerPromiseReactions(reactions, value).
+    // 7. Perform TriggerPromiseReactions(reactions, value).
     trigger_reactions();
     m_fulfill_reactions.clear();
     m_reject_reactions.clear();
-    return js_undefined();
+
+    // 8. Return unused.
 }
 
 // 27.2.1.7 RejectPromise ( promise, reason ), https://tc39.es/ecma262/#sec-rejectpromise
-Value Promise::reject(Value reason)
+void Promise::reject(Value reason)
 {
 
     dbgln_if(PROMISE_DEBUG, "[Promise @ {} / reject()]: Rejecting promise with reason {}", this, reason);
@@ -232,11 +248,12 @@ Value Promise::reject(Value reason)
     if (!m_is_handled)
         vm.host_promise_rejection_tracker(*this, RejectionOperation::Reject);
 
-    // 8. Return TriggerPromiseReactions(reactions, reason).
+    // 8. Perform TriggerPromiseReactions(reactions, reason).
     trigger_reactions();
     m_fulfill_reactions.clear();
     m_reject_reactions.clear();
-    return js_undefined();
+
+    // 9. Return unused.
 }
 
 // 27.2.1.8 TriggerPromiseReactions ( reactions, argument ), https://tc39.es/ecma262/#sec-triggerpromisereactions
@@ -264,7 +281,7 @@ void Promise::trigger_reactions() const
             dbgln("[Promise @ {} / trigger_reactions()]: No reactions!", this);
     }
 
-    // 2. Return undefined.
+    // 2. Return unused.
 }
 
 // 27.2.5.4.1 PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] ), https://tc39.es/ecma262/#sec-performpromisethen

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Promise.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -41,8 +41,8 @@ public:
     };
     ResolvingFunctions create_resolving_functions();
 
-    Value fulfill(Value value);
-    Value reject(Value reason);
+    void fulfill(Value value);
+    void reject(Value reason);
     Value perform_then(Value on_fulfilled, Value on_rejected, Optional<PromiseCapability> result_capability);
 
     bool is_handled() const { return m_is_handled; }

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

@@ -58,7 +58,7 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
 
     // 4. Repeat,
     while (true) {
-        // a. Let next be IteratorStep(iteratorRecord).
+        // a. Let next be Completion(IteratorStep(iteratorRecord)).
         auto next_or_error = iterator_step(global_object, iterator_record);
 
         // b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -85,7 +85,7 @@ static ThrowCompletionOr<Value> perform_promise_common(GlobalObject& global_obje
             return result_capability.promise;
         }
 
-        // e. Let nextValue be IteratorValue(next).
+        // e. Let nextValue be Completion(IteratorValue(next)).
         auto next_value_or_error = iterator_value(global_object, *next);
 
         // f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -123,7 +123,7 @@ static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object,
     return perform_promise_common(
         global_object, iterator_record, constructor, result_capability, promise_resolve,
         [&](PromiseValueList& values) -> ThrowCompletionOr<Value> {
-            // 1. Let valuesArray be ! CreateArrayFromList(values).
+            // 1. Let valuesArray be CreateArrayFromList(values).
             auto* values_array = Array::create_from(global_object, values.values());
 
             // 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
@@ -135,7 +135,7 @@ static ThrowCompletionOr<Value> perform_promise_all(GlobalObject& global_object,
         [&](PromiseValueList& values, RemainingElements& remaining_elements_count, Value next_promise, size_t index) {
             // j. Let steps be the algorithm steps defined in Promise.all Resolve Element Functions.
             // k. Let length be the number of non-optional parameters of the function definition in Promise.all Resolve Element Functions.
-            // l. Let onFulfilled be ! CreateBuiltinFunction(steps, length, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+            // l. Let onFulfilled be CreateBuiltinFunction(steps, length, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
             // m. Set onFulfilled.[[AlreadyCalled]] to false.
             // n. Set onFulfilled.[[Index]] to index.
             // o. Set onFulfilled.[[Values]] to values.
@@ -166,7 +166,7 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
         [&](PromiseValueList& values, RemainingElements& remaining_elements_count, Value next_promise, size_t index) {
             // j. Let stepsFulfilled be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
             // k. Let lengthFulfilled be the number of non-optional parameters of the function definition in Promise.allSettled Resolve Element Functions.
-            // l. Let onFulfilled be ! CreateBuiltinFunction(stepsFulfilled, lengthFulfilled, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+            // l. Let onFulfilled be CreateBuiltinFunction(stepsFulfilled, lengthFulfilled, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
             // m. Let alreadyCalled be the Record { [[Value]]: false }.
             // n. Set onFulfilled.[[AlreadyCalled]] to alreadyCalled.
             // o. Set onFulfilled.[[Index]] to index.
@@ -178,7 +178,7 @@ static ThrowCompletionOr<Value> perform_promise_all_settled(GlobalObject& global
 
             // s. Let stepsRejected be the algorithm steps defined in Promise.allSettled Reject Element Functions.
             // t. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.allSettled Reject Element Functions.
-            // u. Let onRejected be ! CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+            // u. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
             // v. Set onRejected.[[AlreadyCalled]] to alreadyCalled.
             // w. Set onRejected.[[Index]] to index.
             // x. Set onRejected.[[Values]] to values.
@@ -203,7 +203,7 @@ static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object,
             // 1. Let error be a newly created AggregateError object.
             auto* error = AggregateError::create(global_object);
 
-            // 2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: ! CreateArrayFromList(errors) }).
+            // 2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
             auto* errors_array = Array::create_from(global_object, errors.values());
             MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
 
@@ -213,7 +213,7 @@ static ThrowCompletionOr<Value> perform_promise_any(GlobalObject& global_object,
         [&](PromiseValueList& errors, RemainingElements& remaining_elements_count, Value next_promise, size_t index) {
             // j. Let stepsRejected be the algorithm steps defined in Promise.any Reject Element Functions.
             // k. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.any Reject Element Functions.
-            // l. Let onRejected be ! CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
+            // l. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
             // m. Set onRejected.[[AlreadyCalled]] to false.
             // n. Set onRejected.[[Index]] to index.
             // o. Set onRejected.[[Errors]] to errors.
@@ -301,7 +301,7 @@ ThrowCompletionOr<Object*> PromiseConstructor::construct(FunctionObject& new_tar
     // 8. Let resolvingFunctions be CreateResolvingFunctions(promise).
     auto [resolve_function, reject_function] = promise->create_resolving_functions();
 
-    // 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
+    // 9. Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
     auto completion = JS::call(global_object, executor.as_function(), js_undefined(), &resolve_function, &reject_function);
 
     // 10. If completion is an abrupt completion, then
@@ -323,20 +323,20 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
     auto promise_capability = TRY(new_promise_capability(global_object, constructor));
 
-    // 3. Let promiseResolve be GetPromiseResolve(C).
+    // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
     auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
 
-    // 5. Let iteratorRecord be GetIterator(iterable).
+    // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
     auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0)));
 
-    // 7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve).
+    // 7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
     auto result = perform_promise_all(global_object, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
-        // a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+        // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
         if (!iterator_record.done)
             result = iterator_close(global_object, iterator_record, result.release_error());
 
@@ -344,8 +344,8 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all)
         TRY_OR_REJECT(global_object, promise_capability, result);
     }
 
-    // 9. Return Completion(result).
-    return result.release_value();
+    // 9. Return ? result.
+    return result;
 }
 
 // 27.2.4.2 Promise.allSettled ( iterable ), https://tc39.es/ecma262/#sec-promise.allsettled
@@ -357,20 +357,20 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
     auto promise_capability = TRY(new_promise_capability(global_object, constructor));
 
-    // 3. Let promiseResolve be GetPromiseResolve(C).
+    // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
     auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
 
-    // 5. Let iteratorRecord be GetIterator(iterable).
+    // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
     auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0)));
 
-    // 7. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve).
+    // 7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
     auto result = perform_promise_all_settled(global_object, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
-        // a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+        // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
         if (!iterator_record.done)
             result = iterator_close(global_object, iterator_record, result.release_error());
 
@@ -378,8 +378,8 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::all_settled)
         TRY_OR_REJECT(global_object, promise_capability, result);
     }
 
-    // 9. Return Completion(result).
-    return result.release_value();
+    // 9. Return ? result.
+    return result;
 }
 
 // 27.2.4.3 Promise.any ( iterable ), https://tc39.es/ecma262/#sec-promise.any
@@ -391,20 +391,20 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
     auto promise_capability = TRY(new_promise_capability(global_object, constructor));
 
-    // 3. Let promiseResolve be GetPromiseResolve(C).
+    // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
     auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
 
-    // 5. Let iteratorRecord be GetIterator(iterable).
+    // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
     auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0)));
 
-    // 7. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve).
+    // 7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
     auto result = perform_promise_any(global_object, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
-        // a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+        // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
         if (!iterator_record.done)
             result = iterator_close(global_object, iterator_record, result.release_error());
 
@@ -412,8 +412,8 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::any)
         TRY_OR_REJECT(global_object, promise_capability, result);
     }
 
-    // 9. Return Completion(result).
-    return result.release_value();
+    // 9. Return ? result.
+    return result;
 }
 
 // 27.2.4.5 Promise.race ( iterable ), https://tc39.es/ecma262/#sec-promise.race
@@ -425,20 +425,20 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
     // 2. Let promiseCapability be ? NewPromiseCapability(C).
     auto promise_capability = TRY(new_promise_capability(global_object, constructor));
 
-    // 3. Let promiseResolve be GetPromiseResolve(C).
+    // 3. Let promiseResolve be Completion(GetPromiseResolve(C)).
     // 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
     auto promise_resolve = TRY_OR_REJECT(global_object, promise_capability, get_promise_resolve(global_object, constructor));
 
-    // 5. Let iteratorRecord be GetIterator(iterable).
+    // 5. Let iteratorRecord be Completion(GetIterator(iterable)).
     // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
     auto iterator_record = TRY_OR_REJECT(global_object, promise_capability, get_iterator(global_object, vm.argument(0)));
 
-    // 7. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+    // 7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
     auto result = perform_promise_race(global_object, iterator_record, constructor, promise_capability, promise_resolve);
 
     // 8. If result is an abrupt completion, then
     if (result.is_error()) {
-        // a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+        // a. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
         if (!iterator_record.done)
             result = iterator_close(global_object, iterator_record, result.release_error());
 
@@ -446,8 +446,8 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::race)
         TRY_OR_REJECT(global_object, promise_capability, result);
     }
 
-    // 9. Return Completion(result).
-    return result.release_value();
+    // 9. Return ? result.
+    return result;
 }
 
 // 27.2.4.6 Promise.reject ( r ), https://tc39.es/ecma262/#sec-promise.reject

+ 13 - 17
Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -50,7 +50,7 @@ static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, Pr
             handler_result = throw_completion(argument);
         }
     }
-    // e. Else, let handlerResult be HostCallJobCallback(handler, undefined, « argument »).
+    // e. Else, let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)).
     else {
         dbgln_if(PROMISE_DEBUG, "run_reaction_job: Calling handler callback {} @ {} with argument {}", handler.value().callback.cell()->class_name(), handler.value().callback.cell(), argument);
         MarkedVector<Value> arguments(vm.heap());
@@ -63,7 +63,7 @@ static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, Pr
         // i. Assert: handlerResult is not an abrupt completion.
         VERIFY(!handler_result.is_abrupt());
 
-        // ii. Return NormalCompletion(empty).
+        // ii. Return empty.
         dbgln_if(PROMISE_DEBUG, "run_reaction_job: Reaction has no PromiseCapability, returning empty value");
         // TODO: This can't return an empty value at the moment, because the implicit conversion to Completion would fail.
         //       Change it back when this is using completions (`return normal_completion({})`)
@@ -74,20 +74,18 @@ static ThrowCompletionOr<Value> run_reaction_job(GlobalObject& global_object, Pr
 
     // h. If handlerResult is an abrupt completion, then
     if (handler_result.is_abrupt()) {
-        // i. Let status be Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
+        // i. Return ? Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
         auto* reject_function = promise_capability.value().reject;
         dbgln_if(PROMISE_DEBUG, "run_reaction_job: Calling PromiseCapability's reject function @ {}", reject_function);
         return call(global_object, *reject_function, js_undefined(), *handler_result.value());
     }
     // i. Else,
     else {
-        // i. Let status be Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
+        // i. Return ? Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
         auto* resolve_function = promise_capability.value().resolve;
         dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob]: Calling PromiseCapability's resolve function @ {}", resolve_function);
         return call(global_object, *resolve_function, js_undefined(), *handler_result.value());
     }
-
-    // j. Return Completion(status).
 }
 
 // 27.2.2.1 NewPromiseReactionJob ( reaction, argument ), https://tc39.es/ecma262/#sec-newpromisereactionjob
@@ -105,7 +103,7 @@ PromiseJob create_promise_reaction_job(GlobalObject& global_object, PromiseReact
     // 3. If reaction.[[Handler]] is not empty, then
     auto& handler = reaction.handler();
     if (handler.has_value()) {
-        // a. Let getHandlerRealmResult be GetFunctionRealm(reaction.[[Handler]].[[Callback]]).
+        // a. Let getHandlerRealmResult be Completion(GetFunctionRealm(reaction.[[Handler]].[[Callback]])).
         auto get_handler_realm_result = get_function_realm(global_object, *handler->callback.cell());
 
         // b. If getHandlerRealmResult is a normal completion, set handlerRealm to getHandlerRealmResult.[[Value]].
@@ -131,7 +129,7 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_ob
     // a. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
     auto [resolve_function, reject_function] = promise_to_resolve.create_resolving_functions();
 
-    // b. Let thenCallResult be HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
+    // b. Let thenCallResult be Completion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
     dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: Calling then job callback for thenable {}", &thenable);
     MarkedVector<Value> arguments(vm.heap());
     arguments.append(Value(&resolve_function));
@@ -140,15 +138,12 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_ob
 
     // c. If thenCallResult is an abrupt completion, then
     if (then_call_result.is_error()) {
-        // i. Let status be Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
+        // i. Return ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
         dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: then_call_result is an abrupt completion, calling reject function with value {}", *then_call_result.throw_completion().value());
-        auto status = call(global_object, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
-
-        // ii. Return Completion(status).
-        return status;
+        return call(global_object, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
     }
 
-    // d. Return Completion(thenCallResult).
+    // d. Return ? thenCallResult.
     dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: Returning then call result {}", then_call_result.value());
     return then_call_result;
 }
@@ -156,10 +151,11 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(GlobalObject& global_ob
 // 27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then ), https://tc39.es/ecma262/#sec-newpromiseresolvethenablejob
 PromiseJob create_promise_resolve_thenable_job(GlobalObject& global_object, Promise& promise_to_resolve, Value thenable, JobCallback then)
 {
-    // 2. Let getThenRealmResult be GetFunctionRealm(then.[[Callback]]).
-    Realm* then_realm { nullptr };
+    // 2. Let getThenRealmResult be Completion(GetFunctionRealm(then.[[Callback]])).
     auto get_then_realm_result = get_function_realm(global_object, *then.callback.cell());
 
+    Realm* then_realm;
+
     // 3. If getThenRealmResult is a normal completion, let thenRealm be getThenRealmResult.[[Value]].
     if (!get_then_realm_result.is_throw_completion()) {
         then_realm = get_then_realm_result.release_value();

+ 5 - 5
Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -116,14 +116,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
                 return value_handle.value();
             };
 
-            // iv. Let valueThunk be ! CreateBuiltinFunction(returnValue, 0, "", « »).
+            // iv. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
             auto* value_thunk = NativeFunction::create(global_object, move(return_value), 0, "");
 
             // v. Return ? Invoke(promise, "then", « valueThunk »).
             return TRY(Value(promise).invoke(global_object, vm.names.then, value_thunk));
         };
 
-        // b. Let thenFinally be ! CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
+        // b. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
         then_finally = NativeFunction::create(global_object, move(then_finally_closure), 1, "");
 
         // c. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
@@ -144,14 +144,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
                 return throw_completion(reason_handle.value());
             };
 
-            // iv. Let thrower be ! CreateBuiltinFunction(throwReason, 0, "", « »).
+            // iv. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
             auto* thrower = NativeFunction::create(global_object, move(throw_reason), 0, "");
 
             // v. Return ? Invoke(promise, "then", « thrower »).
             return TRY(Value(promise).invoke(global_object, vm.names.then, thrower));
         };
 
-        // d. Let catchFinally be ! CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
+        // d. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
         catch_finally = NativeFunction::create(global_object, move(catch_finally_closure), 1, "");
     }
 

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -54,7 +54,7 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(GlobalObject& global
         return js_undefined();
     };
 
-    // 5. Let executor be ! CreateBuiltinFunction(executorClosure, 2, "", « »).
+    // 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
     auto* executor = NativeFunction::create(global_object, move(executor_closure), 2, "");
 
     // 6. Let promise be ? Construct(C, « executor »).

+ 21 - 15
Userland/Libraries/LibJS/Runtime/PromiseReaction.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -21,22 +21,28 @@ struct PromiseCapability {
 };
 
 // 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
-#define TRY_OR_REJECT(global_object, capability, expression)                                                                            \
-    ({                                                                                                                                  \
-        auto _temporary_try_or_reject_result = (expression);                                                                            \
-        /* 1. If value is an abrupt completion, then */                                                                                 \
-        if (_temporary_try_or_reject_result.is_error()) {                                                                               \
-            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                           \
-            TRY(JS::call(global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
-                                                                                                                                        \
-            /* b. Return capability.[[Promise]]. */                                                                                     \
-            return capability.promise;                                                                                                  \
-        }                                                                                                                               \
-                                                                                                                                        \
-        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                    \
-        _temporary_try_or_reject_result.release_value();                                                                                \
+#define __TRY_OR_REJECT(global_object, capability, expression, CALL_CHECK)                                                                     \
+    ({                                                                                                                                         \
+        auto _temporary_try_or_reject_result = (expression);                                                                                   \
+        /* 1. If value is an abrupt completion, then */                                                                                        \
+        if (_temporary_try_or_reject_result.is_error()) {                                                                                      \
+            /* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */                                                  \
+            CALL_CHECK(JS::call(global_object, *capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
+                                                                                                                                               \
+            /* b. Return capability.[[Promise]]. */                                                                                            \
+            return capability.promise;                                                                                                         \
+        }                                                                                                                                      \
+                                                                                                                                               \
+        /* 2. Else if value is a Completion Record, set value to value.[[Value]]. */                                                           \
+        _temporary_try_or_reject_result.release_value();                                                                                       \
     })
 
+#define TRY_OR_REJECT(global_object, capability, expression) \
+    __TRY_OR_REJECT(global_object, capability, expression, TRY)
+
+#define TRY_OR_MUST_REJECT(global_object, capability, expression) \
+    __TRY_OR_REJECT(global_object, capability, expression, MUST)
+
 // 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
 #define TRY_OR_REJECT_WITH_VALUE(global_object, capability, expression)                                                                 \
     ({                                                                                                                                  \

+ 6 - 6
Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp

@@ -76,7 +76,7 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
     // 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 10. If remainingElementsCount.[[Value]] is 0, then
     if (--m_remaining_elements.value == 0) {
-        // a. Let valuesArray be ! CreateArrayFromList(values).
+        // a. Let valuesArray be CreateArrayFromList(values).
         auto* values_array = Array::create_from(global_object, m_values.values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
@@ -102,7 +102,7 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
     auto& vm = this->vm();
     auto& global_object = this->global_object();
 
-    // 9. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
     auto* object = Object::create(global_object, global_object.object_prototype());
 
     // 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
@@ -117,7 +117,7 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
     // 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 14. If remainingElementsCount.[[Value]] is 0, then
     if (--m_remaining_elements.value == 0) {
-        // a. Let valuesArray be ! CreateArrayFromList(values).
+        // a. Let valuesArray be CreateArrayFromList(values).
         auto* values_array = Array::create_from(global_object, m_values.values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
@@ -143,7 +143,7 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
     auto& vm = this->vm();
     auto& global_object = this->global_object();
 
-    // 9. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
     auto* object = Object::create(global_object, global_object.object_prototype());
 
     // 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
@@ -158,7 +158,7 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
     // 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 14. If remainingElementsCount.[[Value]] is 0, then
     if (--m_remaining_elements.value == 0) {
-        // a. Let valuesArray be ! CreateArrayFromList(values).
+        // a. Let valuesArray be CreateArrayFromList(values).
         auto* values_array = Array::create_from(global_object, m_values.values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
@@ -193,7 +193,7 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
         // a. Let error be a newly created AggregateError object.
         auto* error = AggregateError::create(global_object);
 
-        // b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: ! CreateArrayFromList(errors) }).
+        // b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
         auto* errors_array = Array::create_from(global_object, m_values.values());
         MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp

@@ -105,7 +105,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
 
     // 4. If hasEnumerable is true, then
     if (has_enumerable) {
-        // a. Let enumerable be ! ToBoolean(? Get(Obj, "enumerable")).
+        // a. Let enumerable be ToBoolean(? Get(Obj, "enumerable")).
         auto enumerable = TRY(object.get(vm.names.enumerable)).to_boolean();
 
         // b. Set desc.[[Enumerable]] to enumerable.
@@ -117,7 +117,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
 
     // 6. If hasConfigurable is true, then
     if (has_configurable) {
-        // a. Let configurable be ! ToBoolean(? Get(Obj, "configurable")).
+        // a. Let configurable be ToBoolean(? Get(Obj, "configurable")).
         auto configurable = TRY(object.get(vm.names.configurable)).to_boolean();
 
         // b. Set desc.[[Configurable]] to configurable.
@@ -141,7 +141,7 @@ ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(GlobalObject& globa
 
     // 10. If hasWritable is true, then
     if (has_writable) {
-        // a. Let writable be ! ToBoolean(? Get(Obj, "writable")).
+        // a. Let writable be ToBoolean(? Get(Obj, "writable")).
         auto writable = TRY(object.get(vm.names.writable)).to_boolean();
 
         // b. Set desc.[[Writable]] to writable.

+ 3 - 3
Userland/Libraries/LibJS/Runtime/ProxyConstructor.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -80,11 +80,11 @@ JS_DEFINE_NATIVE_FUNCTION(ProxyConstructor::revocable)
         return js_undefined();
     };
 
-    // 3. Let revoker be ! CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
+    // 3. Let revoker be CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
     // 4. Set revoker.[[RevocableProxy]] to p.
     auto* revoker = NativeFunction::create(global_object, move(revoker_closure), 0, "");
 
-    // 5. Let result be ! OrdinaryObjectCreate(%Object.prototype%).
+    // 5. Let result be OrdinaryObjectCreate(%Object.prototype%).
     auto* result = Object::create(global_object, global_object.object_prototype());
 
     // 6. Perform ! CreateDataPropertyOrThrow(result, "proxy", p).

+ 10 - 10
Userland/Libraries/LibJS/Runtime/ProxyObject.cpp

@@ -113,7 +113,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
         return m_target.internal_set_prototype_of(prototype);
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, V »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, prototype)).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
@@ -162,7 +162,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
         return m_target.is_extensible();
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target)).to_boolean();
 
     // 8. Let targetResult be ? IsExtensible(target).
@@ -200,7 +200,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
         return m_target.internal_prevent_extensions();
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target)).to_boolean();
 
     // 8. If booleanTrapResult is true, then
@@ -280,7 +280,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
     // 12. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
     auto result_desc = TRY(to_property_descriptor(global_object, trap_result));
 
-    // 13. Call CompletePropertyDescriptor(resultDesc).
+    // 13. Perform CompletePropertyDescriptor(resultDesc).
     result_desc.complete();
 
     // 14. Let valid be IsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc).
@@ -338,7 +338,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
     // 7. Let descObj be FromPropertyDescriptor(Desc).
     auto descriptor_object = from_property_descriptor(global_object, property_descriptor);
 
-    // 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)).
+    // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, descObj »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
 
     // 9. If booleanTrapResult is false, return false.
@@ -418,7 +418,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
         return m_target.internal_has_property(property_key);
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
 
     // 8. If booleanTrapResult is false, then
@@ -544,7 +544,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
         return m_target.internal_set(property_key, value, receiver);
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
@@ -600,7 +600,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
         return m_target.internal_delete(property_key);
     }
 
-    // 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)).
+    // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
     auto trap_result = TRY(call(global_object, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
@@ -782,7 +782,7 @@ ThrowCompletionOr<Value> ProxyObject::internal_call(Value this_argument, MarkedV
         return call(global_object, &m_target, this_argument, move(arguments_list));
     }
 
-    // 7. Let argArray be ! CreateArrayFromList(argumentsList).
+    // 7. Let argArray be CreateArrayFromList(argumentsList).
     auto* arguments_array = Array::create_from(global_object, arguments_list);
 
     // 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
@@ -830,7 +830,7 @@ ThrowCompletionOr<Object*> ProxyObject::internal_construct(MarkedVector<Value> a
         return construct(global_object, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target);
     }
 
-    // 8. Let argArray be ! CreateArrayFromList(argumentsList).
+    // 8. Let argArray be CreateArrayFromList(argumentsList).
     auto* arguments_array = Array::create_from(global_object, arguments_list);
 
     // 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -37,7 +37,7 @@ void Realm::set_global_object(GlobalObject& global_object, Object* this_value)
     // 6. Set realmRec.[[GlobalEnv]] to newGlobalEnv.
     m_global_environment = global_object.heap().allocate_without_global_object<GlobalEnvironment>(global_object, *this_value);
 
-    // 7. Return realmRec.
+    // 7. Return unused.
 }
 
 void Realm::visit_edges(Visitor& visitor)

+ 6 - 4
Userland/Libraries/LibJS/Runtime/Reference.cpp

@@ -31,8 +31,10 @@ ThrowCompletionOr<void> Reference::put_value(GlobalObject& global_object, Value
             return throw_reference_error(global_object);
 
         // b. Let globalObj be GetGlobalObject().
-        // c. Return ? Set(globalObj, V.[[ReferencedName]], W, false).
+        // c. Perform ? Set(globalObj, V.[[ReferencedName]], W, false).
         TRY(global_object.set(m_name, value, Object::ShouldThrowExceptions::No));
+
+        // Return unused.
         return {};
     }
 
@@ -54,7 +56,7 @@ ThrowCompletionOr<void> Reference::put_value(GlobalObject& global_object, Value
         if (!succeeded && m_strict)
             return vm.throw_completion<TypeError>(global_object, ErrorType::ReferenceNullishSetProperty, m_name, m_base_value.to_string_without_side_effects());
 
-        // e. Return.
+        // e. Return unused.
         return {};
     }
 
@@ -163,7 +165,7 @@ ThrowCompletionOr<bool> Reference::delete_(GlobalObject& global_object)
 
     // 5. If IsPropertyReference(ref) is true, then
     if (is_property_reference()) {
-        // a. Assert: ! IsPrivateReference(ref) is false.
+        // a. Assert: IsPrivateReference(ref) is false.
         VERIFY(!is_private_reference());
 
         // b. If IsSuperReference(ref) is true, throw a ReferenceError exception.
@@ -239,7 +241,7 @@ Reference make_private_reference(VM& vm, Value base_value, FlyString const& priv
     // 2. Assert: privEnv is not null.
     VERIFY(private_environment);
 
-    // 3. Let privateName be ! ResolvePrivateIdentifier(privEnv, privateIdentifier).
+    // 3. Let privateName be ResolvePrivateIdentifier(privEnv, privateIdentifier).
     auto private_name = private_environment->resolve_private_identifier(private_identifier);
 
     // 4. Return the Reference Record { [[Base]]: baseValue, [[ReferencedName]]: privateName, [[Strict]]: true, [[ThisValue]]: empty }.

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

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
@@ -274,7 +274,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(GlobalObject& global_object,
     MUST(array->create_data_property_or_throw(0, js_string(vm, match.view.u16_view())));
 
     // 29. If R contains any GroupName, then
-    //     a. Let groups be ! OrdinaryObjectCreate(null).
+    //     a. Let groups be OrdinaryObjectCreate(null).
     //     b. Let hasGroups be true.
     // 30. Else,
     //     a. Let groups be undefined.
@@ -395,7 +395,7 @@ size_t advance_string_index(Utf16View const& string, size_t index, bool unicode)
     if (index + 1 >= string.length_in_code_units())
         return index + 1;
 
-    // 5. Let cp be ! CodePointAt(S, index).
+    // 5. Let cp be CodePointAt(S, index).
     auto code_point = code_point_at(string, index);
 
     // 6. Return index + cp.[[CodeUnitCount]].
@@ -458,17 +458,17 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::flags)
 
     // 4. Let hasIndices be ToBoolean(? Get(R, "hasIndices")).
     // 5. If hasIndices is true, append the code unit 0x0064 (LATIN SMALL LETTER D) as the last code unit of result.
-    // 6. Let global be ! ToBoolean(? Get(R, "global")).
+    // 6. Let global be ToBoolean(? Get(R, "global")).
     // 7. If global is true, append the code unit 0x0067 (LATIN SMALL LETTER G) as the last code unit of result.
-    // 8. Let ignoreCase be ! ToBoolean(? Get(R, "ignoreCase")).
+    // 8. Let ignoreCase be ToBoolean(? Get(R, "ignoreCase")).
     // 9. If ignoreCase is true, append the code unit 0x0069 (LATIN SMALL LETTER I) as the last code unit of result.
-    // 10. Let multiline be ! ToBoolean(? Get(R, "multiline")).
+    // 10. Let multiline be ToBoolean(? Get(R, "multiline")).
     // 11. If multiline is true, append the code unit 0x006D (LATIN SMALL LETTER M) as the last code unit of result.
-    // 12. Let dotAll be ! ToBoolean(? Get(R, "dotAll")).
+    // 12. Let dotAll be ToBoolean(? Get(R, "dotAll")).
     // 13. If dotAll is true, append the code unit 0x0073 (LATIN SMALL LETTER S) as the last code unit of result.
-    // 14. Let unicode be ! ToBoolean(? Get(R, "unicode")).
+    // 14. Let unicode be ToBoolean(? Get(R, "unicode")).
     // 15. If unicode is true, append the code unit 0x0075 (LATIN SMALL LETTER U) as the last code unit of result.
-    // 16. Let sticky be ! ToBoolean(? Get(R, "sticky")).
+    // 16. Let sticky be ToBoolean(? Get(R, "sticky")).
     // 17. If sticky is true, append the code unit 0x0079 (LATIN SMALL LETTER Y) as the last code unit of result.
 #define __JS_ENUMERATE(flagName, flag_name, flag_char)                  \
     auto flag_##flag_name = TRY(regexp_object->get(vm.names.flagName)); \
@@ -491,7 +491,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match)
     // 3. Let S be ? ToString(string).
     auto string = TRY(vm.argument(0).to_utf16_string(global_object));
 
-    // 4. Let global be ! ToBoolean(? Get(rx, "global")).
+    // 4. Let global be ToBoolean(? Get(rx, "global")).
     bool global = TRY(regexp_object->get(vm.names.global)).to_boolean();
 
     // 5. If global is false, then
@@ -503,7 +503,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match)
     // 6. Else,
     // a. Assert: global is true.
 
-    // b. Let fullUnicode be ! ToBoolean(? Get(rx, "unicode")).
+    // b. Let fullUnicode be ToBoolean(? Get(rx, "unicode")).
     bool full_unicode = TRY(regexp_object->get(vm.names.unicode)).to_boolean();
 
     // c. Perform ? Set(rx, "lastIndex", +0𝔽, true).
@@ -587,7 +587,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
     // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true).
     TRY(matcher->set(vm.names.lastIndex, Value(last_index), Object::ShouldThrowExceptions::Yes));
 
-    // 13. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode).
+    // 13. Return CreateRegExpStringIterator(matcher, S, global, fullUnicode).
     return RegExpStringIterator::create(global_object, *matcher, move(string), global, full_unicode);
 }
 
@@ -614,13 +614,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace)
         replace_value = js_string(vm, move(replace_string));
     }
 
-    // 7. Let global be ! ToBoolean(? Get(rx, "global")).
+    // 7. Let global be ToBoolean(? Get(rx, "global")).
     bool global = TRY(regexp_object->get(vm.names.global)).to_boolean();
     bool full_unicode = false;
 
     // 8. If global is true, then
     if (global) {
-        // a. Let fullUnicode be ! ToBoolean(? Get(rx, "unicode")).
+        // a. Let fullUnicode be ToBoolean(? Get(rx, "unicode")).
         full_unicode = TRY(regexp_object->get(vm.names.unicode)).to_boolean();
 
         // b. Perform ? Set(rx, "lastIndex", +0𝔽, true).

+ 7 - 7
Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp

@@ -76,7 +76,7 @@ ThrowCompletionOr<void> copy_name_and_length(GlobalObject& global_object, Functi
         }
     }
 
-    // 5. Perform ! SetFunctionLength(F, L).
+    // 5. Perform SetFunctionLength(F, L).
     function.set_function_length(length);
 
     // 6. Let targetName be ? Get(Target, "name").
@@ -86,7 +86,7 @@ ThrowCompletionOr<void> copy_name_and_length(GlobalObject& global_object, Functi
     if (!target_name.is_string())
         target_name = js_string(vm, String::empty());
 
-    // 8. Perform ! SetFunctionName(F, targetName, prefix).
+    // 8. Perform SetFunctionName(F, targetName, prefix).
     function.set_function_name({ target_name.as_string().string() }, move(prefix));
 
     return {};
@@ -102,7 +102,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
 
     // 2. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
 
-    // a. Let script be ParseText(! StringToCodePoints(sourceText), Script).
+    // a. Let script be ParseText(StringToCodePoints(sourceText), Script).
     auto parser = Parser(Lexer(source_text));
     auto program = parser.parse_program();
 
@@ -165,7 +165,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
     // 15. Push evalContext onto the execution context stack; evalContext is now the running execution context.
     TRY(vm.push_execution_context(eval_context, eval_realm.global_object()));
 
-    // 16. Let result be EvalDeclarationInstantiation(body, varEnv, lexEnv, null, strictEval).
+    // 16. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, null, strictEval)).
     auto eval_result = eval_declaration_instantiation(vm, eval_realm.global_object(), program, variable_environment, lexical_environment, nullptr, strict_eval);
 
     Completion result;
@@ -217,7 +217,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
     // 5. Push evalContext onto the execution context stack; evalContext is now the running execution context.
     TRY(vm.push_execution_context(eval_context, eval_realm.global_object()));
 
-    // 6. Perform ! HostImportModuleDynamically(null, specifierString, innerCapability).
+    // 6. Perform HostImportModuleDynamically(null, specifierString, innerCapability).
     vm.host_import_module_dynamically(Empty {}, ModuleRequest { move(specifier_string) }, inner_capability);
 
     // 7. Suspend evalContext and remove it from the execution context stack.
@@ -258,7 +258,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
         return get_wrapped_value(global_object, *realm, value);
     };
 
-    // 10. Let onFulfilled be ! CreateBuiltinFunction(steps, 1, "", « [[ExportNameString]] », callerRealm).
+    // 10. Let onFulfilled be CreateBuiltinFunction(steps, 1, "", « [[ExportNameString]] », callerRealm).
     // 11. Set onFulfilled.[[ExportNameString]] to exportNameString.
     auto* on_fulfilled = NativeFunction::create(global_object, move(steps), 1, "", &caller_realm);
 
@@ -271,7 +271,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(GlobalObject& global_object,
         return vm.template throw_completion<TypeError>(global_object, vm.argument(0).as_object().get_without_side_effects(vm.names.message).as_string().string());
     });
 
-    // 13. Return ! PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
+    // 13. Return PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
     return verify_cast<Promise>(inner_capability.promise)->perform_then(on_fulfilled, throw_type_error, promise_capability);
 }
 

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

@@ -50,7 +50,7 @@ static Optional<PropertyDescriptor> string_get_own_property(StringObject const&
     if (property_key.is_symbol())
         return {};
 
-    // 2. Let index be ! CanonicalNumericIndexString(P).
+    // 2. Let index be CanonicalNumericIndexString(P).
     auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
 
     // 3. If index is undefined, return undefined.
@@ -94,7 +94,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> StringObject::internal_get_own_p
     if (descriptor.has_value())
         return descriptor;
 
-    // 3. Return ! StringGetOwnProperty(S, P).
+    // 3. Return StringGetOwnProperty(S, P).
     return string_get_own_property(*this, property_key);
 }
 
@@ -103,7 +103,7 @@ ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey c
 {
     VERIFY(property_key.is_valid());
 
-    // 1. Let stringDesc be ! StringGetOwnProperty(S, P).
+    // 1. Let stringDesc be StringGetOwnProperty(S, P).
     auto string_descriptor = string_get_own_property(*this, property_key);
 
     // 2. If stringDesc is not undefined, then
@@ -111,7 +111,7 @@ ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey c
         // a. Let extensible be S.[[Extensible]].
         auto extensible = m_is_extensible;
 
-        // b. Return ! IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc).
+        // b. Return IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc).
         return is_compatible_property_descriptor(extensible, property_descriptor, string_descriptor);
     }
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/StringPrototype.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -354,7 +354,7 @@ static ThrowCompletionOr<String> transform_case(GlobalObject& global_object, Str
     if (!locale.has_value())
         locale = "und"sv;
 
-    // 8. Let codePoints be ! StringToCodePoints(S).
+    // 8. Let codePoints be StringToCodePoints(S).
 
     String new_code_points;
 
@@ -374,7 +374,7 @@ static ThrowCompletionOr<String> transform_case(GlobalObject& global_object, Str
         VERIFY_NOT_REACHED();
     }
 
-    // 11. Return ! CodePointsToString(newCodePoints).
+    // 11. Return CodePointsToString(newCodePoints).
     return new_code_points;
 }
 

+ 13 - 13
Userland/Libraries/LibJS/Runtime/TypedArray.h

@@ -80,7 +80,7 @@ inline bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalI
     if (typed_array.viewed_array_buffer()->is_detached())
         return false;
 
-    // 2. If ! IsIntegralNumber(index) is false, return false.
+    // 2. If IsIntegralNumber(index) is false, return false.
     // 3. If index is -0𝔽, return false.
     if (!property_index.is_index())
         return false;
@@ -185,11 +185,11 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
-                // i. Let value be ! IntegerIndexedElementGet(O, numericIndex).
+                // i. Let value be IntegerIndexedElementGet(O, numericIndex).
                 auto value = integer_indexed_element_get<T>(*this, numeric_index);
 
                 // ii. If value is undefined, return undefined.
@@ -222,9 +222,9 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
-            // b. If numericIndex is not undefined, return ! IsValidIntegerIndex(O, numericIndex).
+            // b. If numericIndex is not undefined, return IsValidIntegerIndex(O, numericIndex).
             if (!numeric_index.is_undefined())
                 return is_valid_integer_index(*this, numeric_index);
         }
@@ -245,11 +245,11 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
-                // i. If ! IsValidIntegerIndex(O, numericIndex) is false, return false.
+                // i. If IsValidIntegerIndex(O, numericIndex) is false, return false.
                 if (!is_valid_integer_index(*this, numeric_index))
                     return false;
 
@@ -261,7 +261,7 @@ public:
                 if (property_descriptor.enumerable.has_value() && !*property_descriptor.enumerable)
                     return false;
 
-                // iv. If ! IsAccessorDescriptor(Desc) is true, return false.
+                // iv. If IsAccessorDescriptor(Desc) is true, return false.
                 if (property_descriptor.is_accessor_descriptor())
                     return false;
 
@@ -295,11 +295,11 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
-                // i. Return ! IntegerIndexedElementGet(O, numericIndex).
+                // i. Return IntegerIndexedElementGet(O, numericIndex).
                 return integer_indexed_element_get<T>(*this, numeric_index);
             }
         }
@@ -322,7 +322,7 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
@@ -350,11 +350,11 @@ public:
         // 1. If Type(P) is String, then
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
-            // a. Let numericIndex be ! CanonicalNumericIndexString(P).
+            // a. Let numericIndex be CanonicalNumericIndexString(P).
             auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
-                // i. If ! IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.
+                // i. If IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.
                 if (!is_valid_integer_index(*this, numeric_index))
                     return true;
                 return false;

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -119,11 +119,8 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::of)
     MarkedVector<Value> arguments(vm.heap());
     arguments.append(Value(length));
     auto new_object = TRY(typed_array_create(global_object, constructor.as_function(), move(arguments)));
-    for (size_t k = 0; k < length; ++k) {
-        auto success = TRY(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes));
-        if (!success)
-            return vm.throw_completion<TypeError>(global_object, ErrorType::TypedArrayFailedSettingIndex, k);
-    }
+    for (size_t k = 0; k < length; ++k)
+        TRY(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes));
     return new_object;
 }
 

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

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  * Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org>
  *
@@ -1383,7 +1383,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
         // b. Let kValue be ! Get(O, Pk).
         auto value = MUST(typed_array->get(i));
 
-        // c. Let selected be ! ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
+        // c. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
         auto callback_result = TRY(call(global_object, *callback_function, this_value, value, Value((i32)i), typed_array)).to_boolean();
 
         // d. If selected is true, then

+ 20 - 15
Userland/Libraries/LibJS/Runtime/VM.cpp

@@ -282,13 +282,13 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
         // 1. Perform ? RequireObjectCoercible(value).
         TRY(require_object_coercible(global_object, value));
 
-        // 2. Return the result of performing BindingInitialization of ObjectBindingPattern with arguments value and environment.
+        // 2. Return ? BindingInitialization of ObjectBindingPattern with arguments value and environment.
 
         // BindingInitialization of ObjectBindingPattern
         // 1. Perform ? PropertyBindingInitialization of BindingPropertyList with arguments value and environment.
         TRY(property_binding_initialization(*target, value, environment, global_object));
 
-        // 2. Return NormalCompletion(empty).
+        // 2. Return unused.
         return {};
     }
     // BindingPattern : ArrayBindingPattern
@@ -296,7 +296,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
         // 1. Let iteratorRecord be ? GetIterator(value).
         auto iterator_record = TRY(get_iterator(global_object, value));
 
-        // 2. Let result be IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment.
+        // 2. Let result be Completion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecord and environment).
         auto result = iterator_binding_initialization(*target, iterator_record, environment, global_object);
 
         // 3. If iteratorRecord.[[Done]] is false, return ? IteratorClose(iteratorRecord, result).
@@ -308,7 +308,7 @@ ThrowCompletionOr<void> VM::binding_initialization(NonnullRefPtr<BindingPattern>
                 return completion.release_error();
         }
 
-        // 4. Return result.
+        // 4. Return ? result.
         return result;
     }
 }
@@ -439,7 +439,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
 
                 // a. If iteratorRecord.[[Done]] is false, then
                 if (!iterator_record.done) {
-                    // i. Let next be IteratorStep(iteratorRecord).
+                    // i. Let next be Completion(IteratorStep(iteratorRecord)).
                     next = iterator_step(global_object, iterator_record);
 
                     // ii. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -460,7 +460,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
                     break;
                 }
 
-                // c. Let nextValue be IteratorValue(next).
+                // c. Let nextValue be Completion(IteratorValue(next)).
                 auto next_value = iterator_value(global_object, *next.value());
 
                 // d. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -485,7 +485,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
 
             // 2. If iteratorRecord.[[Done]] is false, then
             if (!iterator_record.done) {
-                // a. Let next be IteratorStep(iteratorRecord).
+                // a. Let next be Completion(IteratorStep(iteratorRecord)).
                 auto next = iterator_step(global_object, iterator_record);
 
                 // b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -501,7 +501,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
                 }
                 // e. Else,
                 else {
-                    // i. Set v to IteratorValue(next).
+                    // i. Set v to Completion(IteratorValue(next)).
                     auto value_or_error = iterator_value(global_object, *next.value());
 
                     // ii. If v is an abrupt completion, set iteratorRecord.[[Done]] to true.
@@ -980,7 +980,7 @@ void VM::import_module_dynamically(ScriptOrModule referencing_script_or_module,
         }
     }
 
-    // It must return NormalCompletion(undefined).
+    // It must return unused.
     // Note: Just return void always since the resulting value cannot be accessed by user code.
 }
 
@@ -1000,7 +1000,7 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
         // c. Assert: Evaluate has already been invoked on moduleRecord and successfully completed.
         // Note: If HostResolveImportedModule returns a module evaluate will have been called on it.
 
-        // d. Let namespace be GetModuleNamespace(moduleRecord).
+        // d. Let namespace be Completion(GetModuleNamespace(moduleRecord)).
         auto namespace_ = module_record->get_module_namespace(vm);
 
         // e. If namespace is an abrupt completion, then
@@ -1013,11 +1013,12 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
             // i. Perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] »).
             MUST(call(global_object, resolve_function.cell(), js_undefined(), namespace_.release_value()));
         }
-        // g. Return undefined.
+        // g. Return unused.
+        // NOTE: We don't support returning an empty/optional/unused value here.
         return js_undefined();
     };
 
-    // 2. Let onFulfilled be ! CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
+    // 2. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
     auto* on_fulfilled = NativeFunction::create(current_realm()->global_object(), move(fulfilled_closure), 0, "");
 
     // 3. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures promiseCapability and performs the following steps when called:
@@ -1025,15 +1026,19 @@ void VM::finish_dynamic_import(ScriptOrModule referencing_script_or_module, Modu
         auto error = vm.argument(0);
         // a. Perform ! Call(promiseCapability.[[Reject]], undefined, « error »).
         MUST(call(global_object, rejected_function.cell(), js_undefined(), error));
-        // b. Return undefined.
+
+        // b. Return unused.
+        // NOTE: We don't support returning an empty/optional/unused value here.
         return js_undefined();
     };
 
-    // 4. Let onRejected be ! CreateBuiltinFunction(rejectedClosure, 0, "", « »).
+    // 4. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
     auto* on_rejected = NativeFunction::create(current_realm()->global_object(), move(rejected_closure), 0, "");
 
-    // 5. Perform ! PerformPromiseThen(innerPromise, onFulfilled, onRejected).
+    // 5. Perform PerformPromiseThen(innerPromise, onFulfilled, onRejected).
     inner_promise->perform_then(on_fulfilled, on_rejected, {});
+
+    // 6. Return unused.
 }
 
 }

+ 12 - 12
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
@@ -523,7 +523,7 @@ ThrowCompletionOr<BigInt*> Value::to_bigint(GlobalObject& global_object) const
     case Type::Double:
         return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "number", "BigInt");
     case Type::String: {
-        // 1. Let n be ! StringToBigInt(prim).
+        // 1. Let n be StringToBigInt(prim).
         auto bigint = primitive.string_to_bigint(global_object);
 
         // 2. If n is undefined, throw a SyntaxError exception.
@@ -590,7 +590,7 @@ Optional<BigInt*> Value::string_to_bigint(GlobalObject& global_object) const
 {
     VERIFY(is_string());
 
-    // 1. Let text be ! StringToCodePoints(str).
+    // 1. Let text be StringToCodePoints(str).
     auto text = as_string().string().view().trim_whitespace();
 
     // 2. Let literal be ParseText(text, StringIntegerLiteral).
@@ -1429,46 +1429,46 @@ ThrowCompletionOr<bool> is_loosely_equal(GlobalObject& global_object, Value lhs,
 
     // == End of B.3.6.2 ==
 
-    // 5. If Type(x) is Number and Type(y) is String, return IsLooselyEqual(x, ! ToNumber(y)).
+    // 5. If Type(x) is Number and Type(y) is String, return ! IsLooselyEqual(x, ! ToNumber(y)).
     if (lhs.is_number() && rhs.is_string())
         return is_loosely_equal(global_object, lhs, MUST(rhs.to_number(global_object)));
 
-    // 6. If Type(x) is String and Type(y) is Number, return IsLooselyEqual(! ToNumber(x), y).
+    // 6. If Type(x) is String and Type(y) is Number, return ! IsLooselyEqual(! ToNumber(x), y).
     if (lhs.is_string() && rhs.is_number())
         return is_loosely_equal(global_object, MUST(lhs.to_number(global_object)), rhs);
 
     // 7. If Type(x) is BigInt and Type(y) is String, then
     if (lhs.is_bigint() && rhs.is_string()) {
-        // a. Let n be ! StringToBigInt(y).
+        // a. Let n be StringToBigInt(y).
         auto bigint = rhs.string_to_bigint(global_object);
 
         // b. If n is undefined, return false.
         if (!bigint.has_value())
             return false;
 
-        // c. Return IsLooselyEqual(x, n).
+        // c. Return ! IsLooselyEqual(x, n).
         return is_loosely_equal(global_object, lhs, *bigint);
     }
 
-    // 8. If Type(x) is String and Type(y) is BigInt, return IsLooselyEqual(y, x).
+    // 8. If Type(x) is String and Type(y) is BigInt, return ! IsLooselyEqual(y, x).
     if (lhs.is_string() && rhs.is_bigint())
         return is_loosely_equal(global_object, rhs, lhs);
 
-    // 9. If Type(x) is Boolean, return IsLooselyEqual(! ToNumber(x), y).
+    // 9. If Type(x) is Boolean, return ! IsLooselyEqual(! ToNumber(x), y).
     if (lhs.is_boolean())
         return is_loosely_equal(global_object, MUST(lhs.to_number(global_object)), rhs);
 
-    // 10. If Type(y) is Boolean, return IsLooselyEqual(x, ! ToNumber(y)).
+    // 10. If Type(y) is Boolean, return ! IsLooselyEqual(x, ! ToNumber(y)).
     if (rhs.is_boolean())
         return is_loosely_equal(global_object, lhs, MUST(rhs.to_number(global_object)));
 
-    // 11. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return IsLooselyEqual(x, ? ToPrimitive(y)).
+    // 11. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)).
     if ((lhs.is_string() || lhs.is_number() || lhs.is_bigint() || lhs.is_symbol()) && rhs.is_object()) {
         auto rhs_primitive = TRY(rhs.to_primitive(global_object));
         return is_loosely_equal(global_object, lhs, rhs_primitive);
     }
 
-    // 12. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return IsLooselyEqual(? ToPrimitive(x), y).
+    // 12. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return ! IsLooselyEqual(? ToPrimitive(x), y).
     if (lhs.is_object() && (rhs.is_string() || rhs.is_number() || rhs.is_bigint() || rhs.is_symbol())) {
         auto lhs_primitive = TRY(lhs.to_primitive(global_object));
         return is_loosely_equal(global_object, lhs_primitive, rhs);

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

@@ -16,7 +16,7 @@ ThrowCompletionOr<WrappedFunction*> WrappedFunction::create(GlobalObject& global
     auto& vm = global_object.vm();
 
     // 1. Let internalSlotsList be the internal slots listed in Table 2, plus [[Prototype]] and [[Extensible]].
-    // 2. Let wrapped be ! MakeBasicObject(internalSlotsList).
+    // 2. Let wrapped be MakeBasicObject(internalSlotsList).
     // 3. Set wrapped.[[Prototype]] to callerRealm.[[Intrinsics]].[[%Function.prototype%]].
     // 4. Set wrapped.[[Call]] as described in 2.1.
     // 5. Set wrapped.[[WrappedTargetFunction]] to Target.

+ 24 - 27
Userland/Libraries/LibJS/SourceTextModule.cpp

@@ -303,7 +303,7 @@ ThrowCompletionOr<Vector<FlyString>> SourceTextModule::get_exported_names(VM& vm
 }
 
 // 16.2.1.6.4 InitializeEnvironment ( ), https://tc39.es/ecma262/#sec-source-text-module-record-initialize-environment
-Completion SourceTextModule::initialize_environment(VM& vm)
+ThrowCompletionOr<void> SourceTextModule::initialize_environment(VM& vm)
 {
     // 1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
     for (auto& entry : m_indirect_export_entries) {
@@ -347,8 +347,8 @@ Completion SourceTextModule::initialize_environment(VM& vm)
             // ii. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
             MUST(environment->create_immutable_binding(global_object, import_entry.local_name, true));
 
-            // iii. Call env.InitializeBinding(in.[[LocalName]], namespace).
-            environment->initialize_binding(global_object, import_entry.local_name, namespace_);
+            // iii. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
+            MUST(environment->initialize_binding(global_object, import_entry.local_name, namespace_));
         }
         // d. Else,
         else {
@@ -367,12 +367,12 @@ Completion SourceTextModule::initialize_environment(VM& vm)
                 // 2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
                 MUST(environment->create_immutable_binding(global_object, import_entry.local_name, true));
 
-                // 3. Call env.InitializeBinding(in.[[LocalName]], namespace).
+                // 3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
                 MUST(environment->initialize_binding(global_object, import_entry.local_name, namespace_));
             }
             // iv. Else,
             else {
-                // 1. Call env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
+                // 1. Perform env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
                 MUST(environment->create_import_binding(import_entry.local_name, resolution.module, resolution.export_name));
             }
         }
@@ -422,7 +422,7 @@ Completion SourceTextModule::initialize_environment(VM& vm)
             // 1. Perform ! env.CreateMutableBinding(dn, false).
             MUST(environment->create_mutable_binding(global_object, name, false));
 
-            // 2. Call env.InitializeBinding(dn, undefined).
+            // 2. Perform ! env.InitializeBinding(dn, undefined).
             MUST(environment->initialize_binding(global_object, name, js_undefined()));
 
             // 3. Append dn to declaredVarNames.
@@ -459,8 +459,8 @@ Completion SourceTextModule::initialize_environment(VM& vm)
                 // 1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
                 auto* function = ECMAScriptFunctionObject::create(global_object, function_declaration.name(), function_declaration.source_text(), function_declaration.body(), function_declaration.parameters(), function_declaration.function_length(), environment, private_environment, function_declaration.kind(), function_declaration.is_strict_mode(), function_declaration.might_need_arguments_object(), function_declaration.contains_direct_call_to_eval());
 
-                // 2. Call env.InitializeBinding(dn, fo).
-                environment->initialize_binding(global_object, name, function);
+                // 2. Perform ! env.InitializeBinding(dn, fo).
+                MUST(environment->initialize_binding(global_object, name, function));
             }
         });
     });
@@ -488,8 +488,8 @@ Completion SourceTextModule::initialize_environment(VM& vm)
     // 25. Remove moduleContext from the execution context stack.
     vm.pop_execution_context();
 
-    // 26. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 26. Return unused.
+    return {};
 }
 
 // 16.2.1.6.3 ResolveExport ( exportName [ , resolveSet ] ), https://tc39.es/ecma262/#sec-resolveexport
@@ -555,7 +555,7 @@ ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, FlyS
             // 1. Assert: module imports a specific binding for this export.
             // FIXME: What does this mean? / How do we check this
 
-            // 2. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet).
+            // 2. Return ? importedModule.ResolveExport(e.[[ImportName]], resolveSet).
             return imported_module->resolve_export(vm, entry.local_or_import_name, resolve_set);
         }
     }
@@ -622,7 +622,7 @@ ThrowCompletionOr<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, FlyS
 }
 
 // 16.2.1.6.5 ExecuteModule ( [ capability ] ), https://tc39.es/ecma262/#sec-source-text-module-record-execute-module
-Completion SourceTextModule::execute_module(VM& vm, Optional<PromiseCapability> capability)
+ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, Optional<PromiseCapability> capability)
 {
     dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] SourceTextModule::execute_module({}, capability has value: {})", filename(), capability.has_value());
 
@@ -668,26 +668,23 @@ Completion SourceTextModule::execute_module(VM& vm, Optional<PromiseCapability>
         // e. Resume the context that is now on the top of the execution context stack as the running execution context.
         // FIXME: We don't have resume yet.
 
-        // f. Return Completion(result).
-        if (result.is_error())
+        // f. If result is an abrupt completion, then
+        if (result.is_error()) {
+            // i. Return ? result.
             return result;
-
-        // 16.2.1.11 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-module-semantics-runtime-semantics-evaluation
-        // -> Replace any empty value with undefined.
-
-        result = result.update_empty(js_undefined());
-        return *result.value();
+        }
     }
     // 10. Else,
+    else {
+        // a. Assert: capability is a PromiseCapability Record.
+        VERIFY(capability.has_value());
 
-    // a. Assert: capability is a PromiseCapability Record.
-    VERIFY(capability.has_value());
-
-    // b. Perform ! AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
-    async_block_start(vm, m_ecmascript_code, capability.value(), module_context);
+        // b. Perform AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
+        async_block_start(vm, m_ecmascript_code, capability.value(), module_context);
+    }
 
-    // c. Return NormalCompletion(empty).
-    return normal_completion({});
+    // 11. Return unused.
+    return {};
 }
 
 }

+ 2 - 2
Userland/Libraries/LibJS/SourceTextModule.h

@@ -40,8 +40,8 @@ public:
     }
 
 protected:
-    virtual Completion initialize_environment(VM& vm) override;
-    virtual Completion execute_module(VM& vm, Optional<PromiseCapability> capability) override;
+    virtual ThrowCompletionOr<void> initialize_environment(VM& vm) override;
+    virtual ThrowCompletionOr<void> execute_module(VM& vm, Optional<PromiseCapability> capability) override;
 
 private:
     SourceTextModule(Realm&, StringView filename, bool has_top_level_await, NonnullRefPtr<Program> body, Vector<ModuleRequest> requested_modules,

+ 1 - 2
Userland/Libraries/LibJS/SyntheticModule.cpp

@@ -67,8 +67,7 @@ ThrowCompletionOr<void> SyntheticModule::link(VM& vm)
         environment->initialize_binding(global_object, export_name, js_undefined());
     }
 
-    // 6. Return undefined.
-    // Note: This return value is never visible to the outside so we use void.
+    // 6. Return unused.
     return {};
 }