mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-03 23:25:20 +00:00
This kills 2 birds with one stone: 1. It makes sure generated check_exception() calls in the finalizer don't mis-read the pending exception as caused by their matching operation. 2. It implicitly ensures that terminated finally blocks (by a return statement) overwrite any pending exceptions, since they will never execute the ContinuePendingUnwind operation that restores the stashed exception. This additional logic is required in the JIT (as opposed to the interpreter), since the JIT uses the exception register to store and check the possibly-exceptional results from each individual operation, while the interpreter only modifies it when an operation has thrown an exception.
80 lines
1.8 KiB
C++
80 lines
1.8 KiB
C++
/*
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Format.h>
|
|
|
|
namespace JS::Bytecode {
|
|
|
|
class Register {
|
|
public:
|
|
constexpr static u32 accumulator_index = 0;
|
|
|
|
static constexpr Register accumulator()
|
|
{
|
|
return Register(accumulator_index);
|
|
}
|
|
|
|
constexpr static u32 saved_return_value_index = 1;
|
|
|
|
static constexpr Register saved_return_value()
|
|
{
|
|
return Register(saved_return_value_index);
|
|
}
|
|
|
|
static constexpr u32 exception_index = 2;
|
|
|
|
static constexpr Register exception()
|
|
{
|
|
return Register(exception_index);
|
|
}
|
|
|
|
static constexpr Register this_value()
|
|
{
|
|
constexpr u32 this_value_index = 3;
|
|
return Register(this_value_index);
|
|
}
|
|
|
|
static constexpr Register return_value()
|
|
{
|
|
constexpr u32 return_value_index = 4;
|
|
return Register(return_value_index);
|
|
}
|
|
|
|
static constexpr Register saved_exception()
|
|
{
|
|
constexpr u32 saved_exception_index = 5;
|
|
return Register(saved_exception_index);
|
|
}
|
|
|
|
static constexpr u32 reserved_register_count = 6;
|
|
|
|
constexpr explicit Register(u32 index)
|
|
: m_index(index)
|
|
{
|
|
}
|
|
|
|
constexpr bool operator==(Register reg) const { return m_index == reg.index(); }
|
|
|
|
constexpr u32 index() const { return m_index; }
|
|
|
|
private:
|
|
u32 m_index;
|
|
};
|
|
|
|
}
|
|
|
|
template<>
|
|
struct AK::Formatter<JS::Bytecode::Register> : AK::Formatter<FormatString> {
|
|
ErrorOr<void> format(FormatBuilder& builder, JS::Bytecode::Register const& value)
|
|
{
|
|
if (value.index() == JS::Bytecode::Register::accumulator_index)
|
|
return builder.put_string("acc"sv);
|
|
return AK::Formatter<FormatString>::format(builder, "${}"sv, value.index());
|
|
}
|
|
};
|