IC: progress

This commit is contained in:
Araq
2026-06-23 12:03:29 +02:00
parent 08e9514c1d
commit 39e63e9fcc
2 changed files with 24 additions and 0 deletions

View File

@@ -361,6 +361,16 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
assert t.kind == tyObject
result = lookupInRecord(t.n, v.itemId)
if result != nil: break
# A LOADED (Sealed) env object carries fields baked by the producer process;
# re-lifting a NIF-loaded routine in a consumer (e.g. a macro VM-evaluating an
# imported `p2pProtocolBackendImpl`) re-captures the same local under a
# divergent process-local id, so the derived-itemId match misses. Fall back to
# the name+position identity `addField` uses — SYMMETRIC with `addField`'s
# Sealed by-name reuse — so the access resolves the field `addField` produced
# instead of failing with `not part of closure object type`.
if t.state == Sealed:
result = lookupCapturedField(t.n, v)
if result != nil: break
t = t.baseClass
if t == nil: break
t = t.skipTypes(skipPtrs)

View File

@@ -1401,6 +1401,18 @@ proc transformBody*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; flags: Transf
g.vmTransfIdgen = idGeneratorForBackend(g.systemModule)
liftIdgen = g.vmTransfIdgen
var c = openTransf(g, prc.getModule, "", liftIdgen, flags)
# `liftCapturedVars` rewrites captured locals to `:env.field` IN PLACE on the
# body it is handed; the env-creation prologue lands only in the returned
# wrapper. When the VM drives this transform (running a macro/CT proc), that
# in-place mutation corrupts the routine's PRE-transform `ast[bodyPos]` —
# under IC exactly the node `getBody` serializes to the module's `.s.nif`. So
# snapshot the pristine body before the VM lift and restore `ast[bodyPos]`
# afterwards: the VM still consumes the fully-lifted `result`, but `getBody`
# keeps faithfully returning the pre-transform body for serialization. The
# cg/backend path (`inVMTransform == 0`) is untouched.
let vmPristineBody =
if g.inVMTransform > 0: copyTree(getBody(g, prc))
else: nil
result = liftLambdas(g, prc, getBody(g, prc), c.tooEarly, c.idgen, flags)
result = processTransf(c, result, prc)
liftDefer(c, result)
@@ -1410,6 +1422,8 @@ proc transformBody*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; flags: Transf
result = g.transformClosureIterator(c.idgen, prc, result)
incl(result.flags, nfTransf)
if vmPristineBody != nil:
prc.ast[bodyPos] = vmPristineBody
if useCache in flags or prc.typ.callConv == ccInline:
# genProc for inline procs will be called multiple times from different modules,