06 — JME, Handles, Tags und Phantom-Policies¶
Status: Normativer Konsolidierungsentwurf
1. Grundsatz¶
JDL kennt keine rohen Pointer in der Sprache.
JDL arbeitet mit:
Low-Level in JDL bedeutet nicht Pointer-Arithmetik mit religiösem Beistand, sondern präzise Handle- und Policy-Semantik.
2. HandleId ist technische Identität¶
HandleId schützt gegen stale handles / ABA-Probleme.
Er sagt aber allein nicht genug über die Semantik des Handles.
Semantisch wichtige Fragen:
Was liegt hinter dem Handle?
Welche Memory-Policy gilt?
In welcher Arena oder welchem Pool liegt das Objekt?
Ist der Zugriff strong oder weak?
Darf der Wert kopiert, bewegt oder geteilt werden?
Darf er Task-Grenzen überschreiten?
Diese Bedeutungen gehören in Type Engine + Tags + Meta-Records, nicht als lose Kommentare in D-Code.
3. JME-Schichten¶
JDL Source
|
| type RequestData : struct { ... }
| :> Memory(Arena[RequestArena])
v
Type Engine
|
| normalisiert Meta
| beweist Labels
v
Generator
|
| entscheidet Register-/Handle-Repräsentation
v
VM
|
| transportiert HandleId bei JME-Werten
v
JME
|
| prüft index + generation
| verwaltet Slot, Refcount, Arena, Pool
v
Objekt
4. Tags für JME-Regionen¶
tag ArenaKind
tag RequestArena : ArenaKind
tag AnalysisArena : ArenaKind
tag PoolKind
tag ConnectionPool : PoolKind
tag ParserNodePool : PoolKind
Verwendung:
type RequestData : struct {
headers: Map[str, str]
body: str
} :> Memory(Arena[RequestArena])
type DbConnection : struct {
native: NativeDbConnection
} :> Memory(Pool[ConnectionPool])
RequestArena und ConnectionPool sind keine Runtime-Werte. Sie markieren Speicherklassen.
5. Memory-Policies¶
Empfohlene Tag-/Type-Level-Form:
Parametrisierte Policies wie Arena[RequestArena] und Pool[ConnectionPool] sind keine einfachen Tag-Varianten, sondern Type-Level-Policy-Ausdrücke.
Konzeptionell:
Syntax bleibt JDL-typisch:
:> Memory(Value)
:> Memory(Rc)
:> Memory(Weak)
:> Memory(Arena[RequestArena])
:> Memory(Pool[ConnectionPool])
6. Typisierte Handle-Abstraktionen¶
Nicht jeder User-Typ muss explizit einen Handle wrapper enthalten.
Normaler Fall:
Der User schreibt Typ + Policy. Der Compiler/JME entscheidet Handle-Repräsentation.
Explizite Handle-Typen gehören in die Stdlib oder an Systemgrenzen:
type Weak[T] : struct {
id: HandleId
} :> Memory(Value)
type Strong[T] : struct {
id: HandleId
} :> Memory(Value)
type JoinHandle[T] : struct {
id: HandleId
} :> Own(Unique) :> Share(Send)
7. Phantom-Policies an Handles¶
Für spezielle Systemtypen können Tags über Phantom-Parameter gebunden werden.
tag AccessMode : enum =
| ReadOnly
| ReadWrite
| Volatile
| Atomic
type ResourceHandle[T, phantom Access: AccessMode] : struct {
id: HandleId
}
Beispiele:
def readConfig(handle: ResourceHandle[ConfigBlob, ReadOnly]) -> ConfigBlob
def writeBuffer(handle: ResourceHandle[Buffer, ReadWrite], data: Array[u8]) -> ()
def readDeviceRegister(handle: ResourceHandle[RegisterBlock, Volatile], offset: u32) -> u32
Runtime:
Compile-Time:
ResourceHandle[Buffer, ReadOnly]
ResourceHandle[Buffer, ReadWrite]
ResourceHandle[RegisterBlock, Volatile]
nicht austauschbar
8. Trust-Level für Ressourcen¶
tag TrustLevel : enum =
| Untrusted
| Validated
| Trusted
type Buffer[phantom Trust: TrustLevel] : struct {
data: Array[u8]
}
APIs:
def parseRaw(input: Buffer[Untrusted])
-> Result[Buffer[Validated], ParseError]
def execute(input: Buffer[Trusted])
-> Result[(), ExecError]
Damit kann ein unvalidierter Buffer nicht versehentlich an eine gefährliche API gehen.
9. Weak und Option¶
Weak-Referenzen sind nicht-besitzende Handles.
Zugriff:
Mit try-Boundary:
10. Keine rohen Pointer¶
Verboten in JDL:
Ausnahme:
JDL-seitig werden Low-Level-Ressourcen über Handles und Policies modelliert.
11. Normative Invarianten¶
JME-1: JDL kennt keine rohen Pointer.
JME-2: JDL-Code arbeitet mit Werten, Handles und typisierten Ressourcenabstraktionen.
JME-3: HandleId ist technische Runtime-Identität, keine vollständige Semantik.
JME-4: Memory-/Access-/Trust-/Region-Semantik wird durch Tags, Meta-Records und Phantom-Parameter modelliert.
JME-5: Die Type Engine normalisiert JME-Policies vor Codegen.
JME-6: Die JME erzwingt Runtime-Sicherheit über Handle Table + Generation.
JME-7: Die Type Engine erzwingt statische Sicherheit über Labels + Policies.
JME-8: Explizite HandleId-Felder sind System-/Stdlib- oder FFI-nahe Konstrukte und müssen starke Ownership-Labels tragen.