mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-10 17:12:41 +02:00
Split Rust program compilation so code generation and assembly finish before the main thread materializes GC-backed executable objects. The new CompiledProgram handle owns the parsed program, generator state, and bytecode until C++ consumes it on the main thread. Wire WebContent script fetching through that handle for classic scripts and modules. Syntax-error paths still return ParsedProgram, so existing error reporting stays in place. Successful fetches now do top-level codegen on the thread pool before deferred_invoke hands control back to the main thread. Executable creation, SharedFunctionInstanceData materialization, module metadata extraction, and declaration data extraction still run on the main thread where VM and GC access is valid.
108 lines
3.4 KiB
C++
108 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2021-2022, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashTable.h>
|
|
#include <AK/Utf16FlyString.h>
|
|
#include <LibGC/Ptr.h>
|
|
#include <LibGC/Root.h>
|
|
#include <LibJS/Export.h>
|
|
#include <LibJS/Forward.h>
|
|
#include <LibJS/ParserError.h>
|
|
#include <LibJS/Runtime/Realm.h>
|
|
|
|
namespace JS {
|
|
|
|
JS_API extern bool g_dump_ast;
|
|
JS_API extern bool g_dump_ast_use_color;
|
|
|
|
namespace FFI {
|
|
|
|
struct ParsedProgram;
|
|
struct CompiledProgram;
|
|
|
|
}
|
|
|
|
namespace RustIntegration {
|
|
|
|
struct ScriptResult;
|
|
|
|
}
|
|
|
|
// 16.1.4 Script Records, https://tc39.es/ecma262/#sec-script-records
|
|
class JS_API Script final : public Cell {
|
|
GC_CELL(Script, Cell);
|
|
GC_DECLARE_ALLOCATOR(Script);
|
|
|
|
public:
|
|
struct HostDefined {
|
|
virtual ~HostDefined() = default;
|
|
|
|
virtual void visit_host_defined_self(Cell::Visitor&) = 0;
|
|
|
|
template<typename T>
|
|
bool fast_is() const = delete;
|
|
|
|
virtual bool is_script() const { return false; }
|
|
virtual bool is_classic_script() const { return false; }
|
|
virtual bool is_module_script() const { return false; }
|
|
};
|
|
|
|
virtual ~Script() override;
|
|
static Result<GC::Ref<Script>, Vector<ParserError>> parse(StringView source_text, Realm&, StringView filename = {}, HostDefined* = nullptr, size_t line_number_offset = 1);
|
|
static Result<GC::Ref<Script>, Vector<ParserError>> create_from_parsed(FFI::ParsedProgram* parsed, NonnullRefPtr<SourceCode const> source_code, Realm&, HostDefined* = nullptr);
|
|
static Result<GC::Ref<Script>, Vector<ParserError>> create_from_compiled(FFI::CompiledProgram* compiled, NonnullRefPtr<SourceCode const> source_code, Realm&, HostDefined* = nullptr);
|
|
|
|
Realm& realm() { return *m_realm; }
|
|
Vector<LoadedModuleRequest>& loaded_modules() { return m_loaded_modules; }
|
|
Vector<LoadedModuleRequest> const& loaded_modules() const { return m_loaded_modules; }
|
|
|
|
HostDefined* host_defined() const { return m_host_defined; }
|
|
StringView filename() const LIFETIME_BOUND { return m_filename; }
|
|
|
|
Bytecode::Executable* cached_executable() const { return m_executable; }
|
|
|
|
ThrowCompletionOr<void> global_declaration_instantiation(VM&, GlobalEnvironment&);
|
|
|
|
// Pre-computed global declaration instantiation data.
|
|
// These are extracted from the AST at parse time so that GDI can run
|
|
// without needing to walk the AST.
|
|
struct FunctionToInitialize {
|
|
GC::Ref<SharedFunctionInstanceData> shared_data;
|
|
Utf16FlyString name;
|
|
};
|
|
struct LexicalBinding {
|
|
Utf16FlyString name;
|
|
bool is_constant { false };
|
|
};
|
|
|
|
private:
|
|
Script(Realm&, StringView filename, RustIntegration::ScriptResult&&, HostDefined*);
|
|
|
|
virtual void visit_edges(Cell::Visitor&) override;
|
|
|
|
GC::Ptr<Realm> m_realm; // [[Realm]]
|
|
Vector<LoadedModuleRequest> m_loaded_modules; // [[LoadedModules]]
|
|
|
|
mutable GC::Ptr<Bytecode::Executable> m_executable;
|
|
|
|
Vector<Utf16FlyString> m_lexical_names;
|
|
Vector<Utf16FlyString> m_var_names;
|
|
Vector<FunctionToInitialize> m_functions_to_initialize;
|
|
HashTable<Utf16FlyString> m_declared_function_names;
|
|
Vector<Utf16FlyString> m_var_scoped_names;
|
|
Vector<Utf16FlyString> m_annex_b_candidate_names;
|
|
Vector<LexicalBinding> m_lexical_bindings;
|
|
bool m_is_strict_mode { false };
|
|
|
|
// Needed for potential lookups of modules.
|
|
ByteString m_filename;
|
|
HostDefined* m_host_defined { nullptr }; // [[HostDefined]]
|
|
};
|
|
|
|
}
|