LibJS: Remove callerRealm from HostEnsureCanCompileStrings
This is a normative change in the ecma262 spec. See: https://github.com/tc39/ecma262/commit/2527be4
This commit is contained in:
parent
a0a4d169f4
commit
77ba3d3e3f
Notes:
sideshowbarker
2024-07-17 11:08:16 +09:00
Author: https://github.com/Lubrsi Commit: https://github.com/SerenityOS/serenity/commit/77ba3d3e3f Pull-request: https://github.com/SerenityOS/serenity/pull/13773 Reviewed-by: https://github.com/linusg ✅
7 changed files with 79 additions and 87 deletions
|
@ -432,7 +432,7 @@ Completion CallExpression::execute(Interpreter& interpreter, GlobalObject& globa
|
|||
&& callee_reference.name().as_string() == vm.names.eval.as_string()) {
|
||||
|
||||
auto script_value = arg_list.size() == 0 ? js_undefined() : arg_list[0];
|
||||
return perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct);
|
||||
return perform_eval(global_object, script_value, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct);
|
||||
}
|
||||
|
||||
return call(global_object, function, this_value, move(arg_list));
|
||||
|
|
|
@ -490,8 +490,8 @@ ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject& global_
|
|||
return Reference { bv, property_key, actual_this, strict };
|
||||
}
|
||||
|
||||
// 19.2.1.1 PerformEval ( x, callerRealm, strictCaller, direct ), https://tc39.es/ecma262/#sec-performeval
|
||||
ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller, EvalMode direct)
|
||||
// 19.2.1.1 PerformEval ( x, strictCaller, direct ), https://tc39.es/ecma262/#sec-performeval
|
||||
ThrowCompletionOr<Value> perform_eval(GlobalObject& global_object, Value x, CallerMode strict_caller, EvalMode direct)
|
||||
{
|
||||
// 1. Assert: If direct is false, then strictCaller is also false.
|
||||
VERIFY(direct == EvalMode::Direct || strict_caller == CallerMode::NonStrict);
|
||||
|
@ -500,27 +500,28 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
if (!x.is_string())
|
||||
return x;
|
||||
|
||||
auto& vm = caller_realm.vm();
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 3. Let evalRealm be the current Realm Record.
|
||||
auto& eval_realm = *vm.running_execution_context().realm;
|
||||
|
||||
// 4. Perform ? HostEnsureCanCompileStrings(callerRealm, evalRealm).
|
||||
TRY(vm.host_ensure_can_compile_strings(*caller_realm.associated_realm(), eval_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. Let inFunction be false.
|
||||
// 6. Let inFunction be false.
|
||||
bool in_function = false;
|
||||
|
||||
// 6. Let inMethod be false.
|
||||
// 7. Let inMethod be false.
|
||||
bool in_method = false;
|
||||
|
||||
// 7. Let inDerivedConstructor be false.
|
||||
// 8. Let inDerivedConstructor be false.
|
||||
bool in_derived_constructor = false;
|
||||
|
||||
// 8. Let inClassFieldInitializer be false.
|
||||
// 9. Let inClassFieldInitializer be false.
|
||||
bool in_class_field_initializer = false;
|
||||
|
||||
// 9. If direct is true, then
|
||||
// 10. If direct is true, then
|
||||
if (direct == EvalMode::Direct) {
|
||||
// a. Let thisEnvRec be GetThisEnvironment().
|
||||
auto& this_environment_record = get_this_environment(vm);
|
||||
|
@ -551,7 +552,7 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
}
|
||||
}
|
||||
|
||||
// 10. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
|
||||
// 11. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
|
||||
// a. Let script be ParseText(StringToCodePoints(x), Script).
|
||||
// c. If script Contains ScriptBody is false, return undefined.
|
||||
// d. Let body be the ScriptBody of script.
|
||||
|
@ -575,22 +576,22 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
// b. If script is a List of errors, throw a SyntaxError exception.
|
||||
if (parser.has_errors()) {
|
||||
auto& error = parser.errors()[0];
|
||||
return vm.throw_completion<SyntaxError>(caller_realm, error.to_string());
|
||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
||||
}
|
||||
|
||||
auto strict_eval = strict_caller == CallerMode::Strict;
|
||||
if (program->is_strict_mode())
|
||||
strict_eval = true;
|
||||
|
||||
// 13. Let runningContext be the running execution context.
|
||||
// 14. NOTE: If direct is true, runningContext will be the execution context that performed the direct eval. If direct is false, runningContext will be the execution context for the invocation of the eval function.
|
||||
// 14. Let runningContext be the running execution context.
|
||||
// 15. NOTE: If direct is true, runningContext will be the execution context that performed the direct eval. If direct is false, runningContext will be the execution context for the invocation of the eval function.
|
||||
auto& running_context = vm.running_execution_context();
|
||||
|
||||
Environment* lexical_environment;
|
||||
Environment* variable_environment;
|
||||
PrivateEnvironment* private_environment;
|
||||
|
||||
// 15. If direct is true, then
|
||||
// 16. If direct is true, then
|
||||
if (direct == EvalMode::Direct) {
|
||||
// a. Let lexEnv be NewDeclarativeEnvironment(runningContext's LexicalEnvironment).
|
||||
lexical_environment = new_declarative_environment(*running_context.lexical_environment);
|
||||
|
@ -601,7 +602,7 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
// c. Let privateEnv be runningContext's PrivateEnvironment.
|
||||
private_environment = running_context.private_environment;
|
||||
}
|
||||
// 16. Else,
|
||||
// 17. Else,
|
||||
else {
|
||||
// a. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
|
||||
lexical_environment = new_declarative_environment(eval_realm.global_environment());
|
||||
|
@ -613,7 +614,7 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
private_environment = nullptr;
|
||||
}
|
||||
|
||||
// 17. If strictEval is true, set varEnv to lexEnv.
|
||||
// 18. If strictEval is true, set varEnv to lexEnv.
|
||||
if (strict_eval)
|
||||
variable_environment = lexical_environment;
|
||||
|
||||
|
@ -624,50 +625,50 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
variable_environment->set_permanently_screwed_by_eval();
|
||||
}
|
||||
|
||||
// 18. If runningContext is not already suspended, suspend runningContext.
|
||||
// 19. If runningContext is not already suspended, suspend runningContext.
|
||||
// FIXME: We don't have this concept yet.
|
||||
|
||||
// 19. Let evalContext be a new ECMAScript code execution context.
|
||||
// 20. Let evalContext be a new ECMAScript code execution context.
|
||||
ExecutionContext eval_context(vm.heap());
|
||||
|
||||
// 20. Set evalContext's Function to null.
|
||||
// 21. Set evalContext's Function to null.
|
||||
// NOTE: This was done in the construction of eval_context.
|
||||
|
||||
// 21. Set evalContext's Realm to evalRealm.
|
||||
// 22. Set evalContext's Realm to evalRealm.
|
||||
eval_context.realm = &eval_realm;
|
||||
|
||||
// 22. Set evalContext's ScriptOrModule to runningContext's ScriptOrModule.
|
||||
// 23. Set evalContext's ScriptOrModule to runningContext's ScriptOrModule.
|
||||
eval_context.script_or_module = running_context.script_or_module;
|
||||
|
||||
// 23. Set evalContext's VariableEnvironment to varEnv.
|
||||
// 24. Set evalContext's VariableEnvironment to varEnv.
|
||||
eval_context.variable_environment = variable_environment;
|
||||
|
||||
// 24. Set evalContext's LexicalEnvironment to lexEnv.
|
||||
// 25. Set evalContext's LexicalEnvironment to lexEnv.
|
||||
eval_context.lexical_environment = lexical_environment;
|
||||
|
||||
// 25. Set evalContext's PrivateEnvironment to privateEnv.
|
||||
// 26. Set evalContext's PrivateEnvironment to privateEnv.
|
||||
eval_context.private_environment = private_environment;
|
||||
|
||||
// NOTE: This isn't in the spec, but we require it.
|
||||
eval_context.is_strict_mode = strict_eval;
|
||||
|
||||
// 26. Push evalContext onto the execution context stack; evalContext is now the running execution context.
|
||||
// 27. 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()));
|
||||
|
||||
// NOTE: We use a ScopeGuard to automatically pop the execution context when any of the `TRY`s below return a throw completion.
|
||||
ScopeGuard pop_guard = [&] {
|
||||
// FIXME: 30. Suspend evalContext and remove it from the execution context stack.
|
||||
// FIXME: 31. Suspend evalContext and remove it from the execution context stack.
|
||||
|
||||
// 31. Resume the context that is now on the top of the execution context stack as the running execution context.
|
||||
// 32. Resume the context that is now on the top of the execution context stack as the running execution context.
|
||||
vm.pop_execution_context();
|
||||
};
|
||||
|
||||
// 27. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)).
|
||||
// 28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)).
|
||||
TRY(eval_declaration_instantiation(vm, eval_realm.global_object(), program, variable_environment, lexical_environment, private_environment, strict_eval));
|
||||
|
||||
Optional<Value> eval_result;
|
||||
|
||||
// 28. If result.[[Type]] is normal, then
|
||||
// 29. If result.[[Type]] is normal, then
|
||||
// a. Set result to the result of evaluating body.
|
||||
if (auto* bytecode_interpreter = Bytecode::Interpreter::current()) {
|
||||
auto executable_result = Bytecode::Generator::generate(program);
|
||||
|
@ -684,14 +685,14 @@ ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, Calle
|
|||
eval_result = {};
|
||||
} else {
|
||||
auto& ast_interpreter = vm.interpreter();
|
||||
eval_result = TRY(program->execute(ast_interpreter, caller_realm));
|
||||
eval_result = TRY(program->execute(ast_interpreter, global_object));
|
||||
}
|
||||
|
||||
// 29. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
||||
// 30. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
||||
// a. Set result to NormalCompletion(undefined).
|
||||
// NOTE: Step 30 and 31 is handled by `pop_guard` above.
|
||||
// 32. Return ? result.
|
||||
// NOTE: Step 32 is also performed with each use of `TRY` above.
|
||||
// NOTE: Step 31 and 32 is handled by `pop_guard` above.
|
||||
// 33. Return ? result.
|
||||
// NOTE: Step 33 is also performed with each use of `TRY` above.
|
||||
return eval_result.value_or(js_undefined());
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ enum class EvalMode {
|
|||
Direct,
|
||||
Indirect
|
||||
};
|
||||
ThrowCompletionOr<Value> perform_eval(Value, GlobalObject&, CallerMode, EvalMode);
|
||||
ThrowCompletionOr<Value> perform_eval(GlobalObject&, Value, CallerMode, EvalMode);
|
||||
|
||||
ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& global_object, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict);
|
||||
|
||||
|
|
|
@ -40,22 +40,13 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. Assert: The execution context stack has at least two elements.
|
||||
VERIFY(vm.execution_context_stack().size() >= 2);
|
||||
// 1. Let currentRealm be the current Realm Record.
|
||||
auto& current_realm = *vm.running_execution_context().realm;
|
||||
|
||||
// 2. Let callerContext be the second to top element of the execution context stack.
|
||||
auto& caller_context = *vm.execution_context_stack().at(vm.execution_context_stack().size() - 2);
|
||||
// 2. Perform ? HostEnsureCanCompileStrings(currentRealm).
|
||||
TRY(vm.host_ensure_can_compile_strings(current_realm));
|
||||
|
||||
// 3. Let callerRealm be callerContext's Realm.
|
||||
auto& caller_realm = *caller_context.realm;
|
||||
|
||||
// 4. Let calleeRealm be the current Realm Record.
|
||||
auto& callee_realm = *vm.running_execution_context().realm;
|
||||
|
||||
// 5. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
|
||||
TRY(vm.host_ensure_can_compile_strings(caller_realm, callee_realm));
|
||||
|
||||
// 6. If newTarget is undefined, set newTarget to constructor.
|
||||
// 3. If newTarget is undefined, set newTarget to constructor.
|
||||
if (new_target == nullptr)
|
||||
new_target = &constructor;
|
||||
|
||||
|
@ -63,7 +54,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
Object* (GlobalObject::*fallback_prototype)() = nullptr;
|
||||
|
||||
switch (kind) {
|
||||
// 7. If kind is normal, then
|
||||
// 4. If kind is normal, then
|
||||
case FunctionKind::Normal:
|
||||
// a. Let prefix be "function".
|
||||
prefix = "function"sv;
|
||||
|
@ -76,7 +67,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
fallback_prototype = &GlobalObject::function_prototype;
|
||||
break;
|
||||
|
||||
// 8. Else if kind is generator, then
|
||||
// 5. Else if kind is generator, then
|
||||
case FunctionKind::Generator:
|
||||
// a. Let prefix be "function*".
|
||||
prefix = "function*"sv;
|
||||
|
@ -89,7 +80,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
fallback_prototype = &GlobalObject::generator_function_prototype;
|
||||
break;
|
||||
|
||||
// 9. Else if kind is async, then
|
||||
// 6. Else if kind is async, then
|
||||
case FunctionKind::Async:
|
||||
// a. Let prefix be "async function".
|
||||
prefix = "async function"sv;
|
||||
|
@ -102,7 +93,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
fallback_prototype = &GlobalObject::async_function_prototype;
|
||||
break;
|
||||
|
||||
// 10. Else,
|
||||
// 7. Else,
|
||||
case FunctionKind::AsyncGenerator:
|
||||
// a. Assert: kind is asyncGenerator.
|
||||
|
||||
|
@ -121,23 +112,23 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
// 11. Let argCount be the number of elements in args.
|
||||
// 8. Let argCount be the number of elements in args.
|
||||
auto arg_count = args.size();
|
||||
|
||||
// 12. Let P be the empty String.
|
||||
// 9. Let P be the empty String.
|
||||
String parameters_string = "";
|
||||
|
||||
Optional<Value> body_arg;
|
||||
|
||||
// 13. If argCount = 0, let bodyArg be the empty String.
|
||||
// 10. If argCount = 0, let bodyArg be the empty String.
|
||||
if (arg_count == 0) {
|
||||
// Optimization: Instead of creating a js_string() here, we just check if body_arg is empty in step 16.
|
||||
}
|
||||
// 14. Else if argCount = 1, let bodyArg be args[0].
|
||||
// 11. Else if argCount = 1, let bodyArg be args[0].
|
||||
else if (arg_count == 1) {
|
||||
body_arg = args[0];
|
||||
}
|
||||
// 15. Else,
|
||||
// 12. Else,
|
||||
else {
|
||||
// a. Assert: argCount > 1.
|
||||
VERIFY(arg_count > 1);
|
||||
|
@ -167,11 +158,11 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
body_arg = args[k];
|
||||
}
|
||||
|
||||
// 16. Let bodyString be the string-concatenation of 0x000A (LINE FEED), ? ToString(bodyArg), and 0x000A (LINE FEED).
|
||||
// 13. Let bodyString be the string-concatenation of 0x000A (LINE FEED), ? ToString(bodyArg), and 0x000A (LINE FEED).
|
||||
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).
|
||||
// 14. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyString, and "}".
|
||||
// 15. Let sourceText be StringToCodePoints(sourceString).
|
||||
auto source_text = String::formatted("{} anonymous({}\n) {{{}}}", prefix, parameters_string, body_string);
|
||||
|
||||
u8 parse_options = FunctionNodeParseOptions::CheckForFunctionAndName;
|
||||
|
@ -180,18 +171,18 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
if (kind == FunctionKind::Generator || kind == FunctionKind::AsyncGenerator)
|
||||
parse_options |= FunctionNodeParseOptions::IsGeneratorFunction;
|
||||
|
||||
// 19. Let parameters be ParseText(StringToCodePoints(P), parameterSym).
|
||||
// 16. 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);
|
||||
|
||||
// 20. If parameters is a List of errors, throw a SyntaxError exception.
|
||||
// 17. If parameters is a List of errors, throw a SyntaxError exception.
|
||||
if (parameters_parser.has_errors()) {
|
||||
auto error = parameters_parser.errors()[0];
|
||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
||||
}
|
||||
|
||||
// 21. Let body be ParseText(StringToCodePoints(bodyString), bodySym).
|
||||
// 18. 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.
|
||||
|
@ -202,45 +193,45 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
body_parser.m_state.in_generator_function_context = true;
|
||||
(void)body_parser.parse_function_body(parameters, kind, contains_direct_call_to_eval);
|
||||
|
||||
// 22. If body is a List of errors, throw a SyntaxError exception.
|
||||
// 19. If body is a List of errors, throw a SyntaxError exception.
|
||||
if (body_parser.has_errors()) {
|
||||
auto error = body_parser.errors()[0];
|
||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
||||
}
|
||||
|
||||
// 23. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") is not legal.
|
||||
// 24. NOTE: If this step is reached, sourceText must have the syntax of exprSym (although the reverse implication does not hold). The purpose of the next two steps is to enforce any Early Error rules which apply to exprSym directly.
|
||||
// 20. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") is not legal.
|
||||
// 21. NOTE: If this step is reached, sourceText must have the syntax of exprSym (although the reverse implication does not hold). The purpose of the next two steps is to enforce any Early Error rules which apply to exprSym directly.
|
||||
|
||||
// 25. Let expr be ParseText(sourceText, exprSym).
|
||||
// 22. Let expr be ParseText(sourceText, exprSym).
|
||||
auto source_parser = Parser { Lexer { source_text } };
|
||||
// This doesn't need any parse_options, it determines those & the function type based on the tokens that were found.
|
||||
auto expr = source_parser.parse_function_node<FunctionExpression>();
|
||||
|
||||
// 26. If expr is a List of errors, throw a SyntaxError exception.
|
||||
// 23. If expr is a List of errors, throw a SyntaxError exception.
|
||||
if (source_parser.has_errors()) {
|
||||
auto error = source_parser.errors()[0];
|
||||
return vm.throw_completion<SyntaxError>(global_object, error.to_string());
|
||||
}
|
||||
|
||||
// 27. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
|
||||
// 24. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
|
||||
auto* prototype = TRY(get_prototype_from_constructor(global_object, *new_target, fallback_prototype));
|
||||
|
||||
// 28. Let realmF be the current Realm Record.
|
||||
// 25. Let realmF be the current Realm Record.
|
||||
auto* realm = vm.current_realm();
|
||||
|
||||
// 29. Let env be realmF.[[GlobalEnv]].
|
||||
// 26. Let env be realmF.[[GlobalEnv]].
|
||||
auto* environment = &realm->global_environment();
|
||||
|
||||
// 30. Let privateEnv be null.
|
||||
// 27. Let privateEnv be null.
|
||||
PrivateEnvironment* private_environment = nullptr;
|
||||
|
||||
// 31. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
|
||||
// 28. 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.
|
||||
// 32. Perform SetFunctionName(F, "anonymous").
|
||||
// 29. Perform SetFunctionName(F, "anonymous").
|
||||
|
||||
// 33. If kind is generator, then
|
||||
// 30. If kind is generator, then
|
||||
if (kind == FunctionKind::Generator) {
|
||||
// a. Let prototype be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
|
||||
prototype = Object::create(global_object, global_object.generator_function_prototype_prototype());
|
||||
|
@ -248,7 +239,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
// 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
|
||||
// 31. Else if kind is asyncGenerator, then
|
||||
else if (kind == FunctionKind::AsyncGenerator) {
|
||||
// a. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
|
||||
prototype = Object::create(global_object, global_object.async_generator_function_prototype_prototype());
|
||||
|
@ -256,7 +247,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
// 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).
|
||||
// 32. Else if kind is normal, perform MakeConstructor(F).
|
||||
else if (kind == FunctionKind::Normal) {
|
||||
// FIXME: Implement MakeConstructor
|
||||
prototype = Object::create(global_object, global_object.object_prototype());
|
||||
|
@ -264,9 +255,9 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> FunctionConstructor::create_dynamic
|
|||
function->define_direct_property(vm.names.prototype, prototype, Attribute::Writable);
|
||||
}
|
||||
|
||||
// 36. NOTE: Functions whose kind is async are not constructible and do not have a [[Construct]] internal method or a "prototype" property.
|
||||
// 33. NOTE: Functions whose kind is async are not constructible and do not have a [[Construct]] internal method or a "prototype" property.
|
||||
|
||||
// 37. Return F.
|
||||
// 34. Return F.
|
||||
return function;
|
||||
}
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int)
|
|||
// 19.2.1 eval ( x ), https://tc39.es/ecma262/#sec-eval-x
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval)
|
||||
{
|
||||
return perform_eval(vm.argument(0), global_object, CallerMode::NonStrict, EvalMode::Indirect);
|
||||
return perform_eval(global_object, vm.argument(0), CallerMode::NonStrict, EvalMode::Indirect);
|
||||
}
|
||||
|
||||
// 19.2.6.1.1 Encode ( string, unescapedSet ), https://tc39.es/ecma262/#sec-encode
|
||||
|
|
|
@ -132,9 +132,9 @@ VM::VM(OwnPtr<CustomData> custom_data)
|
|||
};
|
||||
|
||||
// 19.2.1.2 HostEnsureCanCompileStrings ( callerRealm, calleeRealm ), https://tc39.es/ecma262/#sec-hostensurecancompilestrings
|
||||
host_ensure_can_compile_strings = [](Realm&, Realm&) -> ThrowCompletionOr<void> {
|
||||
// The host-defined abstract operation HostEnsureCanCompileStrings takes arguments callerRealm (a Realm Record) and calleeRealm (a Realm Record)
|
||||
// and returns either a normal completion containing unused or an abrupt completion.
|
||||
host_ensure_can_compile_strings = [](Realm&) -> ThrowCompletionOr<void> {
|
||||
// The host-defined abstract operation HostEnsureCanCompileStrings takes argument calleeRealm (a Realm Record)
|
||||
// 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.
|
||||
|
|
|
@ -234,7 +234,7 @@ public:
|
|||
Function<void(Function<ThrowCompletionOr<Value>()>, Realm*)> host_enqueue_promise_job;
|
||||
Function<JobCallback(FunctionObject&)> host_make_job_callback;
|
||||
Function<ThrowCompletionOr<HostResizeArrayBufferResult>(GlobalObject&, size_t)> host_resize_array_buffer;
|
||||
Function<ThrowCompletionOr<void>(Realm&, Realm&)> host_ensure_can_compile_strings;
|
||||
Function<ThrowCompletionOr<void>(Realm&)> host_ensure_can_compile_strings;
|
||||
|
||||
private:
|
||||
explicit VM(OwnPtr<CustomData>);
|
||||
|
|
Loading…
Add table
Reference in a new issue