mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:47:36 +00:00
Ladybird+LibJS: Add CLI option to run browser with LibJS bytecode VM
This required quite a bit of plumbing, but now you can run ladybird --use-bytecode
This commit is contained in:
parent
7ec7015750
commit
9c568282dc
20 changed files with 91 additions and 38 deletions
|
@ -8,9 +8,11 @@
|
|||
#include <AK/TemporaryChange.h>
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Bytecode/BasicBlock.h>
|
||||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Instruction.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Bytecode/Op.h>
|
||||
#include <LibJS/Bytecode/PassManager.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/GlobalEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
|
@ -18,6 +20,18 @@
|
|||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
static bool s_bytecode_interpreter_enabled = false;
|
||||
|
||||
bool Interpreter::enabled()
|
||||
{
|
||||
return s_bytecode_interpreter_enabled;
|
||||
}
|
||||
|
||||
void Interpreter::set_enabled(bool enabled)
|
||||
{
|
||||
s_bytecode_interpreter_enabled = enabled;
|
||||
}
|
||||
|
||||
static Interpreter* s_current;
|
||||
bool g_dump_bytecode = false;
|
||||
|
||||
|
@ -425,4 +439,14 @@ Bytecode::PassManager& Interpreter::optimization_pipeline(Interpreter::Optimizat
|
|||
return passes;
|
||||
}
|
||||
|
||||
size_t Interpreter::pc() const
|
||||
{
|
||||
return m_pc ? m_pc->offset() : 0;
|
||||
}
|
||||
|
||||
DeprecatedString Interpreter::debug_position() const
|
||||
{
|
||||
return DeprecatedString::formatted("{}:{:2}:{:4x}", m_current_executable->name, m_current_block->name(), pc());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Generator.h"
|
||||
#include "PassManager.h"
|
||||
#include <LibJS/Bytecode/Label.h>
|
||||
#include <LibJS/Bytecode/Register.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
@ -18,6 +16,9 @@
|
|||
|
||||
namespace JS::Bytecode {
|
||||
|
||||
class InstructionStreamIterator;
|
||||
class PassManager;
|
||||
|
||||
struct RegisterWindow {
|
||||
MarkedVector<Value> registers;
|
||||
MarkedVector<GCPtr<Environment>> saved_lexical_environments;
|
||||
|
@ -27,6 +28,9 @@ struct RegisterWindow {
|
|||
|
||||
class Interpreter {
|
||||
public:
|
||||
[[nodiscard]] static bool enabled();
|
||||
static void set_enabled(bool);
|
||||
|
||||
explicit Interpreter(Realm&);
|
||||
~Interpreter();
|
||||
|
||||
|
@ -82,11 +86,8 @@ public:
|
|||
|
||||
Executable const& current_executable() { return *m_current_executable; }
|
||||
BasicBlock const& current_block() const { return *m_current_block; }
|
||||
size_t pc() const { return m_pc ? m_pc->offset() : 0; }
|
||||
DeprecatedString debug_position()
|
||||
{
|
||||
return DeprecatedString::formatted("{}:{:2}:{:4x}", m_current_executable->name, m_current_block->name(), pc());
|
||||
}
|
||||
size_t pc() const;
|
||||
DeprecatedString debug_position() const;
|
||||
|
||||
enum class OptimizationLevel {
|
||||
None,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <LibJS/Bytecode/BasicBlock.h>
|
||||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Bytecode/PassManager.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Debug.h>
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
||||
|
@ -94,9 +95,13 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtr<JS::En
|
|||
auto timer = Core::ElapsedTimer::start_new();
|
||||
|
||||
// 6. Otherwise, set evaluationStatus to ScriptEvaluation(script's record).
|
||||
auto interpreter = JS::Interpreter::create_with_existing_realm(m_script_record->realm());
|
||||
|
||||
evaluation_status = interpreter->run(*m_script_record, lexical_environment_override);
|
||||
if (JS::Bytecode::Interpreter::enabled()) {
|
||||
auto interpreter = JS::Bytecode::Interpreter(m_script_record->realm());
|
||||
evaluation_status = interpreter.run(*m_script_record, lexical_environment_override);
|
||||
} else {
|
||||
auto interpreter = JS::Interpreter::create_with_existing_realm(m_script_record->realm());
|
||||
evaluation_status = interpreter->run(*m_script_record, lexical_environment_override);
|
||||
}
|
||||
|
||||
// FIXME: If ScriptEvaluation does not complete because the user agent has aborted the running script, leave evaluationStatus as null.
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ OutOfProcessWebView::OutOfProcessWebView()
|
|||
|
||||
OutOfProcessWebView::~OutOfProcessWebView() = default;
|
||||
|
||||
void OutOfProcessWebView::create_client(EnableCallgrindProfiling)
|
||||
void OutOfProcessWebView::create_client(EnableCallgrindProfiling, UseJavaScriptBytecode)
|
||||
{
|
||||
m_client_state = {};
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ private:
|
|||
virtual void did_scroll() override;
|
||||
|
||||
// ^WebView::ViewImplementation
|
||||
virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No) override;
|
||||
virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No, UseJavaScriptBytecode = UseJavaScriptBytecode::No) override;
|
||||
virtual void update_zoom() override;
|
||||
virtual void notify_server_did_layout(Badge<WebContentClient>, Gfx::IntSize content_size) override;
|
||||
virtual void notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize) override;
|
||||
|
|
|
@ -179,7 +179,7 @@ void ViewImplementation::handle_resize()
|
|||
|
||||
#if !defined(AK_OS_SERENITY)
|
||||
|
||||
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling enable_callgrind_profiling, IsLayoutTestMode is_layout_test_mode)
|
||||
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling enable_callgrind_profiling, IsLayoutTestMode is_layout_test_mode, UseJavaScriptBytecode use_javascript_bytecode)
|
||||
{
|
||||
int socket_fds[2] {};
|
||||
TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds));
|
||||
|
@ -221,6 +221,8 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web
|
|||
arguments.remove(0, callgrind_prefix_length);
|
||||
if (is_layout_test_mode == IsLayoutTestMode::Yes)
|
||||
arguments.append("--layout-test-mode"sv);
|
||||
if (use_javascript_bytecode == UseJavaScriptBytecode::Yes)
|
||||
arguments.append("--use-bytecode"sv);
|
||||
|
||||
result = Core::System::exec(arguments[0], arguments.span(), Core::System::SearchInPath::Yes);
|
||||
if (!result.is_error())
|
||||
|
|
|
@ -30,6 +30,11 @@ enum class IsLayoutTestMode {
|
|||
Yes
|
||||
};
|
||||
|
||||
enum class UseJavaScriptBytecode {
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
|
||||
class ViewImplementation {
|
||||
public:
|
||||
virtual ~ViewImplementation() { }
|
||||
|
@ -167,10 +172,10 @@ protected:
|
|||
void request_repaint();
|
||||
void handle_resize();
|
||||
|
||||
virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No) {};
|
||||
virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No, UseJavaScriptBytecode = UseJavaScriptBytecode::No) { }
|
||||
|
||||
#if !defined(AK_OS_SERENITY)
|
||||
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No);
|
||||
ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No, UseJavaScriptBytecode = UseJavaScriptBytecode::No);
|
||||
#endif
|
||||
|
||||
void handle_web_content_process_crash();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue