diff options
35 files changed, 297 insertions, 297 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 3197b84104..14e6697f76 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -22,12 +22,12 @@ #include <LibJS/Runtime/IteratorOperations.h> #include <LibJS/Runtime/MarkedValueList.h> #include <LibJS/Runtime/NativeFunction.h> +#include <LibJS/Runtime/ObjectEnvironmentRecord.h> #include <LibJS/Runtime/PrimitiveString.h> #include <LibJS/Runtime/Reference.h> #include <LibJS/Runtime/RegExpObject.h> #include <LibJS/Runtime/ScriptFunction.h> #include <LibJS/Runtime/Shape.h> -#include <LibJS/Runtime/WithScope.h> #include <typeinfo> namespace JS { @@ -227,11 +227,11 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj new_object = &result.as_object(); } else if (is<SuperExpression>(*m_callee)) { // FIXME: This is merely a band-aid to make super() inside catch {} work (which constructs - // a new LexicalEnvironment without current function). Implement GetSuperConstructor() + // a new DeclarativeEnvironmentRecord without current function). Implement GetSuperConstructor() // and subsequently GetThisEnvironment() instead. auto* function_environment = interpreter.current_environment(); if (!function_environment->current_function()) - function_environment = static_cast<LexicalEnvironment*>(function_environment->parent()); + function_environment = static_cast<DeclarativeEnvironmentRecord*>(function_environment->parent()); auto* super_constructor = function_environment->current_function()->prototype(); // FIXME: Functions should track their constructor kind. @@ -306,8 +306,8 @@ Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_obje VERIFY(object); - auto* with_scope = interpreter.heap().allocate<WithScope>(global_object, *object, interpreter.vm().call_frame().scope); - TemporaryChange<ScopeObject*> scope_change(interpreter.vm().call_frame().scope, with_scope); + auto* object_environment_record = interpreter.heap().allocate<ObjectEnvironmentRecord>(global_object, *object, interpreter.vm().call_frame().environment_record); + TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().call_frame().environment_record, object_environment_record); return interpreter.execute_statement(global_object, m_body).value_or(js_undefined()); } @@ -2055,8 +2055,8 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec HashMap<FlyString, Variable> parameters; parameters.set(m_handler->parameter(), Variable { exception->value(), DeclarationKind::Var }); - auto* catch_scope = interpreter.heap().allocate<LexicalEnvironment>(global_object, move(parameters), interpreter.vm().call_frame().scope); - TemporaryChange<ScopeObject*> scope_change(interpreter.vm().call_frame().scope, catch_scope); + auto* catch_scope = interpreter.heap().allocate<DeclarativeEnvironmentRecord>(global_object, move(parameters), interpreter.vm().call_frame().environment_record); + TemporaryChange<EnvironmentRecord*> scope_change(interpreter.vm().call_frame().environment_record, catch_scope); result = interpreter.execute_statement(global_object, m_handler->body()); } } diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 86c6990f53..77f589f66b 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -14,7 +14,7 @@ #include <LibJS/Bytecode/Op.h> #include <LibJS/Bytecode/Register.h> #include <LibJS/Bytecode/StringTable.h> -#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/EnvironmentRecord.h> namespace JS { @@ -63,7 +63,7 @@ void ScopeNode::generate_bytecode(Bytecode::Generator& generator) const } if (!scope_variables_with_declaration_kind.is_empty()) { - generator.emit<Bytecode::Op::PushLexicalEnvironment>(move(scope_variables_with_declaration_kind)); + generator.emit<Bytecode::Op::PushDeclarativeEnvironmentRecord>(move(scope_variables_with_declaration_kind)); } for (auto& child : children()) { @@ -1219,7 +1219,7 @@ void TryStatement::generate_bytecode(Bytecode::Generator& generator) const if (!m_finalizer) generator.emit<Bytecode::Op::LeaveUnwindContext>(); if (!m_handler->parameter().is_empty()) { - // FIXME: We need a separate LexicalEnvironment here + // FIXME: We need a separate DeclarativeEnvironmentRecord here generator.emit<Bytecode::Op::SetVariable>(generator.intern_string(m_handler->parameter())); } m_handler->body().generate_bytecode(generator); diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index a01ce99238..58139ffd4b 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -9,70 +9,70 @@ #include <AK/Forward.h> #include <LibJS/Forward.h> -#define ENUMERATE_BYTECODE_OPS(O) \ - O(Load) \ - O(LoadImmediate) \ - O(Store) \ - O(Add) \ - O(Sub) \ - O(Mul) \ - O(Div) \ - O(Mod) \ - O(Exp) \ - O(GreaterThan) \ - O(GreaterThanEquals) \ - O(LessThan) \ - O(LessThanEquals) \ - O(AbstractInequals) \ - O(AbstractEquals) \ - O(TypedInequals) \ - O(TypedEquals) \ - O(NewBigInt) \ - O(NewArray) \ - O(IteratorToArray) \ - O(NewString) \ - O(NewObject) \ - O(NewRegExp) \ - O(CopyObjectExcludingProperties) \ - O(GetVariable) \ - O(SetVariable) \ - O(PutById) \ - O(GetById) \ - O(PutByValue) \ - O(GetByValue) \ - O(Jump) \ - O(JumpConditional) \ - O(JumpNullish) \ - O(JumpUndefined) \ - O(Call) \ - O(NewFunction) \ - O(Return) \ - O(BitwiseAnd) \ - O(BitwiseOr) \ - O(BitwiseXor) \ - O(BitwiseNot) \ - O(Not) \ - O(UnaryPlus) \ - O(UnaryMinus) \ - O(Typeof) \ - O(LeftShift) \ - O(RightShift) \ - O(UnsignedRightShift) \ - O(In) \ - O(InstanceOf) \ - O(ConcatString) \ - O(Increment) \ - O(Decrement) \ - O(Throw) \ - O(PushLexicalEnvironment) \ - O(LoadArgument) \ - O(EnterUnwindContext) \ - O(LeaveUnwindContext) \ - O(ContinuePendingUnwind) \ - O(Yield) \ - O(GetIterator) \ - O(IteratorNext) \ - O(IteratorResultDone) \ +#define ENUMERATE_BYTECODE_OPS(O) \ + O(Load) \ + O(LoadImmediate) \ + O(Store) \ + O(Add) \ + O(Sub) \ + O(Mul) \ + O(Div) \ + O(Mod) \ + O(Exp) \ + O(GreaterThan) \ + O(GreaterThanEquals) \ + O(LessThan) \ + O(LessThanEquals) \ + O(AbstractInequals) \ + O(AbstractEquals) \ + O(TypedInequals) \ + O(TypedEquals) \ + O(NewBigInt) \ + O(NewArray) \ + O(IteratorToArray) \ + O(NewString) \ + O(NewObject) \ + O(NewRegExp) \ + O(CopyObjectExcludingProperties) \ + O(GetVariable) \ + O(SetVariable) \ + O(PutById) \ + O(GetById) \ + O(PutByValue) \ + O(GetByValue) \ + O(Jump) \ + O(JumpConditional) \ + O(JumpNullish) \ + O(JumpUndefined) \ + O(Call) \ + O(NewFunction) \ + O(Return) \ + O(BitwiseAnd) \ + O(BitwiseOr) \ + O(BitwiseXor) \ + O(BitwiseNot) \ + O(Not) \ + O(UnaryPlus) \ + O(UnaryMinus) \ + O(Typeof) \ + O(LeftShift) \ + O(RightShift) \ + O(UnsignedRightShift) \ + O(In) \ + O(InstanceOf) \ + O(ConcatString) \ + O(Increment) \ + O(Decrement) \ + O(Throw) \ + O(PushDeclarativeEnvironmentRecord) \ + O(LoadArgument) \ + O(EnterUnwindContext) \ + O(LeaveUnwindContext) \ + O(ContinuePendingUnwind) \ + O(Yield) \ + O(GetIterator) \ + O(IteratorNext) \ + O(IteratorResultDone) \ O(IteratorResultValue) namespace JS::Bytecode { diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 4d4441cd7d..dfa96f32c1 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -48,7 +48,7 @@ Value Interpreter::run(Executable const& executable, BasicBlock const* entry_poi global_call_frame.this_value = &global_object(); static FlyString global_execution_context_name = "(*BC* global execution context)"; global_call_frame.function_name = global_execution_context_name; - global_call_frame.scope = &global_object(); + global_call_frame.environment_record = &global_object(); VERIFY(!vm().exception()); // FIXME: How do we know if we're in strict mode? Maybe the Bytecode::Block should know this? // global_call_frame.is_strict_mode = ???; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index d925c54687..7274641c56 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -12,11 +12,11 @@ #include <LibJS/Bytecode/Op.h> #include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/BigInt.h> +#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h> +#include <LibJS/Runtime/EnvironmentRecord.h> #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/IteratorOperations.h> -#include <LibJS/Runtime/LexicalEnvironment.h> #include <LibJS/Runtime/RegExpObject.h> -#include <LibJS/Runtime/ScopeObject.h> #include <LibJS/Runtime/ScriptFunction.h> #include <LibJS/Runtime/Value.h> @@ -381,13 +381,13 @@ void ContinuePendingUnwind::replace_references_impl(BasicBlock const& from, Basi m_resume_target = Label { to }; } -void PushLexicalEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const +void PushDeclarativeEnvironmentRecord::execute_impl(Bytecode::Interpreter& interpreter) const { HashMap<FlyString, Variable> resolved_variables; for (auto& it : m_variables) resolved_variables.set(interpreter.current_executable().get_string(it.key), it.value); - auto* block_lexical_environment = interpreter.vm().heap().allocate<LexicalEnvironment>(interpreter.global_object(), move(resolved_variables), interpreter.vm().current_scope()); - interpreter.vm().call_frame().scope = block_lexical_environment; + auto* environment_record = interpreter.vm().heap().allocate<DeclarativeEnvironmentRecord>(interpreter.global_object(), move(resolved_variables), interpreter.vm().current_scope()); + interpreter.vm().call_frame().environment_record = environment_record; } void Yield::execute_impl(Bytecode::Interpreter& interpreter) const @@ -639,10 +639,10 @@ String ContinuePendingUnwind::to_string_impl(Bytecode::Executable const&) const return String::formatted("ContinuePendingUnwind resume:{}", m_resume_target); } -String PushLexicalEnvironment::to_string_impl(const Bytecode::Executable& executable) const +String PushDeclarativeEnvironmentRecord::to_string_impl(const Bytecode::Executable& executable) const { StringBuilder builder; - builder.append("PushLexicalEnvironment"); + builder.append("PushDeclarativeEnvironmentRecord"); if (!m_variables.is_empty()) { builder.append(" {"); Vector<String> names; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 177f2f66ed..055fdab701 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -14,7 +14,7 @@ #include <LibJS/Bytecode/Register.h> #include <LibJS/Bytecode/StringTable.h> #include <LibJS/Heap/Cell.h> -#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/EnvironmentRecord.h> #include <LibJS/Runtime/Value.h> namespace JS::Bytecode::Op { @@ -635,10 +635,10 @@ private: Optional<Label> m_continuation_label; }; -class PushLexicalEnvironment final : public Instruction { +class PushDeclarativeEnvironmentRecord final : public Instruction { public: - explicit PushLexicalEnvironment(HashMap<u32, Variable> variables) - : Instruction(Type::PushLexicalEnvironment) + explicit PushDeclarativeEnvironmentRecord(HashMap<u32, Variable> variables) + : Instruction(Type::PushDeclarativeEnvironmentRecord) , m_variables(move(variables)) { } diff --git a/Userland/Libraries/LibJS/CMakeLists.txt b/Userland/Libraries/LibJS/CMakeLists.txt index 25d3d26e83..73c050d8bb 100644 --- a/Userland/Libraries/LibJS/CMakeLists.txt +++ b/Userland/Libraries/LibJS/CMakeLists.txt @@ -49,6 +49,8 @@ set(SOURCES Runtime/DateConstructor.cpp Runtime/Date.cpp Runtime/DatePrototype.cpp + Runtime/DeclarativeEnvironmentRecord.cpp + Runtime/EnvironmentRecord.cpp Runtime/ErrorConstructor.cpp Runtime/Error.cpp Runtime/ErrorPrototype.cpp @@ -69,7 +71,6 @@ set(SOURCES Runtime/IteratorOperations.cpp Runtime/IteratorPrototype.cpp Runtime/JSONObject.cpp - Runtime/LexicalEnvironment.cpp Runtime/Map.cpp Runtime/MapConstructor.cpp Runtime/MapIterator.cpp @@ -82,8 +83,9 @@ set(SOURCES Runtime/NumberConstructor.cpp Runtime/NumberObject.cpp Runtime/NumberPrototype.cpp - Runtime/ObjectConstructor.cpp Runtime/Object.cpp + Runtime/ObjectConstructor.cpp + Runtime/ObjectEnvironmentRecord.cpp Runtime/ObjectPrototype.cpp Runtime/PrimitiveString.cpp Runtime/Promise.cpp @@ -99,7 +101,6 @@ set(SOURCES Runtime/RegExpConstructor.cpp Runtime/RegExpObject.cpp Runtime/RegExpPrototype.cpp - Runtime/ScopeObject.cpp Runtime/ScriptFunction.cpp Runtime/Set.cpp Runtime/SetConstructor.cpp @@ -130,7 +131,6 @@ set(SOURCES Runtime/WeakSet.cpp Runtime/WeakSetConstructor.cpp Runtime/WeakSetPrototype.cpp - Runtime/WithScope.cpp SyntaxHighlighter.cpp Token.cpp ) diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index a8fae90d78..f1a9d5016a 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -131,7 +131,7 @@ class HandleImpl; class Heap; class HeapBlock; class Interpreter; -class LexicalEnvironment; +class DeclarativeEnvironmentRecord; class MarkedValueList; class NativeFunction; class NativeProperty; @@ -142,7 +142,7 @@ class PromiseResolveThenableJob; class PropertyName; class Reference; class ScopeNode; -class ScopeObject; +class EnvironmentRecord; class Shape; class Statement; class StringOrSymbol; diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index 06e096e59f..80bec1d8cd 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -9,8 +9,8 @@ #include <AK/StringBuilder.h> #include <LibJS/AST.h> #include <LibJS/Interpreter.h> +#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h> #include <LibJS/Runtime/GlobalObject.h> -#include <LibJS/Runtime/LexicalEnvironment.h> #include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/Reference.h> #include <LibJS/Runtime/ScriptFunction.h> @@ -50,7 +50,7 @@ void Interpreter::run(GlobalObject& global_object, const Program& program) global_call_frame.this_value = &global_object; static FlyString global_execution_context_name = "(global execution context)"; global_call_frame.function_name = global_execution_context_name; - global_call_frame.scope = &global_object; + global_call_frame.environment_record = &global_object; VERIFY(!vm.exception()); global_call_frame.is_strict_mode = program.is_strict_mode(); vm.push_call_frame(global_call_frame, global_object); @@ -128,15 +128,15 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, ScopeType scope_type, } } - bool pushed_lexical_environment = false; + bool pushed_environment_record = false; if (!scope_variables_with_declaration_kind.is_empty()) { - auto* block_lexical_environment = heap().allocate<LexicalEnvironment>(global_object, move(scope_variables_with_declaration_kind), current_scope()); - vm().call_frame().scope = block_lexical_environment; - pushed_lexical_environment = true; + auto* environment_record = heap().allocate<DeclarativeEnvironmentRecord>(global_object, move(scope_variables_with_declaration_kind), current_scope()); + vm().call_frame().environment_record = environment_record; + pushed_environment_record = true; } - push_scope({ scope_type, scope_node, pushed_lexical_environment }); + push_scope({ scope_type, scope_node, pushed_environment_record }); } void Interpreter::exit_scope(const ScopeNode& scope_node) @@ -144,7 +144,7 @@ void Interpreter::exit_scope(const ScopeNode& scope_node) while (!m_scope_stack.is_empty()) { auto popped_scope = m_scope_stack.take_last(); if (popped_scope.pushed_environment) - vm().call_frame().scope = vm().call_frame().scope->parent(); + vm().call_frame().environment_record = vm().call_frame().environment_record->parent(); if (popped_scope.scope_node.ptr() == &scope_node) break; } @@ -193,10 +193,10 @@ Value Interpreter::execute_statement(GlobalObject& global_object, const Statemen return last_value; } -LexicalEnvironment* Interpreter::current_environment() +DeclarativeEnvironmentRecord* Interpreter::current_environment() { - VERIFY(is<LexicalEnvironment>(vm().call_frame().scope)); - return static_cast<LexicalEnvironment*>(vm().call_frame().scope); + VERIFY(is<DeclarativeEnvironmentRecord>(vm().call_frame().environment_record)); + return static_cast<DeclarativeEnvironmentRecord*>(vm().call_frame().environment_record); } } diff --git a/Userland/Libraries/LibJS/Interpreter.h b/Userland/Libraries/LibJS/Interpreter.h index 8d4e9a9e0e..4407952814 100644 --- a/Userland/Libraries/LibJS/Interpreter.h +++ b/Userland/Libraries/LibJS/Interpreter.h @@ -15,9 +15,9 @@ #include <LibJS/Forward.h> #include <LibJS/Heap/DeferGC.h> #include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h> #include <LibJS/Runtime/ErrorTypes.h> #include <LibJS/Runtime/Exception.h> -#include <LibJS/Runtime/LexicalEnvironment.h> #include <LibJS/Runtime/MarkedValueList.h> #include <LibJS/Runtime/VM.h> #include <LibJS/Runtime/Value.h> @@ -56,8 +56,8 @@ public: ALWAYS_INLINE Heap& heap() { return vm().heap(); } ALWAYS_INLINE Exception* exception() { return vm().exception(); } - ScopeObject* current_scope() { return vm().current_scope(); } - LexicalEnvironment* current_environment(); + EnvironmentRecord* current_scope() { return vm().current_scope(); } + DeclarativeEnvironmentRecord* current_environment(); void enter_scope(const ScopeNode&, ScopeType, GlobalObject&); void exit_scope(const ScopeNode&); diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 651efb53d7..02ef9a026b 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -258,7 +258,7 @@ NonnullRefPtr<Program> Parser::parse_program() program->add_variables(m_state.let_scopes.last()); program->add_functions(m_state.function_scopes.last()); } else { - syntax_error("Unclosed scope"); + syntax_error("Unclosed environment_record"); } program->source_range().end = position(); return program; diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp index f3df564986..ae108f6f5c 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -44,9 +44,9 @@ Value BoundFunction::construct(Function& new_target) return m_target_function->construct(new_target); } -LexicalEnvironment* BoundFunction::create_environment() +DeclarativeEnvironmentRecord* BoundFunction::create_environment_record() { - return m_target_function->create_environment(); + return m_target_function->create_environment_record(); } void BoundFunction::visit_edges(Visitor& visitor) diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.h b/Userland/Libraries/LibJS/Runtime/BoundFunction.h index 5f39b5a2bb..165d73f9de 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.h +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.h @@ -22,7 +22,7 @@ public: virtual Value construct(Function& new_target) override; - virtual LexicalEnvironment* create_environment() override; + virtual DeclarativeEnvironmentRecord* create_environment_record() override; virtual void visit_edges(Visitor&) override; diff --git a/Userland/Libraries/LibJS/Runtime/LexicalEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironmentRecord.cpp index df6ebed89a..a0d52a23b8 100644 --- a/Userland/Libraries/LibJS/Runtime/LexicalEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironmentRecord.cpp @@ -1,47 +1,47 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <LibJS/Interpreter.h> +#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h> #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/GlobalObject.h> -#include <LibJS/Runtime/LexicalEnvironment.h> #include <LibJS/Runtime/Value.h> namespace JS { -LexicalEnvironment::LexicalEnvironment() - : ScopeObject(nullptr) +DeclarativeEnvironmentRecord::DeclarativeEnvironmentRecord() + : EnvironmentRecord(nullptr) { } -LexicalEnvironment::LexicalEnvironment(EnvironmentRecordType environment_record_type) - : ScopeObject(nullptr) +DeclarativeEnvironmentRecord::DeclarativeEnvironmentRecord(EnvironmentRecordType environment_record_type) + : EnvironmentRecord(nullptr) , m_environment_record_type(environment_record_type) { } -LexicalEnvironment::LexicalEnvironment(HashMap<FlyString, Variable> variables, ScopeObject* parent_scope) - : ScopeObject(parent_scope) +DeclarativeEnvironmentRecord::DeclarativeEnvironmentRecord(HashMap<FlyString, Variable> variables, EnvironmentRecord* parent_scope) + : EnvironmentRecord(parent_scope) , m_variables(move(variables)) { } -LexicalEnvironment::LexicalEnvironment(HashMap<FlyString, Variable> variables, ScopeObject* parent_scope, EnvironmentRecordType environment_record_type) - : ScopeObject(parent_scope) +DeclarativeEnvironmentRecord::DeclarativeEnvironmentRecord(HashMap<FlyString, Variable> variables, EnvironmentRecord* parent_scope, EnvironmentRecordType environment_record_type) + : EnvironmentRecord(parent_scope) , m_environment_record_type(environment_record_type) , m_variables(move(variables)) { } -LexicalEnvironment::~LexicalEnvironment() +DeclarativeEnvironmentRecord::~DeclarativeEnvironmentRecord() { } -void LexicalEnvironment::visit_edges(Visitor& visitor) +void DeclarativeEnvironmentRecord::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_this_value); @@ -52,27 +52,27 @@ void LexicalEnvironment::visit_edges(Visitor& visitor) visitor.visit(it.value.value); } -Optional<Variable> LexicalEnvironment::get_from_scope(const FlyString& name) const +Optional<Variable> DeclarativeEnvironmentRecord::get_from_scope(const FlyString& name) const { return m_variables.get(name); } -void LexicalEnvironment::put_to_scope(const FlyString& name, Variable variable) +void DeclarativeEnvironmentRecord::put_to_scope(const FlyString& name, Variable variable) { m_variables.set(name, variable); } -bool LexicalEnvironment::delete_from_scope(FlyString const& name) +bool DeclarativeEnvironmentRecord::delete_from_scope(FlyString const& name) { return m_variables.remove(name); } -bool LexicalEnvironment::has_super_binding() const +bool DeclarativeEnvironmentRecord::has_super_binding() const { return m_environment_record_type == EnvironmentRecordType::Function && this_binding_status() != ThisBindingStatus::Lexical && m_home_object.is_object(); } -Value LexicalEnvironment::get_super_base() +Value DeclarativeEnvironmentRecord::get_super_base() { VERIFY(has_super_binding()); if (m_home_object.is_object()) @@ -80,7 +80,7 @@ Value LexicalEnvironment::get_super_base() return {}; } -bool LexicalEnvironment::has_this_binding() const +bool DeclarativeEnvironmentRecord::has_this_binding() const { // More like "is_capable_of_having_a_this_binding". switch (m_environment_record_type) { @@ -95,7 +95,7 @@ bool LexicalEnvironment::has_this_binding() const VERIFY_NOT_REACHED(); } -Value LexicalEnvironment::get_this_binding(GlobalObject& global_object) const +Value DeclarativeEnvironmentRecord::get_this_binding(GlobalObject& global_object) const { VERIFY(has_this_binding()); if (this_binding_status() == ThisBindingStatus::Uninitialized) { @@ -105,7 +105,7 @@ Value LexicalEnvironment::get_this_binding(GlobalObject& global_object) const return m_this_value; } -void LexicalEnvironment::bind_this_value(GlobalObject& global_object, Value this_value) +void DeclarativeEnvironmentRecord::bind_this_value(GlobalObject& global_object, Value this_value) { VERIFY(has_this_binding()); if (m_this_binding_status == ThisBindingStatus::Initialized) { diff --git a/Userland/Libraries/LibJS/Runtime/LexicalEnvironment.h b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironmentRecord.h index 73a5018a32..928ce91a41 100644 --- a/Userland/Libraries/LibJS/Runtime/LexicalEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/DeclarativeEnvironmentRecord.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,13 +8,13 @@ #include <AK/FlyString.h> #include <AK/HashMap.h> -#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/EnvironmentRecord.h> #include <LibJS/Runtime/Value.h> namespace JS { -class LexicalEnvironment final : public ScopeObject { - JS_OBJECT(LexicalEnvironment, ScopeObject); +class DeclarativeEnvironmentRecord final : public EnvironmentRecord { + JS_OBJECT(DeclarativeEnvironmentRecord, EnvironmentRecord); public: enum class ThisBindingStatus { @@ -30,13 +30,13 @@ public: Module, }; - LexicalEnvironment(); - LexicalEnvironment(EnvironmentRecordType); - LexicalEnvironment(HashMap<FlyString, Variable> variables, ScopeObject* parent_scope); - LexicalEnvironment(HashMap<FlyString, Variable> variables, ScopeObject* parent_scope, EnvironmentRecordType); - virtual ~LexicalEnvironment() override; + DeclarativeEnvironmentRecord(); + DeclarativeEnvironmentRecord(EnvironmentRecordType); + DeclarativeEnvironmentRecord(HashMap<FlyString, Variable> variables, EnvironmentRecord* parent_scope); + DeclarativeEnvironmentRecord(HashMap<FlyString, Variable> variables, EnvironmentRecord* parent_scope, EnvironmentRecordType); + virtual ~DeclarativeEnvironmentRecord() override; - // ^ScopeObject + // ^EnvironmentRecord virtual Optional<Variable> get_from_scope(const FlyString&) const override; virtual void put_to_scope(const FlyString&, Variable) override; virtual bool delete_from_scope(FlyString const&) override; @@ -66,7 +66,7 @@ public: EnvironmentRecordType type() const { return m_environment_record_type; } private: - virtual bool is_lexical_environment() const override { return true; } + virtual bool is_declarative_environment_record() const override { return true; } virtual void visit_edges(Visitor&) override; EnvironmentRecordType m_environment_record_type : 8 { EnvironmentRecordType::Declarative }; @@ -80,6 +80,6 @@ private: }; template<> -inline bool Object::fast_is<LexicalEnvironment>() const { return is_lexical_environment(); } +inline bool Object::fast_is<DeclarativeEnvironmentRecord>() const { return is_declarative_environment_record(); } } diff --git a/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.cpp b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.cpp new file mode 100644 index 0000000000..4e2329c83e --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/Runtime/EnvironmentRecord.h> +#include <LibJS/Runtime/VM.h> + +namespace JS { + +EnvironmentRecord::EnvironmentRecord(EnvironmentRecord* parent) + : Object(vm().environment_record_shape()) + , m_parent(parent) +{ +} + +EnvironmentRecord::EnvironmentRecord(GlobalObjectTag tag) + : Object(tag) +{ +} + +void EnvironmentRecord::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_parent); +} + +} diff --git a/Userland/Libraries/LibJS/Runtime/ScopeObject.h b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h index d64826f95b..5462421236 100644 --- a/Userland/Libraries/LibJS/Runtime/ScopeObject.h +++ b/Userland/Libraries/LibJS/Runtime/EnvironmentRecord.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,8 +15,8 @@ struct Variable { DeclarationKind declaration_kind; }; -class ScopeObject : public Object { - JS_OBJECT(ScopeObject, Object); +class EnvironmentRecord : public Object { + JS_OBJECT(EnvironmentRecord, Object); public: virtual Optional<Variable> get_from_scope(const FlyString&) const = 0; @@ -25,17 +25,17 @@ public: virtual bool has_this_binding() const = 0; virtual Value get_this_binding(GlobalObject&) const = 0; - ScopeObject* parent() { return m_parent; } - const ScopeObject* parent() const { return m_parent; } + EnvironmentRecord* parent() { return m_parent; } + const EnvironmentRecord* parent() const { return m_parent; } protected: - explicit ScopeObject(ScopeObject* parent); - explicit ScopeObject(GlobalObjectTag); + explicit EnvironmentRecord(EnvironmentRecord* parent); + explicit EnvironmentRecord(GlobalObjectTag); virtual void visit_edges(Visitor&) override; private: - ScopeObject* m_parent { nullptr }; + EnvironmentRecord* m_parent { nullptr }; }; } diff --git a/Userland/Libraries/LibJS/Runtime/Function.h b/Userland/Libraries/LibJS/Runtime/Function.h index 41d074eab9..21b9cfa9c7 100644 --- a/Userland/Libraries/LibJS/Runtime/Function.h +++ b/Userland/Libraries/LibJS/Runtime/Function.h @@ -26,7 +26,7 @@ public: virtual Value call() = 0; virtual Value construct(Function& new_target) = 0; virtual const FlyString& name() const = 0; - virtual LexicalEnvironment* create_environment() = 0; + virtual DeclarativeEnvironmentRecord* create_environment_record() = 0; BoundFunction* bind(Value bound_this_value, Vector<Value> arguments); diff --git a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp index 845331143f..69b2674261 100644 --- a/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp @@ -13,7 +13,7 @@ namespace JS { -GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value initial_value, ScriptFunction* generating_function, ScopeObject* generating_scope, Bytecode::RegisterWindow frame) +GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value initial_value, ScriptFunction* generating_function, EnvironmentRecord* generating_scope, Bytecode::RegisterWindow frame) { // This is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) auto generating_function_proto_property = generating_function->get(global_object.vm().names.prototype).to_object(global_object); @@ -22,7 +22,7 @@ GeneratorObject* GeneratorObject::create(GlobalObject& global_object, Value init auto object = global_object.heap().allocate<GeneratorObject>(global_object, global_object, *generating_function_proto_property); object->m_generating_function = generating_function; - object->m_scope = generating_scope; + object->m_environment_record = generating_scope; object->m_frame = move(frame); object->m_previous_value = initial_value; return object; @@ -44,7 +44,7 @@ GeneratorObject::~GeneratorObject() void GeneratorObject::visit_edges(Cell::Visitor& visitor) { Object::visit_edges(visitor); - visitor.visit(m_scope); + visitor.visit(m_environment_record); visitor.visit(m_generating_function); if (m_previous_value.is_object()) visitor.visit(&m_previous_value.as_object()); @@ -106,8 +106,8 @@ Value GeneratorObject::next_impl(VM& vm, GlobalObject& global_object, Optional<V bytecode_interpreter->accumulator() = vm.argument(0); } - // Temporarily switch to the captured scope - TemporaryChange change { vm.call_frame().scope, m_scope }; + // Temporarily switch to the captured environment record + TemporaryChange change { vm.call_frame().environment_record, m_environment_record }; m_previous_value = bytecode_interpreter->run(*m_generating_function->bytecode_executable(), next_block); diff --git a/Userland/Libraries/LibJS/Runtime/GeneratorObject.h b/Userland/Libraries/LibJS/Runtime/GeneratorObject.h index d8d5f90200..08d722f664 100644 --- a/Userland/Libraries/LibJS/Runtime/GeneratorObject.h +++ b/Userland/Libraries/LibJS/Runtime/GeneratorObject.h @@ -15,7 +15,7 @@ class GeneratorObject final : public Object { JS_OBJECT(GeneratorObject, Object); public: - static GeneratorObject* create(GlobalObject&, Value, ScriptFunction*, ScopeObject*, Bytecode::RegisterWindow); + static GeneratorObject* create(GlobalObject&, Value, ScriptFunction*, EnvironmentRecord*, Bytecode::RegisterWindow); GeneratorObject(GlobalObject&, Object& prototype); virtual void initialize(GlobalObject&) override; virtual ~GeneratorObject() override; @@ -25,7 +25,7 @@ public: void set_done() { m_done = true; } private: - ScopeObject* m_scope { nullptr }; + EnvironmentRecord* m_environment_record { nullptr }; ScriptFunction* m_generating_function { nullptr }; Value m_previous_value; Bytecode::RegisterWindow m_frame; diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index efb0c5ec77..f0ec0f7426 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -82,7 +82,7 @@ namespace JS { GlobalObject::GlobalObject() - : ScopeObject(GlobalObjectTag::Tag) + : EnvironmentRecord(GlobalObjectTag::Tag) , m_console(make<Console>(*this)) { } @@ -372,7 +372,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval) } auto& caller_frame = vm.call_stack().at(vm.call_stack().size() - 2); - TemporaryChange scope_change(vm.call_frame().scope, caller_frame->scope); + TemporaryChange scope_change(vm.call_frame().environment_record, caller_frame->environment_record); auto& interpreter = vm.interpreter(); return interpreter.execute_statement(global_object, program).value_or(js_undefined()); diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h index 76ceca24ac..77abad92cc 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h @@ -7,13 +7,13 @@ #pragma once #include <LibJS/Heap/Heap.h> -#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/EnvironmentRecord.h> #include <LibJS/Runtime/VM.h> namespace JS { -class GlobalObject : public ScopeObject { - JS_OBJECT(GlobalObject, ScopeObject); +class GlobalObject : public EnvironmentRecord { + JS_OBJECT(GlobalObject, EnvironmentRecord); public: explicit GlobalObject(); diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp index 9ddec6cdba..cc4634c6cf 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -47,7 +47,7 @@ Value NativeFunction::construct(Function&) return {}; } -LexicalEnvironment* NativeFunction::create_environment() +DeclarativeEnvironmentRecord* NativeFunction::create_environment_record() { return nullptr; } diff --git a/Userland/Libraries/LibJS/Runtime/NativeFunction.h b/Userland/Libraries/LibJS/Runtime/NativeFunction.h index 4d8b8de6b4..3586545e08 100644 --- a/Userland/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Userland/Libraries/LibJS/Runtime/NativeFunction.h @@ -34,7 +34,7 @@ protected: explicit NativeFunction(Object& prototype); private: - virtual LexicalEnvironment* create_environment() override final; + virtual DeclarativeEnvironmentRecord* create_environment_record() override final; virtual bool is_native_function() const final { return true; } FlyString m_name; diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index cfdfb9b8d0..fb9b781bb2 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -108,7 +108,7 @@ public: virtual bool is_global_object() const { return false; } virtual bool is_proxy_object() const { return false; } virtual bool is_native_function() const { return false; } - virtual bool is_lexical_environment() const { return false; } + virtual bool is_declarative_environment_record() const { return false; } // B.3.7 The [[IsHTMLDDA]] Internal Slot, https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot virtual bool is_htmldda() const { return false; } diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp new file mode 100644 index 0000000000..28e3a8507a --- /dev/null +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/AST.h> +#include <LibJS/Runtime/ObjectEnvironmentRecord.h> + +namespace JS { + +ObjectEnvironmentRecord::ObjectEnvironmentRecord(Object& object, EnvironmentRecord* parent_scope) + : EnvironmentRecord(parent_scope) + , m_object(object) +{ +} + +void ObjectEnvironmentRecord::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(&m_object); +} + +Optional<Variable> ObjectEnvironmentRecord::get_from_scope(const FlyString& name) const +{ + auto value = m_object.get(name); + if (value.is_empty()) + return {}; + return Variable { value, DeclarationKind::Var }; +} + +void ObjectEnvironmentRecord::put_to_scope(const FlyString& name, Variable variable) +{ + m_object.put(name, variable.value); +} + +bool ObjectEnvironmentRecord::delete_from_scope(FlyString const& name) +{ + return m_object.delete_property(name); +} + +bool ObjectEnvironmentRecord::has_this_binding() const +{ + return parent()->has_this_binding(); +} + +Value ObjectEnvironmentRecord::get_this_binding(GlobalObject& global_object) const +{ + return parent()->get_this_binding(global_object); +} + +} diff --git a/Userland/Libraries/LibJS/Runtime/WithScope.h b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h index 829725b7d2..97166ea5df 100644 --- a/Userland/Libraries/LibJS/Runtime/WithScope.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironmentRecord.h @@ -1,20 +1,20 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include <LibJS/Runtime/ScopeObject.h> +#include <LibJS/Runtime/EnvironmentRecord.h> namespace JS { -class WithScope : public ScopeObject { - JS_OBJECT(WithScope, ScopeObject); +class ObjectEnvironmentRecord : public EnvironmentRecord { + JS_OBJECT(ObjectEnvironmentRecord, EnvironmentRecord); public: - WithScope(Object&, ScopeObject* parent_scope); + ObjectEnvironmentRecord(Object&, EnvironmentRecord* parent_scope); virtual Optional<Variable> get_from_scope(const FlyString&) const override; virtual void put_to_scope(const FlyString&, Variable) override; diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 560f46cbb5..1b6e912942 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -478,10 +478,10 @@ const FlyString& ProxyObject::name() const return static_cast<Function&>(m_target).name(); } -LexicalEnvironment* ProxyObject::create_environment() +DeclarativeEnvironmentRecord* ProxyObject::create_environment_record() { VERIFY(is_function()); - return static_cast<Function&>(m_target).create_environment(); + return static_cast<Function&>(m_target).create_environment_record(); } } diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index f11a54f311..8493a444cf 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -22,7 +22,7 @@ public: virtual Value call() override; virtual Value construct(Function& new_target) override; virtual const FlyString& name() const override; - virtual LexicalEnvironment* create_environment() override; + virtual DeclarativeEnvironmentRecord* create_environment_record() override; const Object& target() const { return m_target; } const Object& handler() const { return m_handler; } diff --git a/Userland/Libraries/LibJS/Runtime/ScopeObject.cpp b/Userland/Libraries/LibJS/Runtime/ScopeObject.cpp deleted file mode 100644 index 6d0dfcb86f..0000000000 --- a/Userland/Libraries/LibJS/Runtime/ScopeObject.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <LibJS/Runtime/ScopeObject.h> -#include <LibJS/Runtime/VM.h> - -namespace JS { - -ScopeObject::ScopeObject(ScopeObject* parent) - : Object(vm().scope_object_shape()) - , m_parent(parent) -{ -} - -ScopeObject::ScopeObject(GlobalObjectTag tag) - : Object(tag) -{ -} - -void ScopeObject::visit_edges(Visitor& visitor) -{ - Base::visit_edges(visitor); - visitor.visit(m_parent); -} - -} diff --git a/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp index cfa0cdd5f7..fccf957d50 100644 --- a/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -35,7 +35,7 @@ static ScriptFunction* typed_this(VM& vm, GlobalObject& global_object) return static_cast<ScriptFunction*>(this_object); } -ScriptFunction* ScriptFunction::create(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, ScopeObject* parent_scope, FunctionKind kind, bool is_strict, bool is_arrow_function) +ScriptFunction* ScriptFunction::create(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, EnvironmentRecord* parent_scope, FunctionKind kind, bool is_strict, bool is_arrow_function) { Object* prototype = nullptr; switch (kind) { @@ -49,7 +49,7 @@ ScriptFunction* ScriptFunction::create(GlobalObject& global_object, const FlyStr return global_object.heap().allocate<ScriptFunction>(global_object, global_object, name, body, move(parameters), m_function_length, parent_scope, *prototype, kind, is_strict, is_arrow_function); } -ScriptFunction::ScriptFunction(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, ScopeObject* parent_scope, Object& prototype, FunctionKind kind, bool is_strict, bool is_arrow_function) +ScriptFunction::ScriptFunction(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, EnvironmentRecord* parent_scope, Object& prototype, FunctionKind kind, bool is_strict, bool is_arrow_function) : Function(is_arrow_function ? vm().this_value(global_object) : Value(), {}, prototype) , m_name(name) , m_body(body) @@ -93,7 +93,7 @@ void ScriptFunction::visit_edges(Visitor& visitor) visitor.visit(m_parent_scope); } -LexicalEnvironment* ScriptFunction::create_environment() +DeclarativeEnvironmentRecord* ScriptFunction::create_environment_record() { HashMap<FlyString, Variable> variables; for (auto& parameter : m_parameters) { @@ -122,12 +122,12 @@ LexicalEnvironment* ScriptFunction::create_environment() } } - auto* environment = heap().allocate<LexicalEnvironment>(global_object(), move(variables), m_parent_scope, LexicalEnvironment::EnvironmentRecordType::Function); + auto* environment = heap().allocate<DeclarativeEnvironmentRecord>(global_object(), move(variables), m_parent_scope, DeclarativeEnvironmentRecord::EnvironmentRecordType::Function); environment->set_home_object(home_object()); environment->set_current_function(*this); if (m_is_arrow_function) { - if (is<LexicalEnvironment>(m_parent_scope)) - environment->set_new_target(static_cast<LexicalEnvironment*>(m_parent_scope)->new_target()); + if (is<DeclarativeEnvironmentRecord>(m_parent_scope)) + environment->set_new_target(static_cast<DeclarativeEnvironmentRecord*>(m_parent_scope)->new_target()); } return environment; } @@ -191,7 +191,7 @@ Value ScriptFunction::execute_function_body() if (m_kind != FunctionKind::Generator) return result; - return GeneratorObject::create(global_object(), result, this, vm.call_frame().scope, bytecode_interpreter->snapshot_frame()); + return GeneratorObject::create(global_object(), result, this, vm.call_frame().environment_record, bytecode_interpreter->snapshot_frame()); } else { VERIFY(m_kind != FunctionKind::Generator); OwnPtr<Interpreter> local_interpreter; diff --git a/Userland/Libraries/LibJS/Runtime/ScriptFunction.h b/Userland/Libraries/LibJS/Runtime/ScriptFunction.h index f4d1f892f1..ab558c044d 100644 --- a/Userland/Libraries/LibJS/Runtime/ScriptFunction.h +++ b/Userland/Libraries/LibJS/Runtime/ScriptFunction.h @@ -16,9 +16,9 @@ class ScriptFunction final : public Function { JS_OBJECT(ScriptFunction, Function); public: - static ScriptFunction* create(GlobalObject&, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, ScopeObject* parent_scope, FunctionKind, bool is_strict, bool is_arrow_function = false); + static ScriptFunction* create(GlobalObject&, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, EnvironmentRecord* parent_scope, FunctionKind, bool is_strict, bool is_arrow_function = false); - ScriptFunction(GlobalObject&, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, ScopeObject* parent_scope, Object& prototype, FunctionKind, bool is_strict, bool is_arrow_function = false); + ScriptFunction(GlobalObject&, const FlyString& name, const Statement& body, Vector<FunctionNode::Parameter> parameters, i32 m_function_length, EnvironmentRecord* parent_scope, Object& prototype, FunctionKind, bool is_strict, bool is_arrow_function = false); virtual void initialize(GlobalObject&) override; virtual ~ScriptFunction(); @@ -39,7 +39,7 @@ protected: virtual bool is_strict_mode() const final { return m_is_strict; } private: - virtual LexicalEnvironment* create_environment() override; + virtual DeclarativeEnvironmentRecord* create_environment_record() override; virtual void visit_edges(Visitor&) override; Value execute_function_body(); @@ -51,7 +51,7 @@ private: NonnullRefPtr<Statement> m_body; const Vector<FunctionNode::Parameter> m_parameters; Optional<Bytecode::Executable> m_bytecode_executable; - ScopeObject* m_parent_scope { nullptr }; + EnvironmentRecord* m_parent_scope { nullptr }; i32 m_function_length { 0 }; FunctionKind m_kind { FunctionKind::Regular }; bool m_is_strict { false }; diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 17bc99b593..c8f297756d 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -37,7 +37,7 @@ VM::VM() m_single_ascii_character_strings[i] = m_heap.allocate_without_global_object<PrimitiveString>(String::formatted("{:c}", i)); } - m_scope_object_shape = m_heap.allocate_without_global_object<Shape>(Shape::ShapeWithoutGlobalObjectTag::Tag); + m_environment_record_shape = m_heap.allocate_without_global_object<Shape>(Shape::ShapeWithoutGlobalObjectTag::Tag); #define __JS_ENUMERATE(SymbolName, snake_name) \ m_well_known_symbol_##snake_name = js_symbol(*this, "Symbol." #SymbolName, false); @@ -91,7 +91,7 @@ void VM::gather_roots(HashTable<Cell*>& roots) for (auto* string : m_single_ascii_character_strings) roots.set(string); - roots.set(m_scope_object_shape); + roots.set(m_environment_record_shape); roots.set(m_exception); if (m_last_value.is_cell()) @@ -105,7 +105,7 @@ void VM::gather_roots(HashTable<Cell*>& roots) if (argument.is_cell()) roots.set(&argument.as_cell()); } - roots.set(call_frame->scope); + roots.set(call_frame->environment_record); } #define __JS_ENUMERATE(SymbolName, snake_name) \ @@ -131,7 +131,7 @@ Symbol* VM::get_global_symbol(const String& description) return new_global_symbol; } -void VM::set_variable(const FlyString& name, Value value, GlobalObject& global_object, bool first_assignment, ScopeObject* specific_scope) +void VM::set_variable(const FlyString& name, Value value, GlobalObject& global_object, bool first_assignment, EnvironmentRecord* specific_scope) { Optional<Variable> possible_match; if (!specific_scope && m_call_stack.size()) { @@ -164,7 +164,7 @@ void VM::set_variable(const FlyString& name, Value value, GlobalObject& global_o bool VM::delete_variable(FlyString const& name) { - ScopeObject* specific_scope = nullptr; + EnvironmentRecord* specific_scope = nullptr; Optional<Variable> possible_match; if (!m_call_stack.is_empty()) { for (auto* scope = current_scope(); scope; scope = scope->parent()) { @@ -185,12 +185,12 @@ bool VM::delete_variable(FlyString const& name) return specific_scope->delete_from_scope(name); } -void VM::assign(const FlyString& target, Value value, GlobalObject& global_object, bool first_assignment, ScopeObject* specific_scope) +void VM::assign(const FlyString& target, Value value, GlobalObject& global_object, bool first_assignment, EnvironmentRecord* specific_scope) { set_variable(target, move(value), global_object, first_assignment, specific_scope); } -void VM::assign(const Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>>& target, Value value, GlobalObject& global_object, bool first_assignment, ScopeObject* specific_scope) +void VM::assign(const Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>>& target, Value value, GlobalObject& global_object, bool first_assignment, EnvironmentRecord* specific_scope) { if (auto id_ptr = target.get_pointer<NonnullRefPtr<Identifier>>()) return assign((*id_ptr)->string(), move(value), global_object, first_assignment, specific_scope); @@ -198,7 +198,7 @@ void VM::assign(const Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPa assign(target.get<NonnullRefPtr<BindingPattern>>(), move(value), global_object, first_assignment, specific_scope); } -void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, GlobalObject& global_object, bool first_assignment, ScopeObject* specific_scope) +void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, GlobalObject& global_object, bool first_assignment, EnvironmentRecord* specific_scope) { auto& binding = *target; @@ -424,8 +424,8 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal call_frame.arguments = function.bound_arguments(); if (arguments.has_value()) call_frame.arguments.extend(arguments.value().values()); - auto* environment = function.create_environment(); - call_frame.scope = environment; + auto* environment = function.create_environment_record(); + call_frame.environment_record = environment; if (environment) environment->set_new_target(&new_target); @@ -460,8 +460,8 @@ Value VM::construct(Function& function, Function& new_target, Optional<MarkedVal // set the prototype on objects created by constructors that return an object (i.e. NativeFunction subclasses). if (function.constructor_kind() == Function::ConstructorKind::Base && new_target.constructor_kind() == Function::ConstructorKind::Derived && result.is_object()) { if (environment) { - VERIFY(is<LexicalEnvironment>(current_scope())); - static_cast<LexicalEnvironment*>(current_scope())->replace_this_binding(result); + VERIFY(is<DeclarativeEnvironmentRecord>(current_scope())); + static_cast<DeclarativeEnvironmentRecord*>(current_scope())->replace_this_binding(result); } auto prototype = new_target.get(names.prototype); if (exception()) @@ -505,7 +505,7 @@ Value VM::resolve_this_binding(GlobalObject& global_object) const return find_this_scope()->get_this_binding(global_object); } -const ScopeObject* VM::find_this_scope() const +const EnvironmentRecord* VM::find_this_scope() const { // We will always return because the Global environment will always be reached, which has a |this| binding. for (auto* scope = current_scope(); scope; scope = scope->parent()) { @@ -517,8 +517,8 @@ const ScopeObject* VM::find_this_scope() const Value VM::get_new_target() const { - VERIFY(is<LexicalEnvironment>(find_this_scope())); - return static_cast<const LexicalEnvironment*>(find_this_scope())->new_target(); + VERIFY(is<DeclarativeEnvironmentRecord>(find_this_scope())); + return static_cast<const DeclarativeEnvironmentRecord*>(find_this_scope())->new_target(); } Value VM::call_internal(Function& function, Value this_value, Optional<MarkedValueList> arguments) @@ -536,11 +536,11 @@ Value VM::call_internal(Function& function, Value this_value, Optional<MarkedVal call_frame.arguments = function.bound_arguments(); if (arguments.has_value()) call_frame.arguments.extend(arguments.value().values()); - auto* environment = function.create_environment(); - call_frame.scope = environment; + auto* environment = function.create_environment_record(); + call_frame.environment_record = environment; if (environment) { - VERIFY(environment->this_binding_status() == LexicalEnvironment::ThisBindingStatus::Uninitialized); + VERIFY(environment->this_binding_status() == DeclarativeEnvironmentRecord::ThisBindingStatus::Uninitialized); environment->bind_this_value(function.global_object(), call_frame.this_value); } @@ -626,9 +626,9 @@ void VM::dump_scope_chain() const { for (auto* scope = current_scope(); scope; scope = scope->parent()) { dbgln("+> {} ({:p})", scope->class_name(), scope); - if (is<LexicalEnvironment>(*scope)) { - auto& lexical_environment = static_cast<LexicalEnvironment const&>(*scope); - for (auto& variable : lexical_environment.variables()) { + if (is<DeclarativeEnvironmentRecord>(*scope)) { + auto& environment_record = static_cast<DeclarativeEnvironmentRecord const&>(*scope); + for (auto& variable : environment_record.variables()) { dbgln(" {}", variable.key); } } diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index ef2510cf21..fb47a002fb 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -49,7 +49,7 @@ struct CallFrame { Value this_value; Vector<Value> arguments; Array* arguments_object { nullptr }; - ScopeObject* scope { nullptr }; + EnvironmentRecord* environment_record { nullptr }; bool is_strict_mode { false }; }; @@ -122,8 +122,8 @@ public: const Vector<CallFrame*>& call_stack() const { return m_call_stack; } Vector<CallFrame*>& call_stack() { return m_call_stack; } - const ScopeObject* current_scope() const { return call_frame().scope; } - ScopeObject* current_scope() { return call_frame().scope; } + const EnvironmentRecord* current_scope() const { return call_frame().environment_record; } + EnvironmentRecord* current_scope() { return call_frame().environment_record; } bool in_strict_mode() const; @@ -192,11 +192,11 @@ public: FlyString unwind_until_label() const { return m_unwind_until_label; } Value get_variable(const FlyString& name, GlobalObject&); - void set_variable(const FlyString& name, Value, GlobalObject&, bool first_assignment = false, ScopeObject* specific_scope = nullptr); + void set_variable(const FlyString& name, Value, GlobalObject&, bool first_assignment = false, EnvironmentRecord* specific_scope = nullptr); bool delete_variable(FlyString const& name); - void assign(const Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>>& target, Value, GlobalObject&, bool first_assignment = false, ScopeObject* specific_scope = nullptr); - void assign(const FlyString& target, Value, GlobalObject&, bool first_assignment = false, ScopeObject* specific_scope = nullptr); - void assign(const NonnullRefPtr<BindingPattern>& target, Value, GlobalObject&, bool first_assignment = false, ScopeObject* specific_scope = nullptr); + void assign(const Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>>& target, Value, GlobalObject&, bool first_assignment = false, EnvironmentRecord* specific_scope = nullptr); + void assign(const FlyString& target, Value, GlobalObject&, bool first_assignment = false, EnvironmentRecord* specific_scope = nullptr); + void assign(const NonnullRefPtr<BindingPattern>& target, Value, GlobalObject&, bool first_assignment = false, EnvironmentRecord* specific_scope = nullptr); Reference get_reference(const FlyString& name); @@ -223,7 +223,7 @@ public: String join_arguments(size_t start_index = 0) const; Value resolve_this_binding(GlobalObject&) const; - const ScopeObject* find_this_scope() const; + const EnvironmentRecord* find_this_scope() const; Value get_new_target() const; template<typename... Args> @@ -240,7 +240,7 @@ public: CommonPropertyNames names; - Shape& scope_object_shape() { return *m_scope_object_shape; } + Shape& environment_record_shape() { return *m_environment_record_shape; } void run_queued_promise_jobs(); void enqueue_promise_job(NativeFunction&); @@ -286,7 +286,7 @@ private: JS_ENUMERATE_WELL_KNOWN_SYMBOLS #undef __JS_ENUMERATE - Shape* m_scope_object_shape { nullptr }; + Shape* m_environment_record_shape { nullptr }; bool m_underscore_is_last_value { false }; diff --git a/Userland/Libraries/LibJS/Runtime/WithScope.cpp b/Userland/Libraries/LibJS/Runtime/WithScope.cpp deleted file mode 100644 index bacda90a96..0000000000 --- a/Userland/Libraries/LibJS/Runtime/WithScope.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <LibJS/AST.h> -#include <LibJS/Runtime/WithScope.h> - -namespace JS { - -WithScope::WithScope(Object& object, ScopeObject* parent_scope) - : ScopeObject(parent_scope) - , m_object(object) -{ -} - -void WithScope::visit_edges(Cell::Visitor& visitor) -{ - Base::visit_edges(visitor); - visitor.visit(&m_object); -} - -Optional<Variable> WithScope::get_from_scope(const FlyString& name) const -{ - auto value = m_object.get(name); - if (value.is_empty()) - return {}; - return Variable { value, DeclarationKind::Var }; -} - -void WithScope::put_to_scope(const FlyString& name, Variable variable) -{ - m_object.put(name, variable.value); -} - -bool WithScope::delete_from_scope(FlyString const& name) -{ - return m_object.delete_property(name); -} - -bool WithScope::has_this_binding() const -{ - return parent()->has_this_binding(); -} - -Value WithScope::get_this_binding(GlobalObject& global_object) const -{ - return parent()->get_this_binding(global_object); -} - -} |