more efficient enumToStr implementation that works without the old typeinfo structures

This commit is contained in:
Andreas Rumpf
2019-04-07 21:14:54 +02:00
parent f6ad071a46
commit f08e90f0d6
7 changed files with 86 additions and 20 deletions

View File

@@ -1811,3 +1811,17 @@ template detailedInfo*(sym: PSym): string =
proc isInlineIterator*(s: PSym): bool {.inline.} =
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)

View File

@@ -1481,6 +1481,8 @@ proc genOf(p: BProc, n: PNode, d: var TLoc) =
genOf(p, n.sons[1], n.sons[2].typ, d)
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
initLocExpr(p, e.sons[1], a)
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:
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) =
case 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 mCStrToStr: genDollar(p, e, d, "#cstrToNimstr($1)")
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 mNew: genNew(p, e)
of mNewFinalize: genNewFinalize(p, e)

View File

@@ -14,7 +14,7 @@ import
nversion, nimsets, msgs, std / sha1, bitsets, idents, types,
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
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):
import semparallel
@@ -307,6 +307,9 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
s = skipTypes(s.sons[0], skipPtrs)
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t, a.lode.info))
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:
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))

View File

@@ -160,7 +160,7 @@ type
typeNodesName*, nimTypesName*: Rope # used for type info generation
labels*: Natural # for generating unique module-scope names
extensionLoaders*: array['0'..'9', Rope] # special procs for the
# OpenGL wrapper
# OpenGL wrapper
injectStmt*: Rope
sigConflicts*: CountTable[SigHash]
g*: BModuleList

42
compiler/enumtostr.nim Normal file
View 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

View File

@@ -484,20 +484,6 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
tyGenericInst, tyStatic, tyAlias, tySink:
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 =
assert typ.kind == tyDistinct
let baseType = typ[0]

View File

@@ -70,7 +70,7 @@ type
tags: PNode # list of tags
bottom, inTryStmt: int
owner: PSym
owner_module: PSym
ownerModule: PSym
init: seq[int] # list of initialized variables
guards: TModel # nested guards
locked: seq[PNode] # locked locations
@@ -705,7 +705,7 @@ proc track(tracked: PEffects, n: PNode) =
# p's effects are ours too:
var a = n.sons[0]
let op = a.typ
if getConstExpr(tracked.owner_module, n, tracked.graph) != nil:
if getConstExpr(tracked.ownerModule, n, tracked.graph) != nil:
return
if op != nil:
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.tags = effects.sons[tagEffects]
t.owner = s
t.owner_module = s.getModule
t.ownerModule = s.getModule
t.init = @[]
t.guards.s = @[]
t.guards.o = initOperators(g)