Clause
← All dokumentation

Översatt från det engelska originalet · 06042fa · 2026-10-09 · Läs på engelska

Runtime

clause_runtime är ett LLVM-fritt C++23-bibliotek. Det äger kontexter, processheapar, atomer, laddade moduler och livscykelbokföring, och kör Erlang-processer på schemaläggarens arbetstrådar (processer). Alla API:er är interna för projektet; värdanrop måste serialiseras per runtime och får inte överlappa en programkörning, vars arbetstrådar synkroniserar sinsemellan (trådar).

Länkning

Länka exakt en runtime byggd för målet genom Clause::generated_program:

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

Det tar med arkivet, ABI-/runtime-headers och C++23, men inte LLVM. link_consumer.cpp visar en fullständig livscykel.

Livscykel

runtime.hpp:

Ordning vid nedrivning: stäng schemaläggarposter → förstör kontexter → släpp kodregistreringar → förstör schemaläggartjänsten → atomtabellen sist. Upplösta funktionshandtag håller kod och atomstavningar vid liv efter att runtimen rivits, men aldrig en process.

Processminne

Varje kontext äger en ProcessHeap: ett enda heapblock som skapas vid dess första allokering med storleken max(min_heap_words, request), plus en kedja av heapfragment som ägs av samma process. Ord flyttas endast när värden anropar collect() vid en safepoint.

Heapen följer den klassiska ERTS-designen; runtime-heap.md är dess kontrakt (layout, områden, dimensionering, antagning, rötter, skräpsamling).

Kodserver och inbyggda funktioner

Varje runtime äger en 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});

Schemaläggarens bokföring

SchedulerService (scheduler.hpp) registrerar endast processernas livscykel; den kör ingen kod.

Designskisser för arbetstrådar och processer finns i runtime/design/ och runtime/include/{scheduler,process}.hpp. Meddelanden är implementerade (processer): en sändning kopierar meddelandet in i mottagarens heap och lägger till det sist i dess signalinkorg (runtime/include/mailbox.hpp).

Trådar

Schemaläggarens arbetstrådar (plan step 56, arbetstrådar) kör processer på flera trådar i en runtime. Tjänster som de delar är synkroniserade; allt annat förblir begränsat till tråden som kör dess process eller skyddas av exekutorns mutex.

Standard-utdata

RuntimeOptions::standard_output (output.hpp) tar emot erlang:display/1 och senare bytes för standard_io. Standardimplementationen skriver till processens stdout genom C:s stdio (buffrat); en värdmottagare returnerar false för att rapportera en misslyckad skrivning.

erlang:display/1 återger sitt argument i visningsstil, skriver texten och en radbrytning i en enda skrivning och returnerar true. Återgivningsgränser och avvisade skrivningar blir infrastrukturstatusar (resource_limit, output_failure, ...) i den kontrollerade kanalen, aldrig Erlang-undantag.

Programuppstart

CLAUSE_main_v1 (startup.hpp, runtime/src/startup/) kör ett helt program åt den genererade main: den kontrollerar varje deskriptors ABI, startar en standardruntime, registrerar alla moduler före all ingångskod, bygger argv i ingångskontexten, anropar ingångspunkten och översätter resultatet till avslutsstatusen för körbara filer. Rapporter går till stderr efter att stdout har tömts; kontexten och runtimen rivs i ordning på varje väg. CLAUSE_halt_v1 implementerar erlang:halt/0,1 (abort anropar std::abort).

Uppskjutna tjänster

Dessa rapporterar en rad [feature] notimpl (funktioner) och ändrar inget tillstånd:

GränsFel
TermFactory::port (inga portar ännu, plan step 53), reference(ReferenceIdentity) och function(FunctionIdentity)TermError::not_implemented
SchedulerService::run / executeSchedulerError::not_implemented
CodeServer::unloadCodeError::not_implemented
dispatch_builtin på en katalogiserad BIFStatus::not_implemented