LibJS/Bytecode: Only emit ResolveThisBinding once per basic block

Once executed, this instruction will always produce the same result
in subsequent executions, so it's okay to cache it.

Unfortunately it may throw, so we can't just hoist it to the top of
every executable, since that would break observable execution order.
This commit is contained in:
Andreas Kling 2024-05-07 12:16:37 +02:00
commit 0f70ff9a67
Notes: sideshowbarker 2024-07-17 08:43:11 +09:00
4 changed files with 21 additions and 7 deletions

View file

@ -426,8 +426,7 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> AssignmentExpressio
// https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation
// 1. Let env be GetThisEnvironment().
// 2. Let actualThis be ? env.GetThisBinding().
this_value = Bytecode::Operand(generator.allocate_register());
generator.emit<Bytecode::Op::ResolveThisBinding>(*this_value);
this_value = generator.get_this();
// SuperProperty : super [ Expression ]
// 3. Let propertyNameReference be ? Evaluation of Expression.
@ -1486,8 +1485,7 @@ static Bytecode::CodeGenerationErrorOr<BaseAndValue> get_base_and_value_from_mem
if (is<SuperExpression>(member_expression.object())) {
// 1. Let env be GetThisEnvironment().
// 2. Let actualThis be ? env.GetThisBinding().
auto this_value = Bytecode::Operand(generator.allocate_register());
generator.emit<Bytecode::Op::ResolveThisBinding>(this_value);
auto this_value = generator.get_this();
Optional<Bytecode::Operand> computed_property;
@ -2718,9 +2716,7 @@ Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> SpreadExpression::g
Bytecode::CodeGenerationErrorOr<Optional<Bytecode::Operand>> ThisExpression::generate_bytecode(Bytecode::Generator& generator, Optional<Bytecode::Operand> preferred_dst) const
{
Bytecode::Generator::SourceLocationScope scope(generator, *this);
auto dst = choose_dst(generator, preferred_dst);
generator.emit<Bytecode::Op::ResolveThisBinding>(dst);
return dst;
return generator.get_this(preferred_dst);
}
static Bytecode::Operand generate_await(