From 1ee7e97e24fd1672a7ee8bd12abf36965da731ce Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 18 Jan 2022 23:47:11 +0000 Subject: LibJS: Pass source text to ECMAScriptFunctionObject::create() --- Userland/Libraries/LibJS/AST.cpp | 14 +++++++------- Userland/Libraries/LibJS/Bytecode/Op.cpp | 2 +- Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp | 2 +- .../Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp | 13 +++++++------ .../Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h | 10 +++++++--- Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp | 2 +- Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 2 +- 7 files changed, 25 insertions(+), 20 deletions(-) (limited to 'Userland') diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index ebad1acdca..fc26ad8b43 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -299,7 +299,7 @@ Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter& auto* private_scope = interpreter.vm().running_execution_context().private_environment; - auto closure = ECMAScriptFunctionObject::create(global_object, used_name, body(), parameters(), function_length(), scope, private_scope, kind(), is_strict_mode(), might_need_arguments_object(), contains_direct_call_to_eval(), is_arrow_function()); + auto closure = ECMAScriptFunctionObject::create(global_object, used_name, source_text(), body(), parameters(), function_length(), scope, private_scope, kind(), is_strict_mode(), might_need_arguments_object(), contains_direct_call_to_eval(), is_arrow_function()); // FIXME: 6. Perform SetFunctionName(closure, name). // FIXME: 7. Perform MakeConstructor(closure). @@ -1633,7 +1633,7 @@ ThrowCompletionOr ClassField::class_element_evaluation // FIXME: A potential optimization is not creating the functions here since these are never directly accessible. auto function_code = create_ast_node(m_initializer->source_range(), copy_initializer.release_nonnull(), name); - initializer = ECMAScriptFunctionObject::create(interpreter.global_object(), String::empty(), *function_code, {}, 0, interpreter.lexical_environment(), interpreter.vm().running_execution_context().private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false); + initializer = ECMAScriptFunctionObject::create(interpreter.global_object(), String::empty(), String::empty(), *function_code, {}, 0, interpreter.lexical_environment(), interpreter.vm().running_execution_context().private_environment, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false); initializer->make_method(target); } @@ -1675,7 +1675,7 @@ ThrowCompletionOr StaticInitializer::class_element_eva // 4. Let formalParameters be an instance of the production FormalParameters : [empty] . // 5. Let bodyFunction be OrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateScope). // Note: The function bodyFunction is never directly accessible to ECMAScript code. - auto* body_function = ECMAScriptFunctionObject::create(global_object, "", *m_function_body, {}, 0, lexical_environment, private_scope, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false); + auto* body_function = ECMAScriptFunctionObject::create(global_object, String::empty(), String::empty(), *m_function_body, {}, 0, lexical_environment, private_scope, FunctionKind::Normal, true, false, m_contains_direct_call_to_eval, false); // 6. Perform MakeMethod(bodyFunction, homeObject). body_function->make_method(home_object); @@ -1694,8 +1694,8 @@ Completion ClassExpression::execute(Interpreter& interpreter, GlobalObject& glob // 2. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments className and className. auto* value = TRY(class_definition_evaluation(interpreter, global_object, m_name, m_name.is_null() ? "" : m_name)); - // FIXME: // 3. Set value.[[SourceText]] to the source text matched by ClassExpression. + value->set_source_text(m_source_text); // 4. Return value. return Value { value }; @@ -1889,8 +1889,8 @@ ThrowCompletionOr ClassDeclaration::binding_class_declaration_evaluation( // 2. Let value be ? ClassDefinitionEvaluation of ClassTail with arguments className and className. auto* value = TRY(m_class_expression->class_definition_evaluation(interpreter, global_object, class_name, class_name)); - // FIXME: // 3. Set value.[[SourceText]] to the source text matched by ClassDeclaration. + value->set_source_text(m_class_expression->source_text()); // 4. Let env be the running execution context's LexicalEnvironment. auto* env = interpreter.lexical_environment(); @@ -4138,7 +4138,7 @@ void ScopeNode::block_declaration_instantiation(GlobalObject& global_object, Env if (is(declaration)) { auto& function_declaration = static_cast(declaration); - auto* function = ECMAScriptFunctionObject::create(global_object, function_declaration.name(), 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()); + 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()); VERIFY(is(*environment)); static_cast(*environment).initialize_or_set_mutable_binding({}, global_object, function_declaration.name(), function); } @@ -4285,7 +4285,7 @@ ThrowCompletionOr Program::global_declaration_instantiation(Interpreter& i }); for (auto& declaration : functions_to_initialize) { - auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), &global_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval()); + auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), &global_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval()); TRY(global_environment.create_global_function_binding(declaration.name(), function, false)); } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 644d5bd393..1e2ec7e88f 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -426,7 +426,7 @@ void Call::execute_impl(Bytecode::Interpreter& interpreter) const void NewFunction::execute_impl(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); - interpreter.accumulator() = ECMAScriptFunctionObject::create(interpreter.global_object(), m_function_node.name(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.lexical_environment(), vm.running_execution_context().private_environment, m_function_node.kind(), m_function_node.is_strict_mode(), m_function_node.might_need_arguments_object(), m_function_node.is_arrow_function()); + interpreter.accumulator() = ECMAScriptFunctionObject::create(interpreter.global_object(), m_function_node.name(), m_function_node.source_text(), m_function_node.body(), m_function_node.parameters(), m_function_node.function_length(), vm.lexical_environment(), vm.running_execution_context().private_environment, m_function_node.kind(), m_function_node.is_strict_mode(), m_function_node.might_need_arguments_object(), m_function_node.is_arrow_function()); } void Return::execute_impl(Bytecode::Interpreter& interpreter) const diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index cc11fa17a1..696284d27f 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -748,7 +748,7 @@ ThrowCompletionOr eval_declaration_instantiation(VM& vm, GlobalObject& glo return throw_completion(exception->value()); for (auto& declaration : functions_to_initialize) { - auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object()); + auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object()); if (global_var_environment) { TRY(global_var_environment->create_global_function_binding(declaration.name(), function, true)); } else { diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index dce4c693d9..25a256c8fc 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -29,7 +29,7 @@ namespace JS { -ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) +ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) { Object* prototype = nullptr; switch (kind) { @@ -46,15 +46,15 @@ ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_ prototype = global_object.async_generator_function_prototype(); break; } - return global_object.heap().allocate(global_object, move(name), ecmascript_code, move(parameters), m_function_length, parent_scope, private_scope, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function); + return global_object.heap().allocate(global_object, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_scope, private_scope, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function); } -ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, Object& prototype, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) +ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(GlobalObject& global_object, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) { - return global_object.heap().allocate(global_object, move(name), ecmascript_code, move(parameters), m_function_length, parent_scope, private_scope, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function); + return global_object.heap().allocate(global_object, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_scope, private_scope, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function); } -ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, Statement const& ecmascript_code, Vector formal_parameters, i32 function_length, Environment* parent_scope, PrivateEnvironment* private_scope, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) +ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector formal_parameters, i32 function_length, Environment* parent_scope, PrivateEnvironment* private_scope, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) : FunctionObject(prototype) , m_environment(parent_scope) , m_private_environment(private_scope) @@ -62,6 +62,7 @@ ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, Statement con , m_ecmascript_code(ecmascript_code) , m_realm(global_object().associated_realm()) , m_strict(strict) + , m_source_text(move(source_text)) , m_name(move(name)) , m_function_length(function_length) , m_kind(kind) @@ -553,7 +554,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::function_declaration_instantia VERIFY(!vm.exception()); auto* private_environment = callee_context.private_environment; for (auto& declaration : functions_to_initialize) { - auto* function = ECMAScriptFunctionObject::create(global_object(), declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval()); + auto* function = ECMAScriptFunctionObject::create(global_object(), declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval()); MUST(var_environment->set_mutable_binding(global_object(), declaration.name(), function, false)); } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 2da8047dcc..a8a3fb5de1 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -29,10 +29,10 @@ public: Global, }; - static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false); - static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, Object& prototype, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false); + static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false); + static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false); - ECMAScriptFunctionObject(FlyString name, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function); + ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, PrivateEnvironment* private_scope, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function); virtual void initialize(GlobalObject&) override; virtual ~ECMAScriptFunctionObject(); @@ -62,6 +62,9 @@ public: Object* home_object() const { return m_home_object; } void set_home_object(Object* home_object) { m_home_object = home_object; } + String const& source_text() const { return m_source_text; } + void set_source_text(String source_text) { m_source_text = move(source_text); } + struct InstanceField { Variant name; ECMAScriptFunctionObject* initializer { nullptr }; @@ -108,6 +111,7 @@ private: ThisMode m_this_mode { ThisMode::Global }; // [[ThisMode]] bool m_strict { false }; // [[Strict]] Object* m_home_object { nullptr }; // [[HomeObject]] + String m_source_text; // [[SourceText]] Vector m_fields; // [[Fields]] Vector m_private_methods; // [[PrivateMethods]] bool m_is_class_constructor { false }; // [[IsClassConstructor]] diff --git a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp index 3c65465b86..ebeb2e80a0 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -234,7 +234,7 @@ ThrowCompletionOr FunctionConstructor::create_dynamic PrivateEnvironment* private_scope = nullptr; // 31. Let F be ! OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, scope, privateScope). - auto* function = ECMAScriptFunctionObject::create(global_object, "anonymous", *prototype, expr->body(), expr->parameters(), expr->function_length(), scope, private_scope, expr->kind(), expr->is_strict_mode(), expr->might_need_arguments_object(), contains_direct_call_to_eval); + auto* function = ECMAScriptFunctionObject::create(global_object, "anonymous", *prototype, move(source_text), expr->body(), expr->parameters(), expr->function_length(), scope, private_scope, 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"). diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index 5f81bc13e6..ef26616437 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -134,7 +134,7 @@ void EventTarget::set_event_handler_attribute(FlyString const& name, HTML::Event dbgln("Failed to parse script in event handler attribute '{}'", name); return; } - auto* function = JS::ECMAScriptFunctionObject::create(target->script_execution_context()->realm().global_object(), name, program->body(), program->parameters(), program->function_length(), nullptr, nullptr, JS::FunctionKind::Normal, false, false); + auto* function = JS::ECMAScriptFunctionObject::create(target->script_execution_context()->realm().global_object(), name, program->source_text(), program->body(), program->parameters(), program->function_length(), nullptr, nullptr, JS::FunctionKind::Normal, false, false); VERIFY(function); listener = adopt_ref(*new DOM::EventListener(JS::make_handle(static_cast(function)), true)); } -- cgit v1.2.3