mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 18:35:07 +00:00
LibJS/Bytecode: Perform ToNumeric on accumulator before postfix inc/dec
This ensures we get the expected behavior of code like: let a = [] let b = a++ (Where b should be 0, not [], because JavaScript.)
This commit is contained in:
parent
c9bd324369
commit
d364d99cb8
4 changed files with 26 additions and 0 deletions
|
@ -1966,6 +1966,7 @@ Bytecode::CodeGenerationErrorOr<void> UpdateExpression::generate_bytecode(Byteco
|
||||||
Optional<Bytecode::Register> previous_value_for_postfix_reg;
|
Optional<Bytecode::Register> previous_value_for_postfix_reg;
|
||||||
if (!m_prefixed) {
|
if (!m_prefixed) {
|
||||||
previous_value_for_postfix_reg = generator.allocate_register();
|
previous_value_for_postfix_reg = generator.allocate_register();
|
||||||
|
generator.emit<Bytecode::Op::ToNumeric>();
|
||||||
generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
|
generator.emit<Bytecode::Op::Store>(*previous_value_for_postfix_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
O(SuperCall) \
|
O(SuperCall) \
|
||||||
O(Throw) \
|
O(Throw) \
|
||||||
O(ThrowIfNotObject) \
|
O(ThrowIfNotObject) \
|
||||||
|
O(ToNumeric) \
|
||||||
O(Typeof) \
|
O(Typeof) \
|
||||||
O(TypeofVariable) \
|
O(TypeofVariable) \
|
||||||
O(UnaryMinus) \
|
O(UnaryMinus) \
|
||||||
|
|
|
@ -1091,6 +1091,12 @@ ThrowCompletionOr<void> TypeofVariable::execute_impl(Bytecode::Interpreter& inte
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThrowCompletionOr<void> ToNumeric::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
|
{
|
||||||
|
interpreter.accumulator() = TRY(interpreter.accumulator().to_numeric(interpreter.vm()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
DeprecatedString Load::to_deprecated_string_impl(Bytecode::Executable const&) const
|
DeprecatedString Load::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||||
{
|
{
|
||||||
return DeprecatedString::formatted("Load {}", m_src);
|
return DeprecatedString::formatted("Load {}", m_src);
|
||||||
|
@ -1448,4 +1454,9 @@ DeprecatedString TypeofVariable::to_deprecated_string_impl(Bytecode::Executable
|
||||||
return DeprecatedString::formatted("TypeofVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
|
return DeprecatedString::formatted("TypeofVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeprecatedString ToNumeric::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||||
|
{
|
||||||
|
return "ToNumeric"sv;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -835,6 +835,19 @@ public:
|
||||||
void replace_references_impl(Register, Register) { }
|
void replace_references_impl(Register, Register) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ToNumeric final : public Instruction {
|
||||||
|
public:
|
||||||
|
ToNumeric()
|
||||||
|
: Instruction(Type::ToNumeric)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
|
||||||
|
DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
|
||||||
|
void replace_references_impl(BasicBlock const&, BasicBlock const&) { }
|
||||||
|
void replace_references_impl(Register, Register) { }
|
||||||
|
};
|
||||||
|
|
||||||
class Throw final : public Instruction {
|
class Throw final : public Instruction {
|
||||||
public:
|
public:
|
||||||
constexpr static bool IsTerminator = true;
|
constexpr static bool IsTerminator = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue