diff options
author | Linus Groh <mail@linusgroh.de> | 2022-05-02 20:54:39 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-05-03 01:09:29 +0200 |
commit | 9f3f3b0864009b20a9cd02d303aa04b18bdca113 (patch) | |
tree | a9550c3806fac82e345e4a78f520b163b4561ee9 /Userland | |
parent | 15f32379bb399e0a8b2928a8de07cd070fb73ee5 (diff) | |
download | serenity-9f3f3b0864009b20a9cd02d303aa04b18bdca113.zip |
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
Diffstat (limited to 'Userland')
87 files changed, 789 insertions, 733 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index afe61b6a2a..5bcc92e623 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 84675c3a6a..f35c25bfa8 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/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(); }); } diff --git a/Userland/Libraries/LibJS/Contrib/Test262/$262Object.cpp b/Userland/Libraries/LibJS/Contrib/Test262/$262Object.cpp index 8975b27b4f..183dae07c4 100644 --- a/Userland/Libraries/LibJS/Contrib/Test262/$262Object.cpp +++ b/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) diff --git a/Userland/Libraries/LibJS/CyclicModule.cpp b/Userland/Libraries/LibJS/CyclicModule.cpp index aebb290b9e..7320477782 100644 --- a/Userland/Libraries/LibJS/CyclicModule.cpp +++ b/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. } } diff --git a/Userland/Libraries/LibJS/CyclicModule.h b/Userland/Libraries/LibJS/CyclicModule.h index 5d87aa1958..2f66b5d977 100644 --- a/Userland/Libraries/LibJS/CyclicModule.h +++ b/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]] diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index 3e91438b25..6089bd88e4 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/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(); diff --git a/Userland/Libraries/LibJS/Interpreter.h b/Userland/Libraries/LibJS/Interpreter.h index f66e302164..c8e5eed82d 100644 --- a/Userland/Libraries/LibJS/Interpreter.h +++ b/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; } diff --git a/Userland/Libraries/LibJS/Module.cpp b/Userland/Libraries/LibJS/Module.cpp index cefabe18fb..92d5db9b21 100644 --- a/Userland/Libraries/LibJS/Module.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index b81e24707b..fdc034aca0 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/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> { diff --git a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp index 7184cd017f..73c364744c 100644 --- a/Userland/Libraries/LibJS/Runtime/AggregateErrorConstructor.cpp +++ b/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))); diff --git a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp index 14e3605067..3a8be5b28c 100644 --- a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp +++ b/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)); } } diff --git a/Userland/Libraries/LibJS/Runtime/Array.cpp b/Userland/Libraries/LibJS/Runtime/Array.cpp index 56ce0c9332..20a36917fe 100644 --- a/Userland/Libraries/LibJS/Runtime/Array.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp index a477113dd2..1c60b1f675 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h index f64a25b7ca..6dd93aecb7 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 756540e90e..a648df772e 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/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 }. diff --git a/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp index 3f4c1a7ae1..09832934a2 100644 --- a/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.h b/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.h index c9c1fa1c0f..fa4fada97b 100644 --- a/Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.h +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp b/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp index 3a0bb7d368..5838ae9bb4 100644 --- a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp index d13f9bf288..d4862d1783 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Completion.cpp b/Userland/Libraries/LibJS/Runtime/Completion.cpp index c6548eaf09..3683391d47 100644 --- a/Userland/Libraries/LibJS/Runtime/Completion.cpp +++ b/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(); diff --git a/Userland/Libraries/LibJS/Runtime/Completion.h b/Userland/Libraries/LibJS/Runtime/Completion.h index c9f3c29e96..dc7b607ef5 100644 --- a/Userland/Libraries/LibJS/Runtime/Completion.h +++ b/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; diff --git a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp b/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp index 76ddaa8064..739144f0ec 100644 --- a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp index 8fbefbecb5..4591d3e6c3 100644 --- a/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironment.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index f81d29d108..4fcaa64458 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/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 })); } } diff --git a/Userland/Libraries/LibJS/Runtime/Error.cpp b/Userland/Libraries/LibJS/Runtime/Error.cpp index 919b2ba34d..362ce994e9 100644 --- a/Userland/Libraries/LibJS/Runtime/Error.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp index 5b6da08c72..900c8c4a2d 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/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). */ \ diff --git a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp b/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp index 7651f5999e..2f35131b30 100644 --- a/Userland/Libraries/LibJS/Runtime/FinalizationRegistry.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp index 123e6f21d1..0b4ef3912e 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/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). diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp index cc36c618bd..c7f2d2999b 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.cpp +++ b/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. } } diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp index 78c4c063bf..e1fbd55190 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/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()); } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp index a33fdf4ff1..dfa52dac16 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 1ce4a036e7..c15aaa35ed 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/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) diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 711992647a..4c2f91a256 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/CollatorConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/CollatorConstructor.cpp index 2e04af6ebd..e31de7272c 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/CollatorConstructor.cpp +++ b/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))); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp index 0c8295e023..1e35df850a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/CollatorPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp index 93e13dbddb..38456ff04b 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp +++ b/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]]). diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp index b1a92f0eda..4fe76eb643 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp index f29530bf0c..1ce7e148ce 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DisplayNamesPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp index ec5193872c..82f4d7e0b5 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Intl.cpp +++ b/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); }); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp index 21b8bee773..794e703eca 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp +++ b/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]]). diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp index a3101d5b2d..bb70267767 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp index c3a818b79f..2b9e2647b6 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/LocaleConstructor.cpp +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index 6d887887ab..1b38a9807b 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/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]]). diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp index 191fd47c89..9f9d4771aa 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp index 0e73d7e568..40a7de57e4 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp index 354e4afb52..1bbf45be2a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp +++ b/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]]). diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp index 063d4ea964..d02702ba27 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormatPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp b/Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp index ff67e68dba..1e9e4f4ebb 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp index 079874d437..80bb094283 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/SegmentIteratorPrototype.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Segmenter.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Segmenter.cpp index 3bccf69645..5acd0e6dfd 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Segmenter.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp index 2dd67d0cb7..9c92823b6d 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/SegmenterPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp b/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp index dd53cc3d27..8771718a1c 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp index 36b2197898..aacc2edf4c 100644 --- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp +++ b/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). diff --git a/Userland/Libraries/LibJS/Runtime/ModuleEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/ModuleEnvironment.cpp index bcfd09cda4..4135a13124 100644 --- a/Userland/Libraries/LibJS/Runtime/ModuleEnvironment.cpp +++ b/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 {}; } diff --git a/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp b/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp index 91ec15c17d..8aaff376a2 100644 --- a/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index 978095470e..c18831df73 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/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; } diff --git a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp index e59b4d6bc4..a033c59120 100644 --- a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/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))); diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index 32810d33d4..2efaa9b8d4 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 1827df89f2..6876bd8d1a 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index a74abf48bf..92f59c6db1 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp index 4df0e07b9d..3fa519af7c 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/Promise.cpp b/Userland/Libraries/LibJS/Runtime/Promise.cpp index 6770a95170..c6a5a9fcaa 100644 --- a/Userland/Libraries/LibJS/Runtime/Promise.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/Promise.h b/Userland/Libraries/LibJS/Runtime/Promise.h index ca29dde6d7..3bc704cf4d 100644 --- a/Userland/Libraries/LibJS/Runtime/Promise.h +++ b/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; } diff --git a/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp b/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp index 16c18b6aaf..08d66bb54f 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp b/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp index ca59ef716b..4d0eaa979a 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp +++ b/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(); diff --git a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp b/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp index bbda6ff8f7..739715e832 100644 --- a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp +++ b/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, ""); } diff --git a/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp b/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp index 436e6cabad..6d6d2d51af 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseReaction.cpp +++ b/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 »). diff --git a/Userland/Libraries/LibJS/Runtime/PromiseReaction.h b/Userland/Libraries/LibJS/Runtime/PromiseReaction.h index bafd443ed5..86341473b5 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseReaction.h +++ b/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) \ ({ \ diff --git a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp b/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp index ec58b56532..f8afad6a1f 100644 --- a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp +++ b/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 })); diff --git a/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp b/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp index 1a93267bdc..fcdbb36b59 100644 --- a/Userland/Libraries/LibJS/Runtime/PropertyDescriptor.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/Runtime/ProxyConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ProxyConstructor.cpp index 8f5c6f607a..89c8bd7c1e 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyConstructor.cpp +++ b/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). diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 1bf50ed0e8..b000b35ed5 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/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 »). diff --git a/Userland/Libraries/LibJS/Runtime/Realm.cpp b/Userland/Libraries/LibJS/Runtime/Realm.cpp index 4f73ab44a3..35c8faa3e6 100644 --- a/Userland/Libraries/LibJS/Runtime/Realm.cpp +++ b/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) diff --git a/Userland/Libraries/LibJS/Runtime/Reference.cpp b/Userland/Libraries/LibJS/Runtime/Reference.cpp index 7edaea7ea4..1c31fd5cd6 100644 --- a/Userland/Libraries/LibJS/Runtime/Reference.cpp +++ b/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 }. diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index f7dfe18bfe..4f5ce2c2c3 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/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). diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp index 97aa9185a7..d06eef543d 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.cpp b/Userland/Libraries/LibJS/Runtime/StringObject.cpp index 8a9f1a9b86..696bca6e40 100644 --- a/Userland/Libraries/LibJS/Runtime/StringObject.cpp +++ b/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); } diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 97d9e7667b..396ca4897d 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/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; } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index fc12c82877..ca81edccdc 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/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; diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp index a6f014319f..96937dac36 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp +++ b/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; } diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index fd78a0f7fa..ba30a5d33b 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/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 diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index a4a038ce13..7752f29674 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/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. } } diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 50aed9af35..f02fa9009f 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp b/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp index d15269de49..c054e0e3b3 100644 --- a/Userland/Libraries/LibJS/Runtime/WrappedFunction.cpp +++ b/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. diff --git a/Userland/Libraries/LibJS/SourceTextModule.cpp b/Userland/Libraries/LibJS/SourceTextModule.cpp index ba9197d6a1..7bf4e9c678 100644 --- a/Userland/Libraries/LibJS/SourceTextModule.cpp +++ b/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 {}; } } diff --git a/Userland/Libraries/LibJS/SourceTextModule.h b/Userland/Libraries/LibJS/SourceTextModule.h index 302e9f8019..27c4f1065c 100644 --- a/Userland/Libraries/LibJS/SourceTextModule.h +++ b/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, diff --git a/Userland/Libraries/LibJS/SyntheticModule.cpp b/Userland/Libraries/LibJS/SyntheticModule.cpp index 6287dd9caf..bc64da9cee 100644 --- a/Userland/Libraries/LibJS/SyntheticModule.cpp +++ b/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 {}; } |