ladybird/Libraries/LibJS/Bytecode/Interpreter.h
Timothy Flynn 0efa98a57a LibJS+LibWeb+WebContent: Port JS::PropertyKey to UTF-16
This has quite a lot of fall out. But the majority of it is just type or
UDL substitution, where the changes just fall through to other function
calls.

By changing property key storage to UTF-16, the main affected areas are:
* NativeFunction names must now be UTF-16
* Bytecode identifiers must now be UTF-16
* Module/binding names must now be UTF-16
2025-08-05 07:07:15 -04:00

113 lines
3.9 KiB
C++

/*
* Copyright (c) 2021, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibJS/Bytecode/Executable.h>
#include <LibJS/Bytecode/Label.h>
#include <LibJS/Bytecode/Register.h>
#include <LibJS/Export.h>
#include <LibJS/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Runtime/FunctionKind.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/Runtime/Value.h>
namespace JS::Bytecode {
class InstructionStreamIterator;
class JS_API Interpreter {
public:
explicit Interpreter(VM&);
~Interpreter();
[[nodiscard]] Realm& realm() { return *m_realm; }
[[nodiscard]] Object& global_object() { return *m_global_object; }
[[nodiscard]] DeclarativeEnvironment& global_declarative_environment() { return *m_global_declarative_environment; }
VM& vm() { return m_vm; }
VM const& vm() const { return m_vm; }
ThrowCompletionOr<Value> run(Script&, GC::Ptr<Environment> lexical_environment_override = nullptr);
ThrowCompletionOr<Value> run(SourceTextModule&);
ThrowCompletionOr<Value> run(Bytecode::Executable& executable, Optional<size_t> entry_point = {}, Value initial_accumulator_value = js_special_empty_value())
{
auto result_and_return_register = run_executable(executable, entry_point, initial_accumulator_value);
return move(result_and_return_register.value);
}
struct ResultAndReturnRegister {
ThrowCompletionOr<Value> value;
Value return_register_value;
};
ResultAndReturnRegister run_executable(Bytecode::Executable&, Optional<size_t> entry_point, Value initial_accumulator_value = js_special_empty_value());
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 m_registers_and_constants_and_locals_arguments.data()[r.index()];
}
Value reg(Register const& r) const
{
return m_registers_and_constants_and_locals_arguments.data()[r.index()];
}
[[nodiscard]] Value get(Operand) const;
void set(Operand, Value);
Value do_yield(Value value, Optional<Label> continuation);
void do_return(Value value)
{
reg(Register::return_value()) = value;
reg(Register::exception()) = js_special_empty_value();
}
void enter_unwind_context();
void leave_unwind_context();
void catch_exception(Operand dst);
void restore_scheduled_jump();
void leave_finally();
void enter_object_environment(Object&);
Executable& current_executable() { return *m_current_executable; }
Executable const& current_executable() const { return *m_current_executable; }
Span<Value> allocate_argument_values(size_t argument_count)
{
m_argument_values_buffer.resize_and_keep_capacity(argument_count);
return m_argument_values_buffer.span();
}
ExecutionContext& running_execution_context() { return *m_running_execution_context; }
private:
void run_bytecode(size_t entry_point);
enum class HandleExceptionResponse {
ExitFromExecutable,
ContinueInThisExecutable,
};
[[nodiscard]] HandleExceptionResponse handle_exception(size_t& program_counter, Value exception);
VM& m_vm;
Optional<size_t> m_scheduled_jump;
GC::Ptr<Executable> m_current_executable { nullptr };
GC::Ptr<Realm> m_realm { nullptr };
GC::Ptr<Object> m_global_object { nullptr };
GC::Ptr<DeclarativeEnvironment> m_global_declarative_environment { nullptr };
Span<Value> m_registers_and_constants_and_locals_arguments;
Vector<Value> m_argument_values_buffer;
ExecutionContext* m_running_execution_context { nullptr };
};
JS_API extern bool g_dump_bytecode;
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM&, ASTNode const&, JS::FunctionKind kind, Utf16FlyString const& name);
ThrowCompletionOr<GC::Ref<Bytecode::Executable>> compile(VM&, ECMAScriptFunctionObject const&);
}