Clause
← All dokumentation

Översatt från det engelska originalet · 1e3a39c8-dirty · 2026-10-26 · 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:

Nedrivningsordning: 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 vid liv efter runtimens nedrivning, men deras atomplatsord fäster inga stavningar. Atomlagringen tar sina globala platser ur bruk innan poster frigörs; stavningsåtkomst genom en överlevande icke-fast atom-Term rapporterar expired_context.

Processminne

Varje kontext äger en ProcessHeap (process_heap.hpp); dess layout, områden, dimensionering, admission, rötter och skräpsamling specificeras i runtime-heap.md. Värd-API:et:

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});

Persistenta termer

En tabell per runtime (memory/persistent_terms), som ägs av Runtime::Impl och nås genom ProcessContext::persistent_terms(), håller termerna för persistent_term (inbyggda funktioner).

ETS-tabeller

Ett register per runtime (ets/tables), som ägs av Runtime::Impl och nås genom ProcessContext::ets_tables(), håller tabellerna för ets (inbyggda funktioner).

Matchningsspecifikationer

runtime/src/match_spec/ kompilerar och kör matchningsspecifikationer som OTP:s erl_db_util.c gör, för ets och erlang:match_spec_test/3 (inbyggda funktioner).

Schemaläggarens bokföring

SchedulerService (scheduler.hpp) är en värdvänd post över processernas livscykel; den kör ingen kod. Program körs på exekutorn (processer), som inte använder den.

Trådar

Schemaläggarens arbetstrådar (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 io-utdata till standard-utdata (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 (körbara filer): den kontrollerar varje deskriptors ABI, startar en runtime, registrerar alla moduler före all ingångskod, bygger argv i ingångskontexten, kör ingångspunkten på exekutorn och översätter resultatet till avslutsstatusen. 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::function(FunctionIdentity)TermError::not_implemented
SchedulerService::run / executeSchedulerError::not_implemented
CodeServer::unloadCodeError::not_implemented
dispatch_builtin på en katalogiserad BIFStatus::not_implemented