1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:28:11 +00:00

LibJS/Bytecode: Keep saved return value in call frame register

This fixes an issue where returning inside a `try` block and then
calling a function inside `finally` would clobber the saved return
value from the `try` block.

Note that we didn't need to change the base of register allocation,
since it was already 1 too high.

With this fixed, https://microsoft.com/edge loads in bytecode mode. :^)

Thanks to Luke for reducing the issue!
This commit is contained in:
Andreas Kling 2023-07-21 17:30:07 +02:00
parent 475f1b6083
commit 9f06e130a2
4 changed files with 26 additions and 10 deletions

View file

@ -61,6 +61,7 @@ public:
ValueAndFrame run_and_return_frame(Realm&, Bytecode::Executable&, Bytecode::BasicBlock const* entry_point, CallFrame* = nullptr);
ALWAYS_INLINE Value& accumulator() { return reg(Register::accumulator()); }
ALWAYS_INLINE Value& saved_return_value() { return reg(Register::saved_return_value()); }
Value& reg(Register const& r) { return registers()[r.index()]; }
auto& saved_lexical_environment_stack() { return call_frame().saved_lexical_environments; }
@ -119,7 +120,6 @@ private:
Optional<BasicBlock const*> m_pending_jump;
BasicBlock const* m_scheduled_jump { nullptr };
Optional<Value> m_return_value;
Optional<Value> m_saved_return_value;
Optional<Value> m_saved_exception;
Executable* m_current_executable { nullptr };
OwnPtr<JS::Interpreter> m_ast_interpreter;