1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:47:47 +00:00

LibJS: Make more Interpreter functions take a GlobalObject&

This commit is contained in:
Andreas Kling 2020-06-08 21:25:16 +02:00
parent 053863f35e
commit 5042e560ef
9 changed files with 47 additions and 47 deletions

View file

@ -94,7 +94,7 @@ ConsoleWidget::ConsoleWidget()
output_html.append(String::format("<pre>%s</pre>", hint.characters())); output_html.append(String::format("<pre>%s</pre>", hint.characters()));
m_interpreter->throw_exception<JS::SyntaxError>(error.to_string()); m_interpreter->throw_exception<JS::SyntaxError>(error.to_string());
} else { } else {
m_interpreter->run(*program); m_interpreter->run(m_interpreter->global_object(),*program);
} }
if (m_interpreter->exception()) { if (m_interpreter->exception()) {

View file

@ -65,9 +65,9 @@ static void update_function_name(Value& value, const FlyString& name)
} }
} }
Value ScopeNode::execute(Interpreter& interpreter, GlobalObject&) const Value ScopeNode::execute(Interpreter& interpreter, GlobalObject& global_object) const
{ {
return interpreter.run(*this); return interpreter.run(global_object, *this);
} }
Value FunctionDeclaration::execute(Interpreter&, GlobalObject&) const Value FunctionDeclaration::execute(Interpreter&, GlobalObject&) const
@ -216,10 +216,10 @@ Value IfStatement::execute(Interpreter& interpreter, GlobalObject& global_object
return {}; return {};
if (predicate_result.to_boolean()) if (predicate_result.to_boolean())
return interpreter.run(*m_consequent); return interpreter.run(global_object, *m_consequent);
if (m_alternate) if (m_alternate)
return interpreter.run(*m_alternate); return interpreter.run(global_object, *m_alternate);
return js_undefined(); return js_undefined();
} }
@ -230,7 +230,7 @@ Value WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
while (m_test->execute(interpreter, global_object).to_boolean()) { while (m_test->execute(interpreter, global_object).to_boolean()) {
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }
@ -244,7 +244,7 @@ Value DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_o
do { do {
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} while (m_test->execute(interpreter, global_object).to_boolean()); } while (m_test->execute(interpreter, global_object).to_boolean());
@ -261,7 +261,7 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
NonnullRefPtrVector<VariableDeclaration> decls; NonnullRefPtrVector<VariableDeclaration> decls;
decls.append(*static_cast<const VariableDeclaration*>(m_init.ptr())); decls.append(*static_cast<const VariableDeclaration*>(m_init.ptr()));
wrapper->add_variables(decls); wrapper->add_variables(decls);
interpreter.enter_scope(*wrapper, {}, ScopeType::Block); interpreter.enter_scope(*wrapper, {}, ScopeType::Block, global_object);
} }
auto wrapper_cleanup = ScopeGuard([&] { auto wrapper_cleanup = ScopeGuard([&] {
@ -284,7 +284,7 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
return {}; return {};
if (!test_result.to_boolean()) if (!test_result.to_boolean())
break; break;
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
if (interpreter.should_unwind()) { if (interpreter.should_unwind()) {
@ -305,7 +305,7 @@ Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
} }
} else { } else {
while (true) { while (true) {
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
if (interpreter.should_unwind()) { if (interpreter.should_unwind()) {
@ -337,7 +337,7 @@ static FlyString variable_from_for_declaration(Interpreter& interpreter, GlobalO
ASSERT(!variable_declaration->declarations().is_empty()); ASSERT(!variable_declaration->declarations().is_empty());
if (variable_declaration->declaration_kind() != DeclarationKind::Var) { if (variable_declaration->declaration_kind() != DeclarationKind::Var) {
wrapper = create_ast_node<BlockStatement>(); wrapper = create_ast_node<BlockStatement>();
interpreter.enter_scope(*wrapper, {}, ScopeType::Block); interpreter.enter_scope(*wrapper, {}, ScopeType::Block, global_object);
} }
variable_declaration->execute(interpreter, global_object); variable_declaration->execute(interpreter, global_object);
variable_name = variable_declaration->declarations().first().id().string(); variable_name = variable_declaration->declarations().first().id().string();
@ -369,10 +369,10 @@ Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
while (object) { while (object) {
auto property_names = object->get_own_properties(*object, Object::GetOwnPropertyMode::Key, true); auto property_names = object->get_own_properties(*object, Object::GetOwnPropertyMode::Key, true);
for (auto& property_name : property_names.as_object().indexed_properties()) { for (auto& property_name : property_names.as_object().indexed_properties()) {
interpreter.set_variable(variable_name, property_name.value_and_attributes(object).value); interpreter.set_variable(variable_name, property_name.value_and_attributes(object).value, global_object);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
if (interpreter.should_unwind()) { if (interpreter.should_unwind()) {
@ -440,8 +440,8 @@ Value ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
auto next_item = next(); auto next_item = next();
if (!next_item.has_value()) if (!next_item.has_value())
break; break;
interpreter.set_variable(variable_name, next_item.value()); interpreter.set_variable(variable_name, next_item.value(), global_object);
last_value = interpreter.run(*m_body); last_value = interpreter.run(global_object, *m_body);
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
if (interpreter.should_unwind()) { if (interpreter.should_unwind()) {
@ -602,7 +602,7 @@ Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
// FIXME: standard recommends checking with is_unresolvable but it ALWAYS return false here // FIXME: standard recommends checking with is_unresolvable but it ALWAYS return false here
if (reference.is_local_variable() || reference.is_global_variable()) { if (reference.is_local_variable() || reference.is_global_variable()) {
auto name = reference.name(); auto name = reference.name();
lhs_result = interpreter.get_variable(name.to_string()).value_or(js_undefined()); lhs_result = interpreter.get_variable(name.to_string(), global_object).value_or(js_undefined());
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }
@ -981,9 +981,9 @@ void ForOfStatement::dump(int indent) const
body().dump(indent + 1); body().dump(indent + 1);
} }
Value Identifier::execute(Interpreter& interpreter, GlobalObject&) const Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object) const
{ {
auto value = interpreter.get_variable(string()); auto value = interpreter.get_variable(string(), global_object);
if (value.is_empty()) if (value.is_empty())
return interpreter.throw_exception<ReferenceError>(String::format("'%s' not known", string().characters())); return interpreter.throw_exception<ReferenceError>(String::format("'%s' not known", string().characters()));
return value; return value;
@ -1237,7 +1237,7 @@ Value VariableDeclaration::execute(Interpreter& interpreter, GlobalObject& globa
return {}; return {};
auto variable_name = declarator.id().string(); auto variable_name = declarator.id().string();
update_function_name(initalizer_result, variable_name); update_function_name(initalizer_result, variable_name);
interpreter.set_variable(variable_name, initalizer_result, true); interpreter.set_variable(variable_name, initalizer_result, global_object, true);
} }
} }
return js_undefined(); return js_undefined();
@ -1646,12 +1646,12 @@ void ThrowStatement::dump(int indent) const
Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
{ {
interpreter.run(block(), {}, ScopeType::Try); interpreter.run(global_object, block(), {}, ScopeType::Try);
if (auto* exception = interpreter.exception()) { if (auto* exception = interpreter.exception()) {
if (m_handler) { if (m_handler) {
interpreter.clear_exception(); interpreter.clear_exception();
ArgumentVector arguments { { m_handler->parameter(), exception->value() } }; ArgumentVector arguments { { m_handler->parameter(), exception->value() } };
interpreter.run(m_handler->body(), move(arguments)); interpreter.run(global_object, m_handler->body(), move(arguments));
} }
} }

View file

@ -52,12 +52,12 @@ Interpreter::~Interpreter()
{ {
} }
Value Interpreter::run(const Statement& statement, ArgumentVector arguments, ScopeType scope_type) Value Interpreter::run(GlobalObject& global_object, const Statement& statement, ArgumentVector arguments, ScopeType scope_type)
{ {
if (statement.is_program()) { if (statement.is_program()) {
if (m_call_stack.is_empty()) { if (m_call_stack.is_empty()) {
CallFrame global_call_frame; CallFrame global_call_frame;
global_call_frame.this_value = m_global_object; global_call_frame.this_value = &global_object;
global_call_frame.function_name = "(global execution context)"; global_call_frame.function_name = "(global execution context)";
global_call_frame.environment = heap().allocate<LexicalEnvironment>(); global_call_frame.environment = heap().allocate<LexicalEnvironment>();
m_call_stack.append(move(global_call_frame)); m_call_stack.append(move(global_call_frame));
@ -65,16 +65,16 @@ Value Interpreter::run(const Statement& statement, ArgumentVector arguments, Sco
} }
if (!statement.is_scope_node()) if (!statement.is_scope_node())
return statement.execute(*this, global_object()); return statement.execute(*this, global_object);
auto& block = static_cast<const ScopeNode&>(statement); auto& block = static_cast<const ScopeNode&>(statement);
enter_scope(block, move(arguments), scope_type); enter_scope(block, move(arguments), scope_type, global_object);
if (block.children().is_empty()) if (block.children().is_empty())
m_last_value = js_undefined(); m_last_value = js_undefined();
for (auto& node : block.children()) { for (auto& node : block.children()) {
m_last_value = node.execute(*this, global_object()); m_last_value = node.execute(*this, global_object);
if (should_unwind()) { if (should_unwind()) {
if (should_unwind_until(ScopeType::Breakable, block.label())) if (should_unwind_until(ScopeType::Breakable, block.label()))
stop_unwind(); stop_unwind();
@ -92,11 +92,11 @@ Value Interpreter::run(const Statement& statement, ArgumentVector arguments, Sco
return did_return ? m_last_value : js_undefined(); return did_return ? m_last_value : js_undefined();
} }
void Interpreter::enter_scope(const ScopeNode& scope_node, ArgumentVector arguments, ScopeType scope_type) void Interpreter::enter_scope(const ScopeNode& scope_node, ArgumentVector arguments, ScopeType scope_type, GlobalObject& global_object)
{ {
for (auto& declaration : scope_node.functions()) { for (auto& declaration : scope_node.functions()) {
auto* function = ScriptFunction::create(global_object(), declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), current_environment()); auto* function = ScriptFunction::create(global_object, declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), current_environment());
set_variable(declaration.name(), function); set_variable(declaration.name(), function, global_object);
} }
if (scope_type == ScopeType::Function) { if (scope_type == ScopeType::Function) {
@ -110,7 +110,7 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, ArgumentVector argume
for (auto& declaration : scope_node.variables()) { for (auto& declaration : scope_node.variables()) {
for (auto& declarator : declaration.declarations()) { for (auto& declarator : declaration.declarations()) {
if (scope_node.is_program()) { if (scope_node.is_program()) {
global_object().put(declarator.id().string(), js_undefined()); global_object.put(declarator.id().string(), js_undefined());
if (exception()) if (exception())
return; return;
} else { } else {
@ -149,7 +149,7 @@ void Interpreter::exit_scope(const ScopeNode& scope_node)
m_unwind_until = ScopeType::None; m_unwind_until = ScopeType::None;
} }
void Interpreter::set_variable(const FlyString& name, Value value, bool first_assignment) void Interpreter::set_variable(const FlyString& name, Value value, GlobalObject& global_object, bool first_assignment)
{ {
if (m_call_stack.size()) { if (m_call_stack.size()) {
for (auto* environment = current_environment(); environment; environment = environment->parent()) { for (auto* environment = current_environment(); environment; environment = environment->parent()) {
@ -166,10 +166,10 @@ void Interpreter::set_variable(const FlyString& name, Value value, bool first_as
} }
} }
global_object().put(move(name), move(value)); global_object.put(move(name), move(value));
} }
Value Interpreter::get_variable(const FlyString& name) Value Interpreter::get_variable(const FlyString& name, GlobalObject& global_object)
{ {
if (m_call_stack.size()) { if (m_call_stack.size()) {
for (auto* environment = current_environment(); environment; environment = environment->parent()) { for (auto* environment = current_environment(); environment; environment = environment->parent()) {
@ -178,7 +178,7 @@ Value Interpreter::get_variable(const FlyString& name)
return possible_match.value().value; return possible_match.value().value;
} }
} }
auto value = global_object().get(name); auto value = global_object.get(name);
if (m_underscore_is_last_value && name == "_" && value.is_empty()) if (m_underscore_is_last_value && name == "_" && value.is_empty())
return m_last_value; return m_last_value;
return value; return value;

View file

@ -84,7 +84,7 @@ public:
~Interpreter(); ~Interpreter();
Value run(const Statement&, ArgumentVector = {}, ScopeType = ScopeType::Block); Value run(GlobalObject&, const Statement&, ArgumentVector = {}, ScopeType = ScopeType::Block);
GlobalObject& global_object(); GlobalObject& global_object();
const GlobalObject& global_object() const; const GlobalObject& global_object() const;
@ -105,14 +105,14 @@ public:
} }
bool should_unwind() const { return m_unwind_until != ScopeType::None; } bool should_unwind() const { return m_unwind_until != ScopeType::None; }
Value get_variable(const FlyString& name); Value get_variable(const FlyString& name, GlobalObject&);
void set_variable(const FlyString& name, Value, bool first_assignment = false); void set_variable(const FlyString& name, Value, GlobalObject&, bool first_assignment = false);
Reference get_reference(const FlyString& name); Reference get_reference(const FlyString& name);
void gather_roots(Badge<Heap>, HashTable<Cell*>&); void gather_roots(Badge<Heap>, HashTable<Cell*>&);
void enter_scope(const ScopeNode&, ArgumentVector, ScopeType); void enter_scope(const ScopeNode&, ArgumentVector, ScopeType, GlobalObject&);
void exit_scope(const ScopeNode&); void exit_scope(const ScopeNode&);
Value call(Function&, Value this_value, Optional<MarkedValueList> arguments = {}); Value call(Function&, Value this_value, Optional<MarkedValueList> arguments = {});

View file

@ -44,7 +44,7 @@ void Reference::put(Interpreter& interpreter, Value value)
if (is_local_variable() || is_global_variable()) { if (is_local_variable() || is_global_variable()) {
if (is_local_variable()) if (is_local_variable())
interpreter.set_variable(m_name.to_string(), value); interpreter.set_variable(m_name.to_string(), value, interpreter.global_object());
else else
interpreter.global_object().put(m_name, value); interpreter.global_object().put(m_name, value);
return; return;
@ -85,7 +85,7 @@ Value Reference::get(Interpreter& interpreter)
if (is_local_variable() || is_global_variable()) { if (is_local_variable() || is_global_variable()) {
Value value; Value value;
if (is_local_variable()) if (is_local_variable())
value = interpreter.get_variable(m_name.to_string()); value = interpreter.get_variable(m_name.to_string(), interpreter.global_object());
else else
value = interpreter.global_object().get(m_name); value = interpreter.global_object().get(m_name);
if (interpreter.exception()) if (interpreter.exception())

View file

@ -120,7 +120,7 @@ Value ScriptFunction::call(Interpreter& interpreter)
arguments.append({ parameter.name, value }); arguments.append({ parameter.name, value });
interpreter.current_environment()->set(parameter.name, { value, DeclarationKind::Var }); interpreter.current_environment()->set(parameter.name, { value, DeclarationKind::Var });
} }
return interpreter.run(m_body, arguments, ScopeType::Function); return interpreter.run(global_object(), m_body, arguments, ScopeType::Function);
} }
Value ScriptFunction::construct(Interpreter& interpreter) Value ScriptFunction::construct(Interpreter& interpreter)

View file

@ -414,7 +414,7 @@ JS::Value Document::run_javascript(const StringView& source)
} }
dbg() << "Document::run_javascript('" << source << "') will run:"; dbg() << "Document::run_javascript('" << source << "') will run:";
program->dump(0); program->dump(0);
return document().interpreter().run(*program); return document().interpreter().run(document().interpreter().global_object(), *program);
} }
NonnullRefPtr<Element> Document::create_element(const String& tag_name) NonnullRefPtr<Element> Document::create_element(const String& tag_name)

View file

@ -75,7 +75,7 @@ void HTMLScriptElement::children_changed()
parser.print_errors(); parser.print_errors();
return; return;
} }
document().interpreter().run(*program); document().interpreter().run(document().interpreter().global_object(), *program);
} }
void HTMLScriptElement::inserted_into(Node& new_parent) void HTMLScriptElement::inserted_into(Node& new_parent)
@ -112,7 +112,7 @@ void HTMLScriptElement::inserted_into(Node& new_parent)
parser.print_errors(); parser.print_errors();
return; return;
} }
document().interpreter().run(*program); document().interpreter().run(document().interpreter().global_object(), *program);
} }
void HTMLScriptElement::execute_script() void HTMLScriptElement::execute_script()
@ -123,7 +123,7 @@ void HTMLScriptElement::execute_script()
parser.print_errors(); parser.print_errors();
return; return;
} }
document().interpreter().run(*program); document().interpreter().run(document().interpreter().global_object(), *program);
} }
void HTMLScriptElement::prepare_script(Badge<HTMLDocumentParser>) void HTMLScriptElement::prepare_script(Badge<HTMLDocumentParser>)

View file

@ -347,7 +347,7 @@ bool parse_and_run(JS::Interpreter& interpreter, const StringView& source)
printf("%s\n", hint.characters()); printf("%s\n", hint.characters());
interpreter.throw_exception<JS::SyntaxError>(error.to_string()); interpreter.throw_exception<JS::SyntaxError>(error.to_string());
} else { } else {
interpreter.run(*program); interpreter.run(interpreter.global_object(), *program);
} }
if (interpreter.exception()) { if (interpreter.exception()) {
@ -820,7 +820,7 @@ int main(int argc, char** argv)
switch (mode) { switch (mode) {
case CompleteProperty: { case CompleteProperty: {
auto maybe_variable = interpreter->get_variable(variable_name); auto maybe_variable = interpreter->get_variable(variable_name, interpreter->global_object());
if (maybe_variable.is_empty()) { if (maybe_variable.is_empty()) {
maybe_variable = interpreter->global_object().get(FlyString(variable_name)); maybe_variable = interpreter->global_object().get(FlyString(variable_name));
if (maybe_variable.is_empty()) if (maybe_variable.is_empty())