Skip to content

Commit

Permalink
WIP: unify the hook tags (#559)
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq authored Feb 14, 2025
1 parent 9bcd020 commit bdcc890
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 86 deletions.
17 changes: 6 additions & 11 deletions doc/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@
| `(inset T X X)` | NimonyExpr | |
| `(card T X)` | NimonyExpr | |
| `(emove X)` | NimonyExpr | |
| `(destroy X)` | NimonyExpr | |
| `(dup X)` | NimonyExpr | |
| `(copy X X)` | NimonyExpr | |
| `(wasmoved X)` | NimonyExpr | |
| `(sinkh X X)` | NimonyExpr | |
| `(trace X X)` | NimonyExpr | |
| `(destroy X)` | NimonyExpr, NifIndex, HookKind | |
| `(dup X)` | NimonyExpr, NifIndex, HookKind| |
| `(copy X X)` | NimonyExpr, NifIndex, HookKind | |
| `(wasmoved X)` | NimonyExpr, NifIndex, HookKind | |
| `(sinkh X X)` | NimonyExpr, NifIndex, HookKind | |
| `(trace X X)` | NimonyExpr, NifIndex, HookKind | |
| `(errv)` | NifcExpr | error flag for `NIFC` |
| `(staticstmt S)` | NimonyStmt, NiflerKind | `static` statement |
| `(bind Y+)` | NimonyStmt, NiflerKind | `bind` statement |
Expand All @@ -263,8 +263,3 @@
| `(index (public ...) (private ...) (hooks ...) (converter ...) (build ...))` | NifIndex | index section |
| `(public (kv Y INTLIT*)` | NifIndex | public section |
| `(private (kv Y INTLIT*))` | NifIndex | private section |
| `(cloner Y Y)` | NifIndex | cloner hook section |
| `(tracer Y Y)` | NifIndex | tracer hook section |
| `(disarmer Y Y)` | NifIndex | disarmer hook section |
| `(mover Y Y)` | NifIndex | mover hook section |
| `(dtor Y Y)` | NifIndex | destructor hook section |
18 changes: 17 additions & 1 deletion src/hexer/lifter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ import ".." / nimony / [nimony_model, decls, programs, typenav, expreval, xints]
type
TypeCursor = Cursor

AttachedOp* = enum
attachedDestroy,
attachedWasMoved,
attachedDup,
attachedCopy,
attachedSink,
attachedTrace

GenHookRequest = object
sym: SymId
typ: TypeCursor
Expand All @@ -36,6 +44,14 @@ type
structuralTypeToHook: array[AttachedOp, Table[string, SymId]]
hookNames: Table[string, int]

proc hookName*(op: AttachedOp): string =
case op
of attachedDestroy: "destroy"
of attachedWasMoved: "wasMoved"
of attachedDup: "dup"
of attachedCopy: "copy"
of attachedSink: "sink"
of attachedTrace: "trace"

# Phase 1: Determine if the =hook is trivial:

Expand Down Expand Up @@ -470,7 +486,7 @@ proc maybeAddReturn(c: var LiftingCtx; res: SymId) =
copyIntoSymUse c.dest, res, c.info

proc genProcDecl(c: var LiftingCtx; sym: SymId; typ: TypeCursor) =
#let name = attachedOpToLitId(c.op)
#let name = HookKindToLitId(c.op)
#echo "generating ", c.p[dest.m].strings[name] # name
#result = declareSym(c.p[c.thisModule], ProcDecl, name)
let paramA = pool.syms.getOrIncl("dest.0")
Expand Down
5 changes: 2 additions & 3 deletions src/lib/nifindexes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ proc processForChecksum(dest: var Sha1State; content: var TokenBuf) =
skip n
skipToEnd n
of NoIndexTag, InlineIdx, KvIdx, BuildIdx, IndexIdx, PublicIdx, PrivateIdx,
ClonerIdx, TracerIdx, DisarmerIdx, MoverIdx, DtorIdx:
DestroyIdx, DupIdx, CopyIdx, WasmovedIdx, SinkhIdx, TraceIdx:
inc n
inc nested
of ParRi:
Expand Down Expand Up @@ -336,8 +336,7 @@ proc readIndex*(indexName: string): NifIndex =
else:
assert false, "'private' expected"
t = next(s)
# XXX Dup is missing here!
while t.tag.entryKind in {DtorIdx, DisarmerIdx, TracerIdx, ClonerIdx, MoverIdx}:
while t.tag.entryKind in {DestroyIdx, DupIdx, CopyIdx, WasmovedIdx, SinkhIdx, TraceIdx}:
let tagName = pool.tags[t.tag]
result.hooks[tagName] = initTable[string, NifIndexEntry]()
readSection(s, result.hooks[tagName])
Expand Down
13 changes: 7 additions & 6 deletions src/models/nifindex_tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ type
TypeIdx = (70, "type") ## type declaration
InlineIdx = (122, "inline") ## `inline` proc annotation
BuildIdx = (205, "build") ## `build` pragma
DestroyIdx = (248, "destroy")
DupIdx = (249, "dup")
CopyIdx = (250, "copy")
WasmovedIdx = (251, "wasmoved")
SinkhIdx = (252, "sinkh")
TraceIdx = (253, "trace")
IndexIdx = (261, "index") ## index section
PublicIdx = (262, "public") ## public section
PrivateIdx = (263, "private") ## private section
ClonerIdx = (264, "cloner") ## cloner hook section
TracerIdx = (265, "tracer") ## tracer hook section
DisarmerIdx = (266, "disarmer") ## disarmer hook section
MoverIdx = (267, "mover") ## mover hook section
DtorIdx = (268, "dtor") ## destructor hook section

proc rawTagIsNifIndex*(raw: uint32): bool {.inline.} =
let r = raw - 27'u32
r <= 255'u32 and r.uint8 in {0'u8, 23'u8, 24'u8, 25'u8, 27'u8, 29'u8, 30'u8, 31'u8, 32'u8, 36'u8, 37'u8, 38'u8, 39'u8, 40'u8, 41'u8, 42'u8, 43'u8, 95'u8, 178'u8, 234'u8, 235'u8, 236'u8, 237'u8, 238'u8, 239'u8, 240'u8, 241'u8}
r <= 255'u32 and r.uint8 in {0'u8, 23'u8, 24'u8, 25'u8, 27'u8, 29'u8, 30'u8, 31'u8, 32'u8, 36'u8, 37'u8, 38'u8, 39'u8, 40'u8, 41'u8, 42'u8, 43'u8, 95'u8, 178'u8, 221'u8, 222'u8, 223'u8, 224'u8, 225'u8, 226'u8, 234'u8, 235'u8, 236'u8}

13 changes: 13 additions & 0 deletions src/models/nimony_tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,19 @@ type
proc rawTagIsNimonySym*(raw: uint32): bool {.inline.} =
raw >= 50'u32 and raw <= 73'u32

type
HookKind* = enum
NoHook
DestroyH = (248, "destroy")
DupH = (249, "dup")
CopyH = (250, "copy")
WasmovedH = (251, "wasmoved")
SinkhH = (252, "sinkh")
TraceH = (253, "trace")

proc rawTagIsHookKind*(raw: uint32): bool {.inline.} =
raw >= 248'u32 and raw <= 253'u32

type
ControlFlowKind* = enum
NoControlFlow
Expand Down
12 changes: 1 addition & 11 deletions src/models/tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,7 @@ const
("defer", 260),
("index", 261),
("public", 262),
("private", 263),
("cloner", 264),
("tracer", 265),
("disarmer", 266),
("mover", 267),
("dtor", 268)
("private", 263)
]
const
ErrTagId* = 1
Expand Down Expand Up @@ -535,8 +530,3 @@ const
IndexTagId* = 261
PublicTagId* = 262
PrivateTagId* = 263
ClonerTagId* = 264
TracerTagId* = 265
DisarmerTagId* = 266
MoverTagId* = 267
DtorTagId* = 268
24 changes: 8 additions & 16 deletions src/nimony/nimony_model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ import stringviews
import ".." / models / [nimony_tags, callconv_tags]
export nimony_tags, callconv_tags

type
AttachedOp* = enum
attachedDestroy,
attachedWasMoved,
attachedDup,
attachedCopy,
attachedSink,
attachedTrace

proc stmtKind*(c: Cursor): NimonyStmt {.inline.} =
if c.kind == ParLe and rawTagIsNimonyStmt(tag(c).uint32):
result = cast[NimonyStmt](tag(c))
Expand Down Expand Up @@ -261,14 +252,15 @@ proc firstSon*(n: Cursor): Cursor {.inline.} =
result = n
inc result

proc hookName*(op: AttachedOp): string =
proc hookName*(op: HookKind): string =
case op
of attachedDestroy: "destroy"
of attachedWasMoved: "wasMoved"
of attachedDup: "dup"
of attachedCopy: "copy"
of attachedSink: "sink"
of attachedTrace: "trace"
of DestroyH: "destroy"
of WasmovedH: "wasMoved"
of DupH: "dup"
of CopyH: "copy"
of SinkhH: "sink"
of TraceH: "trace"
of NoHook: "(NoHook)"

const
NoSymId* = SymId(0)
Expand Down
73 changes: 36 additions & 37 deletions src/nimony/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3065,15 +3065,6 @@ proc getParamsType(c: var SemContext; paramsAt: int): seq[TypeCursor] =
break
endRead(c.dest)

type
HookOp = enum
hookNone
hookCloner = "cloner"
hookTracer = "tracer"
hookDisarmer = "disarmer"
hookMover = "mover"
hookDtor = "dtor"

proc getObjSymId(c: var SemContext; obj: TypeCursor): SymId =
var obj = skipModifier(obj)
while true:
Expand All @@ -3086,27 +3077,29 @@ proc getObjSymId(c: var SemContext; obj: TypeCursor): SymId =
else:
result = SymId(0)

proc checkTypeHook(c: var SemContext; params: seq[TypeCursor]; op: HookOp; info: PackedLineInfo) =
proc checkTypeHook(c: var SemContext; params: seq[TypeCursor]; op: HookKind; info: PackedLineInfo) =
var cond: bool
case op
of hookNone:
of NoHook:
return
of hookDtor:
of DestroyH:
cond = classifyType(c, c.routine.returnType) == VoidT and params.len == 1
if not cond:
buildErr c, info, "signature for '=destroy' must be proc[T: object](x: T)"
of hookTracer:
of TraceH:
cond = classifyType(c, c.routine.returnType) == VoidT and params.len == 2 and
classifyType(c, params[0]) == MutT and classifyType(c, params[1]) == PointerT
of hookDisarmer:
of WasmovedH:
cond = classifyType(c, c.routine.returnType) == VoidT and
params.len == 1 and classifyType(c, params[0]) == MutT
of hookCloner:
of CopyH:
cond = classifyType(c, c.routine.returnType) == VoidT and params.len == 2 and
classifyType(c, params[0]) == MutT
of hookMover:
of SinkhH:
cond = classifyType(c, c.routine.returnType) == VoidT and params.len == 2 and
classifyType(c, params[0]) == MutT
of DupH:
cond = params.len == 1 and sameTrees(params[0], c.routine.returnType)

if cond:
let obj = getObjSymId(c, params[0])
Expand All @@ -3126,20 +3119,22 @@ proc checkTypeHook(c: var SemContext; params: seq[TypeCursor]; op: HookOp; info:

if not cond:
case op
of hookNone:
of NoHook:
discard
of hookDtor:
of DestroyH:
buildErr c, info, "signature for '=destroy' must be proc[T: object](x: T)"
of hookTracer:
of TraceH:
buildErr c, info, "signature for '=trace' must be proc[T: object](x: var T; env: pointer)"
of hookDisarmer:
of WasmovedH:
buildErr c, info, "signature for '=wasMoved' must be proc[T: object](x: var T)"
of hookCloner:
of CopyH:
buildErr c, info, "signature for '=copy' must be proc[T: object](x: var T; y: T)"
of hookMover:
of SinkhH:
buildErr c, info, "signature for '=sink' must be proc[T: object](x: var T; y: T)"
of DupH:
buildErr c, info, "signature for '=dup' must be proc[T: object](x: T): T"

proc expandHook(c: var SemContext; obj: SymId, symId: SymId, op: HookOp) =
proc expandHook(c: var SemContext; obj: SymId, symId: SymId, op: HookKind) =
c.hookIndexMap.mgetOrPut($op, @[]).add (obj, symId)

proc getHookName(symId: SymId): string =
Expand All @@ -3151,31 +3146,35 @@ proc semHook(c: var SemContext; name: string; beforeParams: int; symId: SymId, i
let params = getParamsType(c, beforeParams)
case name
of "=destroy":
checkTypeHook(c, params, hookDtor, info)
checkTypeHook(c, params, DestroyH, info)
result = params[0]
of "=wasMoved":
checkTypeHook(c, params, hookDisarmer, info)
checkTypeHook(c, params, WasmovedH, info)
result = params[0]
of "=trace":
checkTypeHook(c, params, hookTracer, info)
checkTypeHook(c, params, TraceH, info)
result = params[0]
of "=copy":
checkTypeHook(c, params, hookCloner, info)
checkTypeHook(c, params, CopyH, info)
result = params[0]
of "=sink":
checkTypeHook(c, params, hookMover, info)
checkTypeHook(c, params, SinkhH, info)
result = params[0]
of "=dup":
checkTypeHook(c, params, DupH, info)
result = params[0]
else:
raiseAssert "unreachable"

proc hookToKind(name: string): HookOp =
proc hookToKind(name: string): HookKind =
case name
of "=destroy": hookDtor
of "=wasMoved": hookDisarmer
of "=trace": hookTracer
of "=copy": hookCloner
of "=sink": hookMover
else: hookNone
of "=destroy": DestroyH
of "=wasMoved": WasmovedH
of "=trace": TraceH
of "=copy": CopyH
of "=sink": SinkhH
of "=dup": DupH
else: NoHook

proc semProc(c: var SemContext; it: var Item; kind: SymKind; pass: PassKind) =
let info = it.n.info
Expand Down Expand Up @@ -3246,7 +3245,7 @@ proc semProc(c: var SemContext; it: var Item; kind: SymKind; pass: PassKind) =
c.closeScope() # close parameter scope

let hk = hookToKind(getHookName(symId))
if hk != hookNone:
if hk != NoHook:
let params = getParamsType(c, beforeParams)
assert params.len >= 1
let obj = getObjSymId(c, params[0])
Expand All @@ -3264,7 +3263,7 @@ proc semProc(c: var SemContext; it: var Item; kind: SymKind; pass: PassKind) =
addReturnResult c, resId, it.n.info
let name = getHookName(symId)
let hk = hookToKind(name)
if hk != hookNone:
if hk != NoHook:
let objCursor = semHook(c, name, beforeParams, symId, info)
let obj = getObjSymId(c, objCursor)

Expand Down
3 changes: 2 additions & 1 deletion tools/gen_tags.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type
NiflerKind,
CallConv,
NifcExpr, NifcStmt, NifcType, NifcOther, NifcPragma, NifcTypeQualifier, NifcSym,
NimonyExpr, NimonyStmt, NimonyType, NimonyOther, NimonyPragma, NimonySym, ControlFlowKind,
NimonyExpr, NimonyStmt, NimonyType, NimonyOther, NimonyPragma, NimonySym, HookKind, ControlFlowKind,
NifIndex

proc toSuffix(e: EnumList): (string, string) =
Expand All @@ -31,6 +31,7 @@ proc toSuffix(e: EnumList): (string, string) =
of NimonyPragma: ("P", "NoPragma")
of NimonySym: ("Y", "NoSym")
of ControlFlowKind: ("F", "NoControlFlow")
of HookKind: ("H", "NoHook")
of NifIndex: ("Idx", "NoIndexTag")

proc shortcutToEnumList(shortcut: string): EnumList =
Expand Down

0 comments on commit bdcc890

Please sign in to comment.