Clause
← Gesamte Dokumentation

Übersetzt aus dem englischen Original · 1e3a39c8-dirty · 2026-10-26 · Auf Englisch lesen

Runtime

clause_runtime ist eine LLVM-freie C++23-Bibliothek. Sie besitzt Kontexte, Prozess-Heaps, Atome, geladene Module und die Verwaltung des Lebenszyklus und führt Erlang-Prozesse auf Scheduler-Workern aus (Prozesse). Alle APIs sind projektintern; Host-Aufrufe müssen pro Runtime serialisiert werden und dürfen sich nicht mit einem Programmlauf überschneiden, dessen Worker sich untereinander synchronisieren (Threads).

Linken

Genau eine für das Ziel gebaute Runtime über Clause::generated_program linken:

add_executable(harness harness.cpp)
target_link_libraries(harness PRIVATE Clause::generated_program)

Das bringt das Archiv, die ABI-/Runtime-Header und C++23 mit, aber nicht LLVM. link_consumer.cpp zeigt einen vollständigen Lebenszyklus.

Lebenszyklus

runtime.hpp:

Abbaureihenfolge: Scheduler-Einträge schließen → Kontexte zerstören → Code-Registrierungen freigeben → Scheduler-Dienst zerstören → Atomtabelle zuletzt. Aufgelöste Funktions-Handles halten Code über den Abbau der Runtime hinaus am Leben, aber ihre Atom-Slot-Wörter pinnen keine Schreibweisen. Der Atomspeicher zieht seine globalen Slots zurück, bevor er Datensätze freigibt; ein Zugriff auf die Schreibweise über einen überlebenden Term eines nicht festen Atoms meldet expired_context.

Prozessspeicher

Jeder Kontext besitzt einen ProcessHeap (process_heap.hpp); sein Layout, seine Bereiche, Größenbemessung, Zulassung, Wurzeln und Speicherbereinigung sind in runtime-heap.md festgelegt. Die Host-API:

Code-Server und Builtins

Jede Runtime besitzt einen CodeServer (code_server.hpp, callable.hpp):

auto functions = std::make_unique<ModuleRegistry>();
auto added = functions->add("identity", 1,
    [](ProcessContext &, std::span<const Term> args) -> CallResult<Term> { return args.front(); });
auto loaded = context.code_server().load({"native_demo", CodeImage::linked(), std::move(functions)});
auto fn = context.code_server().resolve({.module = "native_demo", .function = "identity", .arity = 1});

Persistente Terme

Eine Tabelle pro Runtime (memory/persistent_terms), im Besitz von Runtime::Impl und erreichbar über ProcessContext::persistent_terms(), hält die Terme von persistent_term (Builtins).

ETS-Tabellen

Ein Verzeichnis pro Runtime (ets/tables), im Besitz von Runtime::Impl und über ProcessContext::ets_tables() erreichbar, hält die Tabellen von ets (Builtins).

Match-Spezifikationen

runtime/src/match_spec/ kompiliert und führt Match-Spezifikationen wie erl_db_util.c von OTP aus, für ets und erlang:match_spec_test/3 (Builtins).

Scheduler-Buchführung

SchedulerService (scheduler.hpp) ist ein dem Host zugewandtes Verzeichnis des Lebenszyklus von Prozessen; er führt keinen Code aus. Programme laufen auf dem Executor (Prozesse), der ihn nicht verwendet.

Threads

Scheduler-Worker (Worker) führen Prozesse auf mehreren Threads einer Runtime aus. Dienste, die sie gemeinsam nutzen, sind synchronisiert; alles andere bleibt auf den Thread beschränkt, der seinen Prozess ausführt, oder wird durch den Mutex des Executors geschützt.

Standardausgabe

RuntimeOptions::standard_output (output.hpp) empfängt erlang:display/1 und io-Ausgaben auf die Standardausgabe (io). Der Standard schreibt über C-stdio (gepuffert) auf stdout des Prozesses; eine Host-Senke gibt false zurück, um einen gescheiterten Schreibvorgang zu melden.

erlang:display/1 stellt sein Argument im Anzeigestil dar, schreibt den Text und einen Zeilenumbruch in einem Schreibvorgang und gibt true zurück. Darstellungsgrenzen und abgewiesene Schreibvorgänge werden zu Infrastruktur-Status (resource_limit, output_failure, ...) im geprüften Kanal, nie zu Erlang-Ausnahmen.

Programmstart

CLAUSE_main_v1 (startup.hpp, runtime/src/startup/) führt ein ganzes Programm für das erzeugte main aus (ausführbare Dateien): Es prüft die ABI jedes Deskriptors, startet eine Runtime, registriert alle Module vor jeglichem Einstiegscode, baut argv im Einstiegskontext auf, führt den Einstiegspunkt auf dem Executor aus und bildet das Ergebnis auf den Exit-Status ab. Berichte gehen nach dem Leeren von stdout an stderr; Kontext und Runtime werden auf jedem Pfad in Reihenfolge abgebaut. CLAUSE_halt_v1 implementiert erlang:halt/0,1 (abort ruft std::abort auf).

Zurückgestellte Dienste

Diese melden eine Zeile [feature] notimpl (Features) und ändern keinen Zustand:

GrenzeFehler
TermFactory::function(FunctionIdentity)TermError::not_implemented
SchedulerService::run / executeSchedulerError::not_implemented
CodeServer::unloadCodeError::not_implemented
dispatch_builtin auf einem katalogisierten BIFStatus::not_implemented