first steps in adding template/macro calls to stack traces
This commit is contained in:
parent
2775cda6e1
commit
ee67a67ac4
17 changed files with 96 additions and 38 deletions
|
|
@ -62,8 +62,8 @@ type
|
||||||
nkTripleStrLit, # a triple string literal """
|
nkTripleStrLit, # a triple string literal """
|
||||||
nkNilLit, # the nil literal
|
nkNilLit, # the nil literal
|
||||||
# end of atoms
|
# end of atoms
|
||||||
nkMetaNode_Obsolete, # difficult to explain; represents itself
|
nkComesFrom, # "comes from" template/macro information for
|
||||||
# (used for macros)
|
# better stack trace generation
|
||||||
nkDotCall, # used to temporarily flag a nkCall node;
|
nkDotCall, # used to temporarily flag a nkCall node;
|
||||||
# this is used
|
# this is used
|
||||||
# for transforming ``s.len`` to ``len(s)``
|
# for transforming ``s.len`` to ``len(s)``
|
||||||
|
|
|
||||||
|
|
@ -1982,10 +1982,35 @@ proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) =
|
||||||
assert((sym.loc.r != nil) and (sym.loc.t != nil))
|
assert((sym.loc.r != nil) and (sym.loc.t != nil))
|
||||||
putLocIntoDest(p, d, sym.loc)
|
putLocIntoDest(p, d, sym.loc)
|
||||||
|
|
||||||
|
template genStmtListExprImpl(exprOrStmt) {.dirty.} =
|
||||||
|
#let hasNimFrame = magicsys.getCompilerProc("nimFrame") != nil
|
||||||
|
let hasNimFrame = p.prc != nil and
|
||||||
|
sfSystemModule notin p.module.module.flags and
|
||||||
|
optStackTrace in p.prc.options
|
||||||
|
var frameName: Rope = nil
|
||||||
|
for i in 0 .. n.len - 2:
|
||||||
|
let it = n[i]
|
||||||
|
if it.kind == nkComesFrom:
|
||||||
|
if hasNimFrame and frameName == nil:
|
||||||
|
inc p.labels
|
||||||
|
frameName = "FR" & rope(p.labels) & "_"
|
||||||
|
let theMacro = it[0].sym
|
||||||
|
add p.s(cpsStmts), initFrameNoDebug(p, frameName,
|
||||||
|
makeCString theMacro.name.s,
|
||||||
|
theMacro.info.quotedFilename, it.info.line)
|
||||||
|
else:
|
||||||
|
genStmts(p, it)
|
||||||
|
if n.len > 0: exprOrStmt
|
||||||
|
if frameName != nil:
|
||||||
|
add p.s(cpsStmts), deinitFrameNoDebug(p, frameName)
|
||||||
|
|
||||||
proc genStmtListExpr(p: BProc, n: PNode, d: var TLoc) =
|
proc genStmtListExpr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var length = sonsLen(n)
|
genStmtListExprImpl:
|
||||||
for i in countup(0, length - 2): genStmts(p, n.sons[i])
|
expr(p, n[n.len - 1], d)
|
||||||
if length > 0: expr(p, n.sons[length - 1], d)
|
|
||||||
|
proc genStmtList(p: BProc, n: PNode) =
|
||||||
|
genStmtListExprImpl:
|
||||||
|
genStmts(p, n[n.len - 1])
|
||||||
|
|
||||||
proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -2184,8 +2209,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
of nkCheckedFieldExpr: genCheckedRecordField(p, n, d)
|
of nkCheckedFieldExpr: genCheckedRecordField(p, n, d)
|
||||||
of nkBlockExpr, nkBlockStmt: genBlock(p, n, d)
|
of nkBlockExpr, nkBlockStmt: genBlock(p, n, d)
|
||||||
of nkStmtListExpr: genStmtListExpr(p, n, d)
|
of nkStmtListExpr: genStmtListExpr(p, n, d)
|
||||||
of nkStmtList:
|
of nkStmtList: genStmtList(p, n)
|
||||||
for i in countup(0, sonsLen(n) - 1): genStmts(p, n.sons[i])
|
|
||||||
of nkIfExpr, nkIfStmt: genIf(p, n, d)
|
of nkIfExpr, nkIfStmt: genIf(p, n, d)
|
||||||
of nkWhen:
|
of nkWhen:
|
||||||
# This should be a "when nimvm" node.
|
# This should be a "when nimvm" node.
|
||||||
|
|
|
||||||
|
|
@ -564,9 +564,6 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
lineF(p, cpsStmts, "goto $1;$n", [label])
|
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||||
|
|
||||||
proc getRaiseFrmt(p: BProc): string =
|
|
||||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
|
||||||
|
|
||||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
if p.inExceptBlock > 0:
|
if p.inExceptBlock > 0:
|
||||||
# if the current try stmt have a finally block,
|
# if the current try stmt have a finally block,
|
||||||
|
|
@ -580,7 +577,8 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
var e = rdLoc(a)
|
var e = rdLoc(a)
|
||||||
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
lineCg(p, cpsStmts, "#raiseException((#Exception*)$1, $2);$n",
|
||||||
|
[e, makeCString(typ.sym.name.s)])
|
||||||
else:
|
else:
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
|
|
|
||||||
|
|
@ -493,7 +493,32 @@ proc initLocExprSingleUse(p: BProc, e: PNode, result: var TLoc) =
|
||||||
proc lenField(p: BProc): Rope =
|
proc lenField(p: BProc): Rope =
|
||||||
result = rope(if p.module.compileToCpp: "len" else: "Sup.len")
|
result = rope(if p.module.compileToCpp: "len" else: "Sup.len")
|
||||||
|
|
||||||
include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
|
include ccgcalls, "ccgstmts.nim"
|
||||||
|
|
||||||
|
proc initFrame(p: BProc, procname, filename: Rope): Rope =
|
||||||
|
discard cgsym(p.module, "nimFrame")
|
||||||
|
if p.maxFrameLen > 0:
|
||||||
|
discard cgsym(p.module, "VarSlot")
|
||||||
|
result = rfmt(nil, "\tnimfrs_($1, $2, $3, $4);$n",
|
||||||
|
procname, filename, p.maxFrameLen.rope,
|
||||||
|
p.blocks[0].frameLen.rope)
|
||||||
|
else:
|
||||||
|
result = rfmt(nil, "\tnimfr_($1, $2);$n", procname, filename)
|
||||||
|
|
||||||
|
proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope =
|
||||||
|
discard cgsym(p.module, "nimFrame")
|
||||||
|
addf(p.blocks[0].sections[cpsLocals], "TFrame $1;$n", [frame])
|
||||||
|
result = rfmt(nil, "\t$1.procname = $2; $1.filename = $3; " &
|
||||||
|
" $1.line = $4; $1.len = -1; nimFrame(&$1);$n",
|
||||||
|
frame, procname, filename, rope(line))
|
||||||
|
|
||||||
|
proc deinitFrameNoDebug(p: BProc; frame: Rope): Rope =
|
||||||
|
result = rfmt(p.module, "\t#popFrameOfAddr(&$1);$n", frame)
|
||||||
|
|
||||||
|
proc deinitFrame(p: BProc): Rope =
|
||||||
|
result = rfmt(p.module, "\t#popFrame();$n")
|
||||||
|
|
||||||
|
include ccgexprs
|
||||||
|
|
||||||
# ----------------------------- dynamic library handling -----------------
|
# ----------------------------- dynamic library handling -----------------
|
||||||
# We don't finalize dynamic libs as the OS does this for us.
|
# We don't finalize dynamic libs as the OS does this for us.
|
||||||
|
|
@ -600,7 +625,7 @@ proc symInDynamicLibPartial(m: BModule, sym: PSym) =
|
||||||
sym.typ.sym = nil # generate a new name
|
sym.typ.sym = nil # generate a new name
|
||||||
|
|
||||||
proc cgsym(m: BModule, name: string): Rope =
|
proc cgsym(m: BModule, name: string): Rope =
|
||||||
var sym = magicsys.getCompilerProc(name)
|
let sym = magicsys.getCompilerProc(name)
|
||||||
if sym != nil:
|
if sym != nil:
|
||||||
case sym.kind
|
case sym.kind
|
||||||
of skProc, skFunc, skMethod, skConverter, skIterator: genProc(m, sym)
|
of skProc, skFunc, skMethod, skConverter, skIterator: genProc(m, sym)
|
||||||
|
|
@ -637,19 +662,6 @@ proc generateHeaders(m: BModule) =
|
||||||
add(m.s[cfsHeaders], "#undef powerpc" & tnl)
|
add(m.s[cfsHeaders], "#undef powerpc" & tnl)
|
||||||
add(m.s[cfsHeaders], "#undef unix" & tnl)
|
add(m.s[cfsHeaders], "#undef unix" & tnl)
|
||||||
|
|
||||||
proc initFrame(p: BProc, procname, filename: Rope): Rope =
|
|
||||||
discard cgsym(p.module, "nimFrame")
|
|
||||||
if p.maxFrameLen > 0:
|
|
||||||
discard cgsym(p.module, "VarSlot")
|
|
||||||
result = rfmt(nil, "\tnimfrs_($1, $2, $3, $4);$n",
|
|
||||||
procname, filename, p.maxFrameLen.rope,
|
|
||||||
p.blocks[0].frameLen.rope)
|
|
||||||
else:
|
|
||||||
result = rfmt(nil, "\tnimfr_($1, $2);$n", procname, filename)
|
|
||||||
|
|
||||||
proc deinitFrame(p: BProc): Rope =
|
|
||||||
result = rfmt(p.module, "\t#popFrame();$n")
|
|
||||||
|
|
||||||
proc closureSetup(p: BProc, prc: PSym) =
|
proc closureSetup(p: BProc, prc: PSym) =
|
||||||
if tfCapturesEnv notin prc.typ.flags: return
|
if tfCapturesEnv notin prc.typ.flags: return
|
||||||
# prc.ast[paramsPos].last contains the type we're after:
|
# prc.ast[paramsPos].last contains the type we're after:
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode =
|
||||||
var evalTemplateCounter* = 0
|
var evalTemplateCounter* = 0
|
||||||
# to prevent endless recursion in templates instantiation
|
# to prevent endless recursion in templates instantiation
|
||||||
|
|
||||||
proc wrapInComesFrom*(info: TLineInfo; res: PNode): PNode =
|
proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
||||||
when true:
|
when true:
|
||||||
result = res
|
result = res
|
||||||
result.info = info
|
result.info = info
|
||||||
|
|
@ -124,8 +124,12 @@ proc wrapInComesFrom*(info: TLineInfo; res: PNode): PNode =
|
||||||
if x[i].kind in nkCallKinds:
|
if x[i].kind in nkCallKinds:
|
||||||
x.sons[i].info = info
|
x.sons[i].info = info
|
||||||
else:
|
else:
|
||||||
result = newNodeI(nkPar, info)
|
result = newNodeI(nkStmtListExpr, info)
|
||||||
|
var d = newNodeI(nkComesFrom, info)
|
||||||
|
d.add newSymNode(sym, info)
|
||||||
|
result.add d
|
||||||
result.add res
|
result.add res
|
||||||
|
result.typ = res.typ
|
||||||
|
|
||||||
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode =
|
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode =
|
||||||
inc(evalTemplateCounter)
|
inc(evalTemplateCounter)
|
||||||
|
|
@ -156,6 +160,6 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode =
|
||||||
for i in countup(0, safeLen(body) - 1):
|
for i in countup(0, safeLen(body) - 1):
|
||||||
evalTemplateAux(body.sons[i], args, ctx, result)
|
evalTemplateAux(body.sons[i], args, ctx, result)
|
||||||
result.flags.incl nfFromTemplate
|
result.flags.incl nfFromTemplate
|
||||||
result = wrapInComesFrom(n.info, result)
|
result = wrapInComesFrom(n.info, tmpl, result)
|
||||||
dec(evalTemplateCounter)
|
dec(evalTemplateCounter)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2369,6 +2369,8 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
of nkGotoState, nkState:
|
of nkGotoState, nkState:
|
||||||
internalError(n.info, "first class iterators not implemented")
|
internalError(n.info, "first class iterators not implemented")
|
||||||
of nkPragmaBlock: gen(p, n.lastSon, r)
|
of nkPragmaBlock: gen(p, n.lastSon, r)
|
||||||
|
of nkComesFrom:
|
||||||
|
discard "XXX to implement for better stack traces"
|
||||||
else: internalError(n.info, "gen: unknown node type: " & $n.kind)
|
else: internalError(n.info, "gen: unknown node type: " & $n.kind)
|
||||||
|
|
||||||
var globals: PGlobals
|
var globals: PGlobals
|
||||||
|
|
|
||||||
|
|
@ -723,7 +723,7 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||||
result = accessViaEnvParam(n, owner)
|
result = accessViaEnvParam(n, owner)
|
||||||
else:
|
else:
|
||||||
result = accessViaEnvVar(n, owner, d, c)
|
result = accessViaEnvVar(n, owner, d, c)
|
||||||
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit,
|
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom,
|
||||||
nkTemplateDef, nkTypeSection:
|
nkTemplateDef, nkTypeSection:
|
||||||
discard
|
discard
|
||||||
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
|
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef:
|
||||||
|
|
|
||||||
|
|
@ -1397,8 +1397,8 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
put(g, tkBracketRi, "]")
|
put(g, tkBracketRi, "]")
|
||||||
of nkTupleClassTy:
|
of nkTupleClassTy:
|
||||||
put(g, tkTuple, "tuple")
|
put(g, tkTuple, "tuple")
|
||||||
of nkMetaNode_Obsolete:
|
of nkComesFrom:
|
||||||
put(g, tkParLe, "(META|")
|
put(g, tkParLe, "(ComesFrom|")
|
||||||
gsub(g, n, 0)
|
gsub(g, n, 0)
|
||||||
put(g, tkParRi, ")")
|
put(g, tkParRi, ")")
|
||||||
of nkGotoState, nkState:
|
of nkGotoState, nkState:
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
result = evalMacroCall(c.module, c.cache, n, nOrig, sym)
|
result = evalMacroCall(c.module, c.cache, n, nOrig, sym)
|
||||||
if efNoSemCheck notin flags:
|
if efNoSemCheck notin flags:
|
||||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||||
result = wrapInComesFrom(nOrig.info, result)
|
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
proc forceBool(c: PContext, n: PNode): PNode =
|
proc forceBool(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -2380,6 +2380,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if n.len != 1 and n.len != 2: illFormedAst(n)
|
if n.len != 1 and n.len != 2: illFormedAst(n)
|
||||||
for i in 0 ..< n.len:
|
for i in 0 ..< n.len:
|
||||||
n.sons[i] = semExpr(c, n.sons[i])
|
n.sons[i] = semExpr(c, n.sons[i])
|
||||||
|
of nkComesFrom: discard "ignore the comes from information for now"
|
||||||
else:
|
else:
|
||||||
localError(n.info, errInvalidExpressionX,
|
localError(n.info, errInvalidExpressionX,
|
||||||
renderTree(n, {renderNoComments}))
|
renderTree(n, {renderNoComments}))
|
||||||
|
|
|
||||||
|
|
@ -655,5 +655,8 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
of nkBracketExpr: result = foldArrayAccess(m, n)
|
of nkBracketExpr: result = foldArrayAccess(m, n)
|
||||||
of nkDotExpr: result = foldFieldAccess(m, n)
|
of nkDotExpr: result = foldFieldAccess(m, n)
|
||||||
|
of nkStmtListExpr:
|
||||||
|
if n.len == 2 and n[0].kind == nkComesFrom:
|
||||||
|
result = getConstExpr(m, n[1])
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
let a = n.sym
|
let a = n.sym
|
||||||
let b = getGenSym(c, a)
|
let b = getGenSym(c, a)
|
||||||
if b != a: n.sym = b
|
if b != a: n.sym = b
|
||||||
of nkEmpty, succ(nkSym)..nkNilLit:
|
of nkEmpty, succ(nkSym)..nkNilLit, nkComesFrom:
|
||||||
# see tests/compile/tgensymgeneric.nim:
|
# see tests/compile/tgensymgeneric.nim:
|
||||||
# We need to open the gensym'ed symbol again so that the instantiation
|
# We need to open the gensym'ed symbol again so that the instantiation
|
||||||
# creates a fresh copy; but this is wrong the very first reason for gensym
|
# creates a fresh copy; but this is wrong the very first reason for gensym
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
of nkMixinStmt:
|
of nkMixinStmt:
|
||||||
if c.scopeN > 0: result = semTemplBodySons(c, n)
|
if c.scopeN > 0: result = semTemplBodySons(c, n)
|
||||||
else: result = semMixinStmt(c.c, n, c.toMixin)
|
else: result = semMixinStmt(c.c, n, c.toMixin)
|
||||||
of nkEmpty, nkSym..nkNilLit:
|
of nkEmpty, nkSym..nkNilLit, nkComesFrom:
|
||||||
discard
|
discard
|
||||||
of nkIfStmt:
|
of nkIfStmt:
|
||||||
for i in countup(0, sonsLen(n)-1):
|
for i in countup(0, sonsLen(n)-1):
|
||||||
|
|
@ -528,7 +528,7 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = semTemplBodyDirty(c, n.sons[0])
|
result = semTemplBodyDirty(c, n.sons[0])
|
||||||
of nkBindStmt:
|
of nkBindStmt:
|
||||||
result = semBindStmt(c.c, n, c.toBind)
|
result = semBindStmt(c.c, n, c.toBind)
|
||||||
of nkEmpty, nkSym..nkNilLit:
|
of nkEmpty, nkSym..nkNilLit, nkComesFrom:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
|
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
|
||||||
|
|
|
||||||
|
|
@ -791,7 +791,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
result = transformSym(c, n)
|
result = transformSym(c, n)
|
||||||
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
|
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit, nkComesFrom:
|
||||||
# nothing to be done for leaves:
|
# nothing to be done for leaves:
|
||||||
result = PTransNode(n)
|
result = PTransNode(n)
|
||||||
of nkBracketExpr: result = transformArrayAccess(c, n)
|
of nkBracketExpr: result = transformArrayAccess(c, n)
|
||||||
|
|
|
||||||
|
|
@ -1847,6 +1847,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
globalError(n.info, errGenerated, "VM is not allowed to 'cast'")
|
globalError(n.info, errGenerated, "VM is not allowed to 'cast'")
|
||||||
of nkTypeOfExpr:
|
of nkTypeOfExpr:
|
||||||
genTypeLit(c, n.typ, dest)
|
genTypeLit(c, n.typ, dest)
|
||||||
|
of nkComesFrom:
|
||||||
|
discard "XXX to implement for better stack traces"
|
||||||
else:
|
else:
|
||||||
globalError(n.info, errGenerated, "cannot generate VM code for " & $n)
|
globalError(n.info, errGenerated, "cannot generate VM code for " & $n)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ type
|
||||||
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
|
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkUIntLit, nnkUInt8Lit,
|
||||||
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
|
nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
|
||||||
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
|
nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
|
||||||
nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
|
nnkTripleStrLit, nnkNilLit, nnkComesFrom, nnkDotCall,
|
||||||
nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
|
nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
|
||||||
nnkPrefix, nnkPostfix, nnkHiddenCallConv,
|
nnkPrefix, nnkPostfix, nnkHiddenCallConv,
|
||||||
nnkExprEqExpr,
|
nnkExprEqExpr,
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,18 @@ proc getFrame*(): PFrame {.compilerRtl, inl.} = framePtr
|
||||||
proc popFrame {.compilerRtl, inl.} =
|
proc popFrame {.compilerRtl, inl.} =
|
||||||
framePtr = framePtr.prev
|
framePtr = framePtr.prev
|
||||||
|
|
||||||
|
when false:
|
||||||
|
proc popFrameOfAddr(s: PFrame) {.compilerRtl.} =
|
||||||
|
var it = framePtr
|
||||||
|
if it == s:
|
||||||
|
framePtr = framePtr.prev
|
||||||
|
else:
|
||||||
|
while it != nil:
|
||||||
|
if it == s:
|
||||||
|
framePtr = it.prev
|
||||||
|
break
|
||||||
|
it = it.prev
|
||||||
|
|
||||||
proc setFrame*(s: PFrame) {.compilerRtl, inl.} =
|
proc setFrame*(s: PFrame) {.compilerRtl, inl.} =
|
||||||
framePtr = s
|
framePtr = s
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue