diff --git a/Ladybird/BrowserWindow.cpp b/Ladybird/BrowserWindow.cpp index 5cd141f24e4..26cdfe12ab2 100644 --- a/Ladybird/BrowserWindow.cpp +++ b/Ladybird/BrowserWindow.cpp @@ -39,10 +39,11 @@ static QIcon const& app_icon() return icon; } -BrowserWindow::BrowserWindow(Browser::CookieJar& cookie_jar, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) +BrowserWindow::BrowserWindow(Browser::CookieJar& cookie_jar, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, WebView::UseJavaScriptBytecode use_javascript_bytecode) : m_cookie_jar(cookie_jar) , m_webdriver_content_ipc_path(webdriver_content_ipc_path) , m_enable_callgrind_profiling(enable_callgrind_profiling) + , m_use_javascript_bytecode(use_javascript_bytecode) { setWindowIcon(app_icon()); m_tabs_container = new QTabWidget(this); @@ -415,7 +416,7 @@ void BrowserWindow::debug_request(DeprecatedString const& request, DeprecatedStr Tab& BrowserWindow::new_tab(QString const& url, Web::HTML::ActivateTab activate_tab) { - auto tab = make(this, m_webdriver_content_ipc_path, m_enable_callgrind_profiling); + auto tab = make(this, m_webdriver_content_ipc_path, m_enable_callgrind_profiling, m_use_javascript_bytecode); auto tab_ptr = tab.ptr(); m_tabs.append(std::move(tab)); diff --git a/Ladybird/BrowserWindow.h b/Ladybird/BrowserWindow.h index e1ddf74de95..fd2197357e9 100644 --- a/Ladybird/BrowserWindow.h +++ b/Ladybird/BrowserWindow.h @@ -26,7 +26,7 @@ class CookieJar; class BrowserWindow : public QMainWindow { Q_OBJECT public: - explicit BrowserWindow(Browser::CookieJar&, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); + explicit BrowserWindow(Browser::CookieJar&, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, WebView::UseJavaScriptBytecode); WebContentView& view() const { return m_current_tab->view(); } @@ -115,4 +115,5 @@ private: StringView m_webdriver_content_ipc_path; WebView::EnableCallgrindProfiling m_enable_callgrind_profiling; + WebView::UseJavaScriptBytecode m_use_javascript_bytecode; }; diff --git a/Ladybird/ConsoleWidget.cpp b/Ladybird/ConsoleWidget.cpp index ce8abdf17d7..1115d7e722a 100644 --- a/Ladybird/ConsoleWidget.cpp +++ b/Ladybird/ConsoleWidget.cpp @@ -27,7 +27,7 @@ ConsoleWidget::ConsoleWidget() { setLayout(new QVBoxLayout); - m_output_view = new WebContentView({}, WebView::EnableCallgrindProfiling::No); + m_output_view = new WebContentView({}, WebView::EnableCallgrindProfiling::No, WebView::UseJavaScriptBytecode::No); if (is_using_dark_system_theme(*this)) m_output_view->update_palette(WebContentView::PaletteMode::Dark); diff --git a/Ladybird/Tab.cpp b/Ladybird/Tab.cpp index 975ff90e317..7a16f0f25fb 100644 --- a/Ladybird/Tab.cpp +++ b/Ladybird/Tab.cpp @@ -59,7 +59,7 @@ static QIcon render_svg_icon_with_theme_colors(QString name, QPalette const& pal return icon; } -Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) +Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, WebView::UseJavaScriptBytecode use_javascript_bytecode) : QWidget(window) , m_window(window) { @@ -67,7 +67,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: m_layout->setSpacing(0); m_layout->setContentsMargins(0, 0, 0, 0); - m_view = new WebContentView(webdriver_content_ipc_path, enable_callgrind_profiling); + m_view = new WebContentView(webdriver_content_ipc_path, enable_callgrind_profiling, use_javascript_bytecode); m_toolbar = new QToolBar(this); m_location_edit = new LocationEdit(this); m_reset_zoom_button = new QToolButton(m_toolbar); diff --git a/Ladybird/Tab.h b/Ladybird/Tab.h index 3616af597e6..1228eabff28 100644 --- a/Ladybird/Tab.h +++ b/Ladybird/Tab.h @@ -27,7 +27,7 @@ class InspectorWidget; class Tab final : public QWidget { Q_OBJECT public: - Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); + Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, WebView::UseJavaScriptBytecode); virtual ~Tab() override; WebContentView& view() { return *m_view; } diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index 74134853242..33430b415fe 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -69,12 +70,16 @@ ErrorOr serenity_main(Main::Arguments arguments) int webcontent_fd_passing_socket { -1 }; bool is_layout_test_mode = false; + bool use_javascript_bytecode = false; Core::ArgsParser args_parser; args_parser.add_option(webcontent_fd_passing_socket, "File descriptor of the passing socket for the WebContent connection", "webcontent-fd-passing-socket", 'c', "webcontent_fd_passing_socket"); args_parser.add_option(is_layout_test_mode, "Is layout test mode", "layout-test-mode", 0); + args_parser.add_option(use_javascript_bytecode, "Enable JavaScript bytecode VM", "use-bytecode", 0); args_parser.parse(arguments); + JS::Bytecode::Interpreter::set_enabled(use_javascript_bytecode); + VERIFY(webcontent_fd_passing_socket >= 0); Web::Platform::FontPlugin::install(*new Ladybird::FontPluginQt(is_layout_test_mode)); diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 3b73ec9fded..835c121bb8f 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -51,7 +51,7 @@ bool is_using_dark_system_theme(QWidget&); -WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) +WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, WebView::UseJavaScriptBytecode use_javascript_bytecode) : m_webdriver_content_ipc_path(webdriver_content_ipc_path) { setMouseTracking(true); @@ -72,7 +72,7 @@ WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::E update_viewport_rect(); }); - create_client(enable_callgrind_profiling); + create_client(enable_callgrind_profiling, use_javascript_bytecode); } WebContentView::~WebContentView() = default; @@ -512,12 +512,12 @@ void WebContentView::update_palette(PaletteMode mode) client().async_update_system_theme(make_system_theme_from_qt_palette(*this, mode)); } -void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_callgrind_profiling) +void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_callgrind_profiling, WebView::UseJavaScriptBytecode use_javascript_bytecode) { m_client_state = {}; auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); - auto new_client = launch_web_content_process(candidate_web_content_paths, enable_callgrind_profiling).release_value_but_fixme_should_propagate_errors(); + auto new_client = launch_web_content_process(candidate_web_content_paths, enable_callgrind_profiling, WebView::IsLayoutTestMode::No, use_javascript_bytecode).release_value_but_fixme_should_propagate_errors(); m_client_state.client = new_client; m_client_state.client->on_web_content_process_crash = [this] { diff --git a/Ladybird/WebContentView.h b/Ladybird/WebContentView.h index 5d0ff0c668b..0a7dbba982e 100644 --- a/Ladybird/WebContentView.h +++ b/Ladybird/WebContentView.h @@ -39,7 +39,7 @@ class WebContentView final , public WebView::ViewImplementation { Q_OBJECT public: - explicit WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); + explicit WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, WebView::UseJavaScriptBytecode); virtual ~WebContentView() override; Function on_tab_open_request; @@ -96,7 +96,7 @@ signals: private: // ^WebView::ViewImplementation - virtual void create_client(WebView::EnableCallgrindProfiling = WebView::EnableCallgrindProfiling::No) override; + virtual void create_client(WebView::EnableCallgrindProfiling = WebView::EnableCallgrindProfiling::No, WebView::UseJavaScriptBytecode = WebView::UseJavaScriptBytecode::No) override; virtual void update_zoom() override; virtual Gfx::IntRect viewport_rect() const override; virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const override; diff --git a/Ladybird/main.cpp b/Ladybird/main.cpp index 739e631df86..8332c9351e8 100644 --- a/Ladybird/main.cpp +++ b/Ladybird/main.cpp @@ -70,6 +70,7 @@ ErrorOr serenity_main(Main::Arguments arguments) StringView webdriver_content_ipc_path; bool enable_callgrind_profiling = false; bool enable_sql_database = false; + bool use_javascript_bytecode = false; Core::ArgsParser args_parser; args_parser.set_general_help("The Ladybird web browser :^)"); @@ -77,6 +78,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path"); args_parser.add_option(enable_callgrind_profiling, "Enable Callgrind profiling", "enable-callgrind-profiling", 'P'); args_parser.add_option(enable_sql_database, "Enable SQL database", "enable-sql-database", 0); + args_parser.add_option(use_javascript_bytecode, "Enable JavaScript bytecode VM", "use-bytecode", 0); args_parser.parse(arguments); auto get_formatted_url = [&](StringView const& raw_url) -> ErrorOr { @@ -99,7 +101,7 @@ ErrorOr serenity_main(Main::Arguments arguments) auto cookie_jar = database ? TRY(Browser::CookieJar::create(*database)) : Browser::CookieJar::create(); s_settings = adopt_own_if_nonnull(new Browser::Settings()); - BrowserWindow window(cookie_jar, webdriver_content_ipc_path, enable_callgrind_profiling ? WebView::EnableCallgrindProfiling::Yes : WebView::EnableCallgrindProfiling::No); + BrowserWindow window(cookie_jar, webdriver_content_ipc_path, enable_callgrind_profiling ? WebView::EnableCallgrindProfiling::Yes : WebView::EnableCallgrindProfiling::No, use_javascript_bytecode ? WebView::UseJavaScriptBytecode::Yes : WebView::UseJavaScriptBytecode::No); window.setWindowTitle("Ladybird"); window.resize(800, 600); window.show(); diff --git a/Tests/LibJS/test-bytecode-js.cpp b/Tests/LibJS/test-bytecode-js.cpp index 1ab808e2e14..833c42419b3 100644 --- a/Tests/LibJS/test-bytecode-js.cpp +++ b/Tests/LibJS/test-bytecode-js.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/Tests/LibJS/test262-runner.cpp b/Tests/LibJS/test262-runner.cpp index 38b06f14e27..4ea77aa01d1 100644 --- a/Tests/LibJS/test262-runner.cpp +++ b/Tests/LibJS/test262-runner.cpp @@ -32,7 +32,6 @@ #endif static DeprecatedString s_current_test = ""; -static bool s_use_bytecode = false; static bool s_enable_bytecode_optimizations = false; static bool s_parse_only = false; static DeprecatedString s_harness_file_directory; @@ -217,11 +216,11 @@ static Result run_test(StringView source, StringView filepath, return program_or_error.release_error(); OwnPtr bytecode_interpreter = nullptr; - if (s_use_bytecode) + if (JS::Bytecode::Interpreter::enabled()) bytecode_interpreter = make(realm); auto run_with_interpreter = [&](ScriptOrModuleProgram& program) { - if (s_use_bytecode) + if (JS::Bytecode::Interpreter::enabled()) return run_program(*bytecode_interpreter, program); return run_program(*ast_interpreter, program); }; @@ -572,11 +571,12 @@ int main(int argc, char** argv) int timeout = 10; bool enable_debug_printing = false; bool disable_core_dumping = false; + bool use_bytecode = false; Core::ArgsParser args_parser; args_parser.set_general_help("LibJS test262 runner for streaming tests"); args_parser.add_option(s_harness_file_directory, "Directory containing the harness files", "harness-location", 'l', "harness-files"); - args_parser.add_option(s_use_bytecode, "Use the bytecode interpreter", "use-bytecode", 'b'); + args_parser.add_option(use_bytecode, "Use the bytecode interpreter", "use-bytecode", 'b'); args_parser.add_option(s_enable_bytecode_optimizations, "Enable the bytecode optimization passes", "enable-bytecode-optimizations", 'e'); args_parser.add_option(s_parse_only, "Only parse the files", "parse-only", 'p'); args_parser.add_option(timeout, "Seconds before test should timeout", "timeout", 't', "seconds"); @@ -584,6 +584,8 @@ int main(int argc, char** argv) args_parser.add_option(disable_core_dumping, "Disable core dumping", "disable-core-dump", 0); args_parser.parse(arguments); + JS::Bytecode::Interpreter::set_enabled(use_bytecode); + #if !defined(AK_OS_MACOS) && !defined(AK_OS_EMSCRIPTEN) if (disable_core_dumping && prctl(PR_SET_DUMPABLE, 0, 0) < 0) { perror("prctl(PR_SET_DUMPABLE)"); diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 9574711384b..2fe1dbcda71 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -8,9 +8,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -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()); +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.h b/Userland/Libraries/LibJS/Bytecode/Interpreter.h index bd511ae9a19..a3b05bb966e 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.h +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.h @@ -6,8 +6,6 @@ #pragma once -#include "Generator.h" -#include "PassManager.h" #include #include #include @@ -18,6 +16,9 @@ namespace JS::Bytecode { +class InstructionStreamIterator; +class PassManager; + struct RegisterWindow { MarkedVector registers; MarkedVector> 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, diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index ab1f1407c29..d98c747cffa 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index 4b118c33b21..c4beae208b8 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -1,11 +1,12 @@ /* - * Copyright (c) 2021-2022, Andreas Kling + * Copyright (c) 2021-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include +#include #include #include #include @@ -94,9 +95,13 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, JS::GCPtrrealm()); - - 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. diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp index 97a7c43b523..fcc778bf85c 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp @@ -35,7 +35,7 @@ OutOfProcessWebView::OutOfProcessWebView() OutOfProcessWebView::~OutOfProcessWebView() = default; -void OutOfProcessWebView::create_client(EnableCallgrindProfiling) +void OutOfProcessWebView::create_client(EnableCallgrindProfiling, UseJavaScriptBytecode) { m_client_state = {}; diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h index 56ea39aa65c..b8d1a916fc6 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h @@ -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, Gfx::IntSize content_size) override; virtual void notify_server_did_paint(Badge, i32 bitmap_id, Gfx::IntSize) override; diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index e45c84353a7..10901a10fcd 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -179,7 +179,7 @@ void ViewImplementation::handle_resize() #if !defined(AK_OS_SERENITY) -ErrorOr> ViewImplementation::launch_web_content_process(ReadonlySpan candidate_web_content_paths, EnableCallgrindProfiling enable_callgrind_profiling, IsLayoutTestMode is_layout_test_mode) +ErrorOr> ViewImplementation::launch_web_content_process(ReadonlySpan 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> 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()) diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 070a623d664..c326007931f 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -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> launch_web_content_process(ReadonlySpan candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No); + ErrorOr> launch_web_content_process(ReadonlySpan candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No, IsLayoutTestMode = IsLayoutTestMode::No, UseJavaScriptBytecode = UseJavaScriptBytecode::No); #endif void handle_web_content_process_crash(); diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index ba4105f58a1..e1ebbb48ba7 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -46,16 +46,17 @@ class HeadlessWebContentView final : public WebView::ViewImplementation { public: - static ErrorOr> create(Core::AnonymousBuffer theme, Gfx::IntSize const& window_size, StringView web_driver_ipc_path, WebView::IsLayoutTestMode is_layout_test_mode = WebView::IsLayoutTestMode::No) + static ErrorOr> create(Core::AnonymousBuffer theme, Gfx::IntSize const& window_size, StringView web_driver_ipc_path, WebView::IsLayoutTestMode is_layout_test_mode = WebView::IsLayoutTestMode::No, WebView::UseJavaScriptBytecode use_javascript_bytecode = WebView::UseJavaScriptBytecode::No) { auto view = TRY(adopt_nonnull_own_or_enomem(new (nothrow) HeadlessWebContentView())); #if defined(AK_OS_SERENITY) view->m_client_state.client = TRY(WebView::WebContentClient::try_create(*view)); (void)is_layout_test_mode; + (void)use_javascript_bytecode; #else auto candidate_web_content_paths = TRY(get_paths_for_helper_process("WebContent"sv)); - view->m_client_state.client = TRY(view->launch_web_content_process(candidate_web_content_paths, WebView::EnableCallgrindProfiling::No, is_layout_test_mode)); + view->m_client_state.client = TRY(view->launch_web_content_process(candidate_web_content_paths, WebView::EnableCallgrindProfiling::No, is_layout_test_mode, use_javascript_bytecode)); #endif view->client().async_update_system_theme(move(theme)); @@ -123,7 +124,7 @@ private: void notify_server_did_finish_handling_input_event(bool) override { } void update_zoom() override { } - void create_client(WebView::EnableCallgrindProfiling) override { } + void create_client(WebView::EnableCallgrindProfiling, WebView::UseJavaScriptBytecode) override { } virtual Gfx::IntRect viewport_rect() const override { return m_viewport_rect; } virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const override { return widget_position; } @@ -396,6 +397,7 @@ ErrorOr serenity_main(Main::Arguments arguments) bool dump_layout_tree = false; bool dump_text = false; bool is_layout_test_mode = false; + bool use_javascript_bytecode = false; StringView test_root_path; Core::ArgsParser args_parser; @@ -407,6 +409,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(resources_folder, "Path of the base resources folder (defaults to /res)", "resources", 'r', "resources-root-path"); args_parser.add_option(web_driver_ipc_path, "Path to the WebDriver IPC socket", "webdriver-ipc-path", 0, "path"); args_parser.add_option(is_layout_test_mode, "Enable layout test mode", "layout-test-mode", 0); + args_parser.add_option(use_javascript_bytecode, "Enable JavaScript bytecode VM", "use-bytecode", 0); args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::No); args_parser.parse(arguments); @@ -428,7 +431,7 @@ ErrorOr serenity_main(Main::Arguments arguments) is_layout_test_mode = true; } - auto view = TRY(HeadlessWebContentView::create(move(theme), window_size, web_driver_ipc_path, is_layout_test_mode ? WebView::IsLayoutTestMode::Yes : WebView::IsLayoutTestMode::No)); + auto view = TRY(HeadlessWebContentView::create(move(theme), window_size, web_driver_ipc_path, is_layout_test_mode ? WebView::IsLayoutTestMode::Yes : WebView::IsLayoutTestMode::No, use_javascript_bytecode ? WebView::UseJavaScriptBytecode::Yes : WebView::UseJavaScriptBytecode::No)); RefPtr timer; if (!test_root_path.is_empty()) {