Early engine prototypes resolved Extern(Library:…) via dlopen/dlsym. That complicates reproducible AOT artifacts and blurs security review of loaded code.
Design model
Platform spec article
Design model
Spec standingStandard
-
User foreign libraries resolve at link time; dlopen remains legacy.
Context
Decision
Track Status Link-time Standard for v0.3 — addresses fixed before execution via C ABI profile Dynamic extern_dlopenProposed / legacy — engine feature only; not required for reference CLI Validation High-level Beskid types in extern signatures must be rejected before codegen Syscalls User externs must not embed OS syscall sequences — see Panic, IO, and syscalls Consequences
New platform work documents link-time flows first. Dynamic resolution stays gated behind
extern_dlopeninbeskid_engine.Verification anchors
compiler/crates/beskid_analysisextern validation;beskid_enginelink paths. -
Compiler thunks call stable dispatch entrypoints for language/runtime interop layouts.
Context
Tagged interop values need runtime-known layout offsets. Per-site custom trampolines would fork ABI stability.
Decision
Builtin family Role interop_dispatch_unitUnit-tagged dispatch interop_dispatch_ptrPointer payloads interop_dispatch_usizeScalar bridge Layout stability Offsets are versioned with ABI versioning Implementation beskid_runtime::interopexports registered inBUILTIN_SPECSLowering must route approved tagged calls through these builtins rather than ad-hoc host calls.
Consequences
Interop layout changes require ABI bump or additive symbol policy per D-EXEC-ABI-0002.
Verification anchors
compiler/crates/beskid_runtime/src/interop/; interop lowering tests.
- Contracts and edge cases MUST rules for extern validation, dynamic linking policy, and interop dispatch layout.
- Design model Extern resolution layers, runtime dispatch builtins, and host policy boundaries.
- Examples Declaring Extern contracts, dynamic getpid smoke, and interop dispatch usage patterns.
- FAQ and troubleshooting Extern linking failures, dlopen policy, and interop dispatch debugging.
- Flow and algorithm Extern validation, link registration, optional dlopen resolution, and interop dispatch calls.
- Verification and traceability Engine extern tests, analysis diagnostics, and interop layout traceability.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
| Section id | Required | Found |
|---|---|---|
what-this-feature-specifies | yes | yes |
implementation-anchors | yes | yes |
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
Purpose
Section titled “Purpose”Separate who declares foreign calls, who validates signatures, and who resolves addresses at link or run time. User Extern libraries and runtime builtins follow different policy tracks.
Primary actors
Section titled “Primary actors”| Actor | Role |
|---|---|
| Front-end / analysis | Parses Extern contracts, emits diagnostics for disallowed types (compiler/crates/beskid_analysis). |
| Codegen | Lowers approved calls to Cranelift call targets—either runtime builtins or imported extern symbols. |
Engine (beskid_engine) | Optional extern_dlopen path: dlopen / dlsym with caches (legacy v0.1; Proposed for new work—prefer link-time C ABI profile). |
| Runtime builtins | interop_dispatch_unit, interop_dispatch_ptr, interop_dispatch_usize bridge language/runtime interop layouts (beskid_runtime::interop). |
Dispatch layers
Section titled “Dispatch layers”flowchart TB src[Beskid Extern contract] ty[Type + ABI validation] link[Link-time symbol] dyn[Optional dlopen path] rt[Runtime interop_dispatch_*] src --> ty ty --> link ty --> dyn ty --> rt
Link-time (Standard v0.3): User libraries resolve when producing AOT/JIT artifacts; addresses are fixed before execution.
Dynamic (legacy): Engine loads Library + Symbol strings from Extern(Abi:"C", Library:"…") metadata when extern_dlopen is enabled.
Runtime dispatch: Compiler-generated thunks call interop_dispatch_* for tagged interop values; layout offsets are stable per ABI version (ABI versioning).
Policy boundaries
Section titled “Policy boundaries”- Lowering must not embed OS-specific syscall behavior for user externs; syscalls remain in Panic, IO, and syscalls.
- Allowed Cranelift scalar kinds for engine-validated externs: pointer-width integer,
i64,i32,i8,f64(legacy Extern policy v0.1). - High-level Beskid types in extern signatures must be rejected before codegen.