ORC: support for custom =trace procs (#18459)

* ORC: support custom =trace procs (WIP)
* Update tests/arc/tcustomtrace.nim

Co-authored-by: Clyybber <darkmine956@gmail.com>

* =trace is now documented and seems to work
* make test green

Co-authored-by: Clyybber <darkmine956@gmail.com>
This commit is contained in:
Andreas Rumpf 2021-07-09 15:15:49 +02:00 • committed by GitHub
commit 4ec2f74246
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 321 additions and 11 deletions

View file

@ -667,7 +667,7 @@ type
mIsPartOf, mAstToStr, mParallel,
mSwap, mIsNil, mArrToSeq,
mNewString, mNewStringOfCap, mParseBiggestFloat,
mMove, mWasMoved, mDestroy,
mMove, mWasMoved, mDestroy, mTrace,
mDefault, mUnown, mIsolate, mAccessEnv, mReset,
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,

View file

@ -2422,6 +2422,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mDestroy: genDestroy(p, e)
of mAccessEnv: unaryExpr(p, e, d, "$1.ClE_0")
of mSlice: genSlice(p, e, d)
of mTrace: discard "no code to generate"
else:
when defined(debugMagics):
echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind

View file

@ -136,3 +136,4 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasTypeofVoid")
defineSymbol("nimHasDragonBox")
defineSymbol("nimHasHintAll")
defineSymbol("nimHasTrace")

View file

@ -2079,7 +2079,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
gen(p, n[1], x)
useMagic(p, "nimCopy")
r.res = "nimCopy(null, $1, $2)" % [x.rdLoc, genTypeInfo(p, n.typ)]
of mDestroy: discard "ignore calls to the default destructor"
of mDestroy, mTrace: discard "ignore calls to the default destructor"
of mOrd: genOrd(p, n, r)
of mLengthStr, mLengthSeq, mLengthOpenArray, mLengthArray:
var x: TCompRes

View file

@ -416,11 +416,23 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
body.add destructorCall(c, op, x)
result = true
#result = addDestructorCall(c, t, body, x)
of attachedAsgn, attachedSink, attachedTrace:
of attachedAsgn, attachedSink:
var op = getAttachedOp(c.g, t, c.kind)
result = considerAsgnOrSink(c, t, body, x, y, op)
if op != nil:
setAttachedOp(c.g, c.idgen.module, t, c.kind, op)
of attachedTrace:
var op = getAttachedOp(c.g, t, c.kind)
if op != nil and sfOverriden in op.flags:
if op.ast.isGenericRoutine:
# patch generic =trace:
op = instantiateGeneric(c, op, t, t.typeInst)
setAttachedOp(c.g, c.idgen.module, t, c.kind, op)
result = considerAsgnOrSink(c, t, body, x, y, op)
if op != nil:
setAttachedOp(c.g, c.idgen.module, t, c.kind, op)
of attachedDeepCopy:
let op = getAttachedOp(c.g, t, attachedDeepCopy)
if op != nil:
@ -1065,7 +1077,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
# 4. We have a custom destructor.
# 5. We have a (custom) generic destructor.
# we do not generate '=trace' nor '=dispose' procs if we
# we do not generate '=trace' procs if we
# have the cycle detection disabled, saves code size.
let lastAttached = if g.config.selectedGC == gcOrc: attachedTrace
else: attachedSink

View file

@ -551,6 +551,12 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
let op = getAttachedOp(c.graph, t, attachedDestructor)
if op != nil:
result[0] = newSymNode(op)
of mTrace:
result = n
let t = n[1].typ.skipTypes(abstractVar)
let op = getAttachedOp(c.graph, t, attachedTrace)
if op != nil:
result[0] = newSymNode(op)
of mUnown:
result = semUnown(c, n)
of mExists, mForall:

View file

@ -1649,6 +1649,8 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
var noError = false
let cond = if op == attachedDestructor:
t.len == 2 and t[0] == nil and t[1].kind == tyVar
elif op == attachedTrace:
t.len == 3 and t[0] == nil and t[1].kind == tyVar and t[2].kind == tyPointer
else:
t.len >= 2 and t[0] == nil
@ -1673,8 +1675,12 @@ proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) =
localError(c.config, n.info, errGenerated,
"type bound operation `" & s.name.s & "` can be defined only in the same module with its type (" & obj.typeToString() & ")")
if not noError and sfSystemModule notin s.owner.flags:
localError(c.config, n.info, errGenerated,
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
if op == attachedTrace:
localError(c.config, n.info, errGenerated,
"signature for '=trace' must be proc[T: object](x: var T; env: pointer)")
else:
localError(c.config, n.info, errGenerated,
"signature for '" & s.name.s & "' must be proc[T: object](x: var T)")
incl(s.flags, sfUsed)
incl(s.flags, sfOverriden)
@ -1752,7 +1758,8 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
localError(c.config, n.info, errGenerated,
"signature for '" & s.name.s & "' must be proc[T: object](x: var T; y: T)")
of "=trace":
bindTypeHook(c, s, n, attachedTrace)
if s.magic != mTrace:
bindTypeHook(c, s, n, attachedTrace)
else:
if sfOverriden in s.flags:
localError(c.config, n.info, errGenerated,

View file

@ -1362,7 +1362,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
globalError(c.config, n.info, sizeOfLikeMsg("offsetof"))
of mRunnableExamples:
discard "just ignore any call to runnableExamples"
of mDestroy: discard "ignore calls to the default destructor"
of mDestroy, mTrace: discard "ignore calls to the default destructor"
of mMove:
let arg = n[1]
let a = c.genx(arg)