From c1998f96c29f04cdad822e14867c3a7ffb6cf4b3 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sun, 3 Nov 2024 20:18:56 +1300 Subject: [PATCH] LibJS: Update HostEnsureCanCompileStrings arguments to latest spec --- .../Libraries/LibJS/Runtime/AbstractOperations.cpp | 7 +++---- Userland/Libraries/LibJS/Runtime/AbstractOperations.h | 6 ++---- .../Libraries/LibJS/Runtime/FunctionConstructor.cpp | 4 ++-- Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp | 5 ++--- Userland/Libraries/LibJS/Runtime/VM.cpp | 10 ++++++---- Userland/Libraries/LibJS/Runtime/VM.h | 7 ++++++- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index 7c059f550c4..bfca98a3242 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -511,13 +511,14 @@ ThrowCompletionOr perform_eval(VM& vm, Value x, CallerMode strict_caller, // 2. If Type(x) is not String, return x. if (!x.is_string()) return x; + auto& code_string = x.as_string(); // 3. Let evalRealm be the current Realm Record. auto& eval_realm = *vm.running_execution_context().realm; // 4. NOTE: In the case of a direct eval, evalRealm is the realm of both the caller of eval and of the eval function itself. - // 5. Perform ? HostEnsureCanCompileStrings(evalRealm). - TRY(vm.host_ensure_can_compile_strings(eval_realm)); + // 5. Perform ? HostEnsureCanCompileStrings(evalRealm, « », x, direct). + TRY(vm.host_ensure_can_compile_strings(eval_realm, {}, code_string.utf8_string_view(), direct)); // 6. Let inFunction be false. bool in_function = false; @@ -571,8 +572,6 @@ ThrowCompletionOr perform_eval(VM& vm, Value x, CallerMode strict_caller, // f. If inMethod is false, and body Contains SuperProperty, throw a SyntaxError exception. // g. If inDerivedConstructor is false, and body Contains SuperCall, throw a SyntaxError exception. // h. If inClassFieldInitializer is true, and ContainsArguments of body is true, throw a SyntaxError exception. - auto& code_string = x.as_string(); - Parser::EvalInitialState initial_state { .in_eval_function_context = in_function, .allow_super_property_lookup = in_method, diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index 38be85f9057..63ad0c8bd2b 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace JS { @@ -67,10 +68,7 @@ enum class CallerMode { Strict, NonStrict }; -enum class EvalMode { - Direct, - Indirect -}; + ThrowCompletionOr perform_eval(VM&, Value, CallerMode, EvalMode); ThrowCompletionOr eval_declaration_instantiation(VM& vm, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict); diff --git a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp index 94bb6ed42c4..fde9ae87125 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -142,8 +142,8 @@ ThrowCompletionOr> FunctionConstructor::c // 10. Let currentRealm be the current Realm Record. auto& realm = *vm.current_realm(); - // FIXME: 11. Perform ? HostEnsureCanCompileStrings(currentRealm, parameterStrings, bodyString, false). - TRY(vm.host_ensure_can_compile_strings(current_realm)); + // 11. Perform ? HostEnsureCanCompileStrings(currentRealm, parameterStrings, bodyString, false). + TRY(vm.host_ensure_can_compile_strings(realm, parameter_strings, body_string, EvalMode::Indirect)); // 12. Let P be the empty String. String parameters_string; diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp index 4326e75b2b4..9f25afc64e0 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -95,9 +95,8 @@ ThrowCompletionOr copy_name_and_length(VM& vm, FunctionObject& function, F // 3.1.3 PerformShadowRealmEval ( sourceText: a String, callerRealm: a Realm Record, evalRealm: a Realm Record, ), https://tc39.es/proposal-shadowrealm/#sec-performshadowrealmeval ThrowCompletionOr perform_shadow_realm_eval(VM& vm, StringView source_text, Realm& caller_realm, Realm& eval_realm) { - // FIXME: Needs to be updated to latest ECMA-262. See: https://github.com/tc39/proposal-shadowrealm/issues/367 - // 1. Perform ? HostEnsureCanCompileStrings(callerRealm, evalRealm). - TRY(vm.host_ensure_can_compile_strings(eval_realm)); + // 1. Perform ? HostEnsureCanCompileStrings(evalRealm, « », sourceText, false). + TRY(vm.host_ensure_can_compile_strings(eval_realm, {}, source_text, EvalMode::Indirect)); // 2. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection: diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index d32a197ac79..d452ed99588 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -120,10 +120,12 @@ VM::VM(OwnPtr custom_data, ErrorMessages error_messages) return Vector { "type" }; }; - // 19.2.1.2 HostEnsureCanCompileStrings ( callerRealm, calleeRealm ), https://tc39.es/ecma262/#sec-hostensurecancompilestrings - host_ensure_can_compile_strings = [](Realm&) -> ThrowCompletionOr { - // The host-defined abstract operation HostEnsureCanCompileStrings takes argument calleeRealm (a Realm Record) - // and returns either a normal completion containing unused or a throw completion. + // 19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm, parameterStrings, bodyString, direct ), https://tc39.es/ecma262/#sec-hostensurecancompilestrings + host_ensure_can_compile_strings = [](Realm&, ReadonlySpan, StringView, EvalMode) -> ThrowCompletionOr { + // The host-defined abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (a Realm Record), + // parameterStrings (a List of Strings), bodyString (a String), and direct (a Boolean) and returns either a normal + // completion containing unused or a throw completion. + // // It allows host environments to block certain ECMAScript functions which allow developers to compile strings into ECMAScript code. // An implementation of HostEnsureCanCompileStrings must conform to the following requirements: // - If the returned Completion Record is a normal completion, it must be a normal completion containing unused. diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 373b67e6449..fb8109af03e 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -37,6 +37,11 @@ enum class HandledByHost { Unhandled, }; +enum class EvalMode { + Direct, + Indirect +}; + class VM : public RefCounted { public: struct CustomData { @@ -276,7 +281,7 @@ public: Function host_enqueue_finalization_registry_cleanup_job; Function()>>, Realm*)> host_enqueue_promise_job; Function(FunctionObject&)> host_make_job_callback; - Function(Realm&)> host_ensure_can_compile_strings; + Function(Realm&, ReadonlySpan, StringView, EvalMode)> host_ensure_can_compile_strings; Function(Object&)> host_ensure_can_add_private_element; Function(ArrayBuffer&, size_t)> host_resize_array_buffer; Function host_unrecognized_date_string;