Przeglądaj źródła

LibJS/Bytecode: Don't generate ResolveThisBinding if not needed

Functions that don't have a FunctionEnvironment will get their `this`
value from the ExecutionContext. This patch stops generating
ResolveThisBinding instructions at all for functions like that, and
instead pre-populates the `this` register when entering a new bytecode
executable.
Andreas Kling 1 rok temu
rodzic
commit
e6b1e54c44

+ 7 - 0
Userland/Libraries/LibJS/Bytecode/Generator.cpp

@@ -1087,6 +1087,13 @@ ScopedOperand Generator::get_this(Optional<ScopedOperand> preferred_dst)
         m_current_basic_block->set_has_resolved_this();
         return this_value();
     }
+
+    // OPTIMIZATION: If we're compiling a function that doesn't allocate a FunctionEnvironment,
+    //               it will always have the same `this` value as the outer function,
+    //               and so the `this` value is already in the `this` register!
+    if (m_function && !m_function->allocates_function_environment())
+        return this_value();
+
     auto dst = preferred_dst.has_value() ? preferred_dst.value() : allocate_register();
     emit<Bytecode::Op::ResolveThisBinding>();
     m_current_basic_block->set_has_resolved_this();

+ 1 - 0
Userland/Libraries/LibJS/Bytecode/Interpreter.cpp

@@ -718,6 +718,7 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
 
     reg(Register::accumulator()) = initial_accumulator_value;
     reg(Register::return_value()) = {};
+    reg(Register::this_value()) = running_execution_context.this_value;
 
     running_execution_context.executable = &executable;