Explorar el Código

LibJS: Move [[ThisMode]] to ECMAScriptFunctionObject

Linus Groh hace 3 años
padre
commit
1e97a85095

+ 3 - 3
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) {

+ 9 - 0
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<FunctionNode::Parameter> 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<FunctionNode::Parameter> 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<FunctionNode::Parameter> const m_formal_parameters; // [[FormalParameters]]
     NonnullRefPtr<Statement> 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]]
 

+ 0 - 11
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<Value> 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<InstanceField> m_fields;
 };

+ 1 - 2
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<ECMAScriptFunctionObject>(function) && static_cast<ECMAScriptFunctionObject&>(function).this_mode() == ECMAScriptFunctionObject::ThisMode::Lexical)) {
         return;
     }