v0.3 interop split author syntax from execution lowering; articles must not fork MUST tables.
FFI and extern
Platform spec feature
FFI and extern
Spec standingStandard
-
Author-facing extern import rules live on this hub.
Context
Decision
This feature hub must own normative MUST/SHOULD contract text for foreign import. Sibling articles must not redefine hub requirements.
Consequences
Execution and tooling specs link here for
Externplacement and attribute shape.Verification anchors
/platform-spec/language-meta/interop/ffi-and-extern/;
compiler/crates/beskid_analysiscontract validation. -
Extern on non-contract declarations is E1510.
Context
Bulk C-style surfaces need stable contract blocks; module-level extern was exploratory.
Decision
Externmust apply only tocontractdeclarations in v0.3 Standard. The reference compiler must rejectExternon non-contract declarations (E1510).Consequences
Codegen collects
ExternImportfrom contract metadata; mod-level extern remains non-Standard.Verification anchors
compiler/crates/beskid_analysis/src/types/context/context.rs; extern attribute schema. -
Bulk import uses contract blocks with method signatures.
Context
Header-style
Externonmodwas considered for v0.3 but increases parser and ABI ambiguity.Decision
Externonmodis not part of v0.3 Standard. Authors must usecontractblocks with method signatures ending in;.Consequences
Future promotion requires a dedicated ADR and profile conformance tests.
Verification anchors
/platform-spec/language-meta/interop/ffi-and-extern/ v0.3 scope section.
-
Tier-1 user libraries use C profile; runtime builtins stay on Rust ABI.
Context
Mixing user
Externsymbols withBESKID_RUNTIME_ABI_VERSIONexports caused namespace and stability risk.Decision
Plane Rule User libraries C ABI profile + link-time binding Runtime embedding Rust ABI profile / frozen builtin table Separation User Externmust not mutate runtime builtin symbol namespaceConsequences
JIT registration and engine policy keep tables disjoint; see profile boundary map on hub.
Verification anchors
compiler/crates/beskid_abi; Rust ABI profile; C ABI profile. -
CLayout primitive structs are Proposed not v0.3.0 Standard.
Context
Arbitrary Beskid record
repr(C)needs layout rules beyond interop views.Decision
repr(C)on arbitrary Beskid types is out of scope for v0.3.0 Standard; CLayout primitive structs land in v0.3.1 (Proposed) per C layout types.Consequences
v0.3.0 Standard ships interop view types and link-time import first.
Verification anchors
- Contract import syntax How extern contracts declare foreign imports and map to symbols and call shapes.
- Extern attribute schema Normative Extern and per-method interop attributes for contract imports (v0.3).
- FFI and extern — Verification and traceability Conformance strategy for v0.3 FFI spec (fixtures, diagnostics, ignored runtime tests).
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
v0.3 scope
v0.3 FFI finalizes normative platform contracts for user interop and layout at foreign boundaries. This pass is spec-first: reference compiler and CLI behavior may land in v0.3.x point releases after the text is stable.
In scope for v0.3 Standard
Externoncontractdeclarations (import from C-compatible libraries).- Interop view types (v0.3.0) for buffers and string-like data at the boundary.
- Link-time library binding as the conformance path for Standard tier-1 hosts.
- Export and callbacks for embedding and plugin models.
- Project
linkmetadata and foreign library import tooling.
Out of scope or deferred
- Changes to
BESKID_RUNTIME_ABI_VERSIONand the frozen runtime builtin export table — runtime embedding stays on the Rust ABI profile. repr(C)record types on arbitrary Beskid types — v0.3.1 (see C layout types).- WinAPI / stdcall as a stdlib concern — tier-1 Standard conformance does not require Windows user-extern linking in corelib; platform packages may document Proposed mappings separately.
- Runtime
dlopenresolution — demoted to dynamic resolution profile (non-Standard appendix).
Profile boundary map
flowchart TB
subgraph author [Author Beskid code]
contract[contract + Extern attribute]
views[interop view types]
end
subgraph lang [language-meta]
ic[Interop.Contracts]
cabi[C ABI profile]
export[Export and callbacks]
rustabi[Rust ABI profile]
end
subgraph tool [tooling]
link[Project.proj link metadata]
fli[foreign library import]
end
subgraph exec [execution]
dispatch[Extern dispatch and policy]
builtins[Runtime builtins table]
end
contract --> ic
contract --> cabi
views --> ic
link --> fli --> dispatch
cabi --> dispatch
export --> rustabi --> builtins
dispatch -.->|must not mutate| builtinsTier-1 rule: user Extern libraries use C ABI profile + link-time binding. Runtime embedding and compiler builtins stay on Rust ABI profile / frozen BESKID_RUNTIME_ABI_VERSION — never mixed in the same symbol namespace.
Link-time resolution (reference compiler): AOT builds resolve ExternImport symbols through the project link block and AotBuildRequest::external_libraries (compiler/crates/beskid_aot/src/api.rs, compiler/crates/beskid_aot/src/linker.rs). See C ABI profile — Link-time linking for normative rules; normative text is not duplicated here.
What this feature specifies
This feature is the canonical language-level chapter for foreign import in Beskid: Extern metadata, contract import syntax, optional per-method symbol overrides, and how declarations connect to Interop.Contracts and the C ABI profile.
Lowering tables, linker drivers, and syscall policy remain under /execution/ and Extern dispatch and policy; this hub owns author-facing rules only.
Placement of Extern
The Extern attribute is a contract-level interop marker only. The reference compiler must reject Extern on non-contract declarations (diagnostic E1510).
Extern on mod is not part of v0.3 Standard; bulk C-header-style surfaces should use contract blocks with method signatures ending in ;.
Extern supplies ABI and library metadata consumed when building ExternImport records during codegen (compiler/crates/beskid_codegen/src/lowering/lowerable.rs).
Formal attribute shape
The platform reserves a built-in attribute declaration equivalent to:
pub attribute Extern(ContractDeclaration) { Abi: string = "C", Library: string,}Contract methods may carry additional method-level attributes documented in extern attribute schema (for example Symbol overrides).
Safety and pointers
Unmanaged data crossing the boundary must use interop view types or primitives permitted by the active profile. Obligations for borrow, transfer, and opaque handles are normative under ownership at the boundary.
Compiler mods do not gain ambient FFI unless the manifest grants extern_ffi — see mod host bridge FAQ.
Implementation anchors
- Grammar:
compiler/crates/beskid_analysis/src/beskid.pest(contract,ContractMethodSignature) - AST:
compiler/crates/beskid_analysis/src/syntax/items/contract_definition.rs - Semantic validation:
compiler/crates/beskid_analysis/src/types/context/context.rs - Diagnostics:
compiler/crates/beskid_tests/src/analysis/diagnostics.rs(E1510, extern type band) - Codegen extern collection:
compiler/crates/beskid_codegen/src/lowering/lowerable.rs,compiler/crates/beskid_codegen/src/lowering/context.rs
Decisions
Section titled “Decisions”No open decisions. Closed choices are normative ADRs under adr/ (D-LMETA-FFI-0001 … D-LMETA-FFI-0005); use the reader ADRs tab for detail.
Articles
- Feature hub owns normative contractAuthor-facing extern import rules live on this hub.
- Contract import syntaxHow extern contracts declare foreign imports and map to symbols and call shapes.
- Extern attribute schemaNormative Extern and per-method interop attributes for contract imports (v0.3).
- FFI and extern — Verification and traceabilityConformance strategy for v0.3 FFI spec (fixtures, diagnostics, ignored runtime tests).