diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index bf00c10586..28deabee52 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -51,11 +51,11 @@ ECMAScriptFunctionObject::ECMAScriptFunctionObject(GlobalObject& global_object, { // NOTE: This logic is from OrdinaryFunctionCreate, https://tc39.es/ecma262/#sec-ordinaryfunctioncreate if (m_is_arrow_function) - set_this_mode(ThisMode::Lexical); + m_this_mode = ThisMode::Lexical; else if (m_strict) - set_this_mode(ThisMode::Strict); + m_this_mode = ThisMode::Strict; else - set_this_mode(ThisMode::Global); + m_this_mode = ThisMode::Global; // 15.1.3 Static Semantics: IsSimpleParameterList, https://tc39.es/ecma262/#sec-static-semantics-issimpleparameterlist set_has_simple_parameter_list(all_of(m_formal_parameters, [&](auto& parameter) { diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index b609bf6ba2..b863ed8de5 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -17,6 +17,12 @@ class ECMAScriptFunctionObject final : public FunctionObject { JS_OBJECT(ECMAScriptFunctionObject, FunctionObject); public: + enum class ThisMode : u8 { + Lexical, + Strict, + Global, + }; + static ECMAScriptFunctionObject* create(GlobalObject&, FlyString name, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, FunctionKind, bool is_strict, bool is_arrow_function = false); ECMAScriptFunctionObject(GlobalObject&, FlyString name, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_scope, Object& prototype, FunctionKind, bool is_strict, bool is_arrow_function = false); @@ -39,6 +45,8 @@ public: virtual Environment* environment() override { return m_environment; } virtual Realm* realm() const override { return m_realm; } + ThisMode this_mode() const { return m_this_mode; } + protected: virtual bool is_strict_mode() const final { return m_strict; } @@ -54,6 +62,7 @@ private: Vector const m_formal_parameters; // [[FormalParameters]] NonnullRefPtr m_ecmascript_code; // [[ECMAScriptCode]] Realm* m_realm { nullptr }; // [[Realm]] + ThisMode m_this_mode { ThisMode::Global }; // [[ThisMode]] bool m_strict { false }; // [[Strict]] bool m_is_class_constructor { false }; // [[IsClassConstructor]] diff --git a/Userland/Libraries/LibJS/Runtime/FunctionObject.h b/Userland/Libraries/LibJS/Runtime/FunctionObject.h index 3d4f53073a..a3bf54b316 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionObject.h @@ -50,16 +50,6 @@ public: // [[Realm]] virtual Realm* realm() const { return nullptr; } - enum class ThisMode : u8 { - Lexical, - Strict, - Global, - }; - - // [[ThisMode]] - ThisMode this_mode() const { return m_this_mode; } - void set_this_mode(ThisMode this_mode) { m_this_mode = this_mode; } - // This is for IsSimpleParameterList (static semantics) bool has_simple_parameter_list() const { return m_has_simple_parameter_list; } @@ -88,7 +78,6 @@ private: Vector m_bound_arguments; Object* m_home_object { nullptr }; ConstructorKind m_constructor_kind = ConstructorKind::Base; - ThisMode m_this_mode { ThisMode::Global }; bool m_has_simple_parameter_list { false }; Vector m_fields; }; diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 1490525d8a..aaca0f127b 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -636,7 +636,6 @@ void VM::prepare_for_ordinary_call(FunctionObject& function, ExecutionContext& c // 10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument ), https://tc39.es/ecma262/#sec-ordinarycallbindthis void VM::ordinary_call_bind_this(FunctionObject& function, ExecutionContext& callee_context, Value this_argument) { - auto this_mode = function.this_mode(); auto* callee_realm = function.realm(); auto* local_environment = callee_context.lexical_environment; @@ -644,7 +643,7 @@ void VM::ordinary_call_bind_this(FunctionObject& function, ExecutionContext& cal // This almost as the spec describes it however we sometimes don't have callee_realm when dealing // with proxies and arrow functions however this does seemingly achieve spec like behavior. - if (!callee_realm || this_mode == FunctionObject::ThisMode::Lexical) { + if (!callee_realm || (is(function) && static_cast(function).this_mode() == ECMAScriptFunctionObject::ThisMode::Lexical)) { return; }