more efficient enumToStr implementation that works without the old typeinfo structures
This commit is contained in:
parent
f6ad071a46
commit
f08e90f0d6
7 changed files with 86 additions and 20 deletions
|
|
@ -1811,3 +1811,17 @@ template detailedInfo*(sym: PSym): string =
|
||||||
|
|
||||||
proc isInlineIterator*(s: PSym): bool {.inline.} =
|
proc isInlineIterator*(s: PSym): bool {.inline.} =
|
||||||
s.kind == skIterator and s.typ.callConv != ccClosure
|
s.kind == skIterator and s.typ.callConv != ccClosure
|
||||||
|
|
||||||
|
proc newProcType*(info: TLineInfo; owner: PSym): PType =
|
||||||
|
result = newType(tyProc, owner)
|
||||||
|
result.n = newNodeI(nkFormalParams, info)
|
||||||
|
rawAddSon(result, nil) # return type
|
||||||
|
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
||||||
|
# the effects are now stored in there too ... this is a bit hacky, but as
|
||||||
|
# usual we desperately try to save memory:
|
||||||
|
addSon(result.n, newNodeI(nkEffectList, info))
|
||||||
|
|
||||||
|
proc addParam*(procType: PType; param: PSym) =
|
||||||
|
param.position = procType.len-1
|
||||||
|
addSon(procType.n, newSymNode(param))
|
||||||
|
rawAddSon(procType, param.typ)
|
||||||
|
|
|
||||||
|
|
@ -1481,6 +1481,8 @@ proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
genOf(p, n.sons[1], n.sons[2].typ, d)
|
genOf(p, n.sons[1], n.sons[2].typ, d)
|
||||||
|
|
||||||
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
|
if optNimV2 in p.config.globalOptions:
|
||||||
|
localError(p.config, e.info, "'repr' is not available for --newruntime")
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
var t = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
|
|
@ -1980,6 +1982,21 @@ proc genDispose(p: BProc; n: PNode) =
|
||||||
# destructor, but it uses the runtime type. Afterwards the memory is freed:
|
# destructor, but it uses the runtime type. Afterwards the memory is freed:
|
||||||
lineCg(p, cpsStmts, "#nimDestroyAndDispose($#)", rdLoc(a))
|
lineCg(p, cpsStmts, "#nimDestroyAndDispose($#)", rdLoc(a))
|
||||||
|
|
||||||
|
proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
|
const ToStringProcSlot = -4
|
||||||
|
let t = e[1].typ.skipTypes(abstractInst)
|
||||||
|
var toStrProc: PSym = nil
|
||||||
|
for (idx, p) in t.methods:
|
||||||
|
if idx == ToStringProcSlot:
|
||||||
|
toStrProc = p
|
||||||
|
break
|
||||||
|
if toStrProc == nil:
|
||||||
|
toStrProc = genEnumToStrProc(t, e.info, p.module.g.graph)
|
||||||
|
t.methods.add((ToStringProcSlot, toStrProc))
|
||||||
|
var n = copyTree(e)
|
||||||
|
n[0] = newSymNode(toStrProc)
|
||||||
|
expr(p, n, d)
|
||||||
|
|
||||||
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
case op
|
case op
|
||||||
of mOr, mAnd: genAndOr(p, e, d, op)
|
of mOr, mAnd: genAndOr(p, e, d, op)
|
||||||
|
|
@ -2046,7 +2063,11 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
|
of mFloatToStr: genDollar(p, e, d, "#nimFloatToStr($1)")
|
||||||
of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
|
of mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
|
||||||
of mStrToStr: expr(p, e.sons[1], d)
|
of mStrToStr: expr(p, e.sons[1], d)
|
||||||
of mEnumToStr: genRepr(p, e, d)
|
of mEnumToStr:
|
||||||
|
if optNimV2 in p.config.globalOptions:
|
||||||
|
genEnumToStr(p, e, d)
|
||||||
|
else:
|
||||||
|
genRepr(p, e, d)
|
||||||
of mOf: genOf(p, e, d)
|
of mOf: genOf(p, e, d)
|
||||||
of mNew: genNew(p, e)
|
of mNew: genNew(p, e)
|
||||||
of mNewFinalize: genNewFinalize(p, e)
|
of mNewFinalize: genNewFinalize(p, e)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
|
||||||
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
||||||
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
|
||||||
lowerings, tables, sets, ndi, lineinfos, pathutils, transf
|
lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr
|
||||||
|
|
||||||
when not defined(leanCompiler):
|
when not defined(leanCompiler):
|
||||||
import semparallel
|
import semparallel
|
||||||
|
|
@ -307,6 +307,9 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
s = skipTypes(s.sons[0], skipPtrs)
|
s = skipTypes(s.sons[0], skipPtrs)
|
||||||
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info))
|
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info))
|
||||||
of frEmbedded:
|
of frEmbedded:
|
||||||
|
if optNimV2 in p.config.globalOptions:
|
||||||
|
localError(p.config, p.prc.info,
|
||||||
|
"complex object initialization is not supported with --newruntime")
|
||||||
# worst case for performance:
|
# worst case for performance:
|
||||||
var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a)
|
var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a)
|
||||||
linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info))
|
linefmt(p, section, "#objectInit($1, $2);$n", r, genTypeInfo(p.module, t, a.lode.info))
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ type
|
||||||
typeNodesName*, nimTypesName*: Rope # used for type info generation
|
typeNodesName*, nimTypesName*: Rope # used for type info generation
|
||||||
labels*: Natural # for generating unique module-scope names
|
labels*: Natural # for generating unique module-scope names
|
||||||
extensionLoaders*: array['0'..'9', Rope] # special procs for the
|
extensionLoaders*: array['0'..'9', Rope] # special procs for the
|
||||||
# OpenGL wrapper
|
# OpenGL wrapper
|
||||||
injectStmt*: Rope
|
injectStmt*: Rope
|
||||||
sigConflicts*: CountTable[SigHash]
|
sigConflicts*: CountTable[SigHash]
|
||||||
g*: BModuleList
|
g*: BModuleList
|
||||||
|
|
|
||||||
42
compiler/enumtostr.nim
Normal file
42
compiler/enumtostr.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
import ast, idents, lineinfos, modulegraphs, magicsys
|
||||||
|
|
||||||
|
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
|
||||||
|
result = newSym(skProc, getIdent(g.cache, "$"), t.owner, info)
|
||||||
|
|
||||||
|
let dest = newSym(skParam, getIdent(g.cache, "e"), result, info)
|
||||||
|
dest.typ = t
|
||||||
|
|
||||||
|
let res = newSym(skResult, getIdent(g.cache, "result"), result, info)
|
||||||
|
res.typ = getSysType(g, info, tyString)
|
||||||
|
|
||||||
|
result.typ = newType(tyProc, t.owner)
|
||||||
|
result.typ.n = newNodeI(nkFormalParams, info)
|
||||||
|
rawAddSon(result.typ, res.typ)
|
||||||
|
addSon(result.typ.n, newNodeI(nkEffectList, info))
|
||||||
|
|
||||||
|
result.typ.addParam dest
|
||||||
|
|
||||||
|
var body = newNodeI(nkStmtList, info)
|
||||||
|
var caseStmt = newNodeI(nkCaseStmt, info)
|
||||||
|
caseStmt.add(newSymNode dest)
|
||||||
|
|
||||||
|
# copy the branches over, but replace the fields with the for loop body:
|
||||||
|
for i in 0 ..< t.n.len:
|
||||||
|
assert(t.n[i].kind == nkSym)
|
||||||
|
var field = t.n[i].sym
|
||||||
|
let val = if field.ast == nil: field.name.s else: field.ast.strVal
|
||||||
|
caseStmt.add newTree(nkOfBranch, newSymNode(field),
|
||||||
|
newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newStrNode(val, info))))
|
||||||
|
#newIntTypeNode(nkIntLit, field.position, t)
|
||||||
|
|
||||||
|
body.add(caseStmt)
|
||||||
|
|
||||||
|
var n = newNodeI(nkProcDef, info, bodyPos+2)
|
||||||
|
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
|
||||||
|
n.sons[namePos] = newSymNode(result)
|
||||||
|
n.sons[paramsPos] = result.typ.n
|
||||||
|
n.sons[bodyPos] = body
|
||||||
|
n.sons[resultPos] = newSymNode(res)
|
||||||
|
result.ast = n
|
||||||
|
incl result.flags, sfFromGeneric
|
||||||
|
|
@ -484,20 +484,6 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
tyGenericInst, tyStatic, tyAlias, tySink:
|
tyGenericInst, tyStatic, tyAlias, tySink:
|
||||||
liftBodyAux(c, lastSon(t), body, x, y)
|
liftBodyAux(c, lastSon(t), body, x, y)
|
||||||
|
|
||||||
proc newProcType(info: TLineInfo; owner: PSym): PType =
|
|
||||||
result = newType(tyProc, owner)
|
|
||||||
result.n = newNodeI(nkFormalParams, info)
|
|
||||||
rawAddSon(result, nil) # return type
|
|
||||||
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
|
||||||
# the effects are now stored in there too ... this is a bit hacky, but as
|
|
||||||
# usual we desperately try to save memory:
|
|
||||||
addSon(result.n, newNodeI(nkEffectList, info))
|
|
||||||
|
|
||||||
proc addParam(procType: PType; param: PSym) =
|
|
||||||
param.position = procType.len-1
|
|
||||||
addSon(procType.n, newSymNode(param))
|
|
||||||
rawAddSon(procType, param.typ)
|
|
||||||
|
|
||||||
proc liftBodyDistinctType(c: PContext; typ: PType; kind: TTypeAttachedOp; info: TLineInfo): PSym =
|
proc liftBodyDistinctType(c: PContext; typ: PType; kind: TTypeAttachedOp; info: TLineInfo): PSym =
|
||||||
assert typ.kind == tyDistinct
|
assert typ.kind == tyDistinct
|
||||||
let baseType = typ[0]
|
let baseType = typ[0]
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ type
|
||||||
tags: PNode # list of tags
|
tags: PNode # list of tags
|
||||||
bottom, inTryStmt: int
|
bottom, inTryStmt: int
|
||||||
owner: PSym
|
owner: PSym
|
||||||
owner_module: PSym
|
ownerModule: PSym
|
||||||
init: seq[int] # list of initialized variables
|
init: seq[int] # list of initialized variables
|
||||||
guards: TModel # nested guards
|
guards: TModel # nested guards
|
||||||
locked: seq[PNode] # locked locations
|
locked: seq[PNode] # locked locations
|
||||||
|
|
@ -705,7 +705,7 @@ proc track(tracked: PEffects, n: PNode) =
|
||||||
# p's effects are ours too:
|
# p's effects are ours too:
|
||||||
var a = n.sons[0]
|
var a = n.sons[0]
|
||||||
let op = a.typ
|
let op = a.typ
|
||||||
if getConstExpr(tracked.owner_module, n, tracked.graph) != nil:
|
if getConstExpr(tracked.ownerModule, n, tracked.graph) != nil:
|
||||||
return
|
return
|
||||||
if op != nil:
|
if op != nil:
|
||||||
if tracked.owner.kind != skMacro:
|
if tracked.owner.kind != skMacro:
|
||||||
|
|
@ -950,7 +950,7 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PC
|
||||||
t.exc = effects.sons[exceptionEffects]
|
t.exc = effects.sons[exceptionEffects]
|
||||||
t.tags = effects.sons[tagEffects]
|
t.tags = effects.sons[tagEffects]
|
||||||
t.owner = s
|
t.owner = s
|
||||||
t.owner_module = s.getModule
|
t.ownerModule = s.getModule
|
||||||
t.init = @[]
|
t.init = @[]
|
||||||
t.guards.s = @[]
|
t.guards.s = @[]
|
||||||
t.guards.o = initOperators(g)
|
t.guards.o = initOperators(g)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue