Cosmetic compiler cleanup (#12718)
* Cleanup compiler code base
* Unify add calls
* Unify len invocations
* Unify range operators
* Fix oversight
* Remove {.procvar.} pragma
* initCandidate -> newCandidate where reasonable
* Unify safeLen calls
This commit is contained in:
parent
b662842bd0
commit
7e747d11c6
109 changed files with 6115 additions and 6254 deletions
|
|
@ -23,11 +23,11 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
|
|||
result = n
|
||||
elif diff < 0:
|
||||
result = newNodeIT(nkObjUpConv, n.info, d)
|
||||
addSon(result, n)
|
||||
result.add n
|
||||
if downcast: internalError(conf, n.info, "cgmeth.genConv: no upcast allowed")
|
||||
elif diff > 0:
|
||||
result = newNodeIT(nkObjDownConv, n.info, d)
|
||||
addSon(result, n)
|
||||
result.add n
|
||||
if not downcast:
|
||||
internalError(conf, n.info, "cgmeth.genConv: no downcast allowed")
|
||||
else:
|
||||
|
|
@ -44,26 +44,26 @@ proc getDispatcher*(s: PSym): PSym =
|
|||
proc methodCall*(n: PNode; conf: ConfigRef): PNode =
|
||||
result = n
|
||||
# replace ordinary method by dispatcher method:
|
||||
let disp = getDispatcher(result.sons[0].sym)
|
||||
let disp = getDispatcher(result[0].sym)
|
||||
if disp != nil:
|
||||
result.sons[0].sym = disp
|
||||
result[0].sym = disp
|
||||
# change the arguments to up/downcasts to fit the dispatcher's parameters:
|
||||
for i in 1 ..< len(result):
|
||||
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true, conf)
|
||||
for i in 1..<result.len:
|
||||
result[i] = genConv(result[i], disp.typ[i], true, conf)
|
||||
else:
|
||||
localError(conf, n.info, "'" & $result.sons[0] & "' lacks a dispatcher")
|
||||
localError(conf, n.info, "'" & $result[0] & "' lacks a dispatcher")
|
||||
|
||||
type
|
||||
MethodResult = enum No, Invalid, Yes
|
||||
|
||||
proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
|
||||
if a.name.id != b.name.id: return
|
||||
if len(a.typ) != len(b.typ):
|
||||
if a.typ.len != b.typ.len:
|
||||
return
|
||||
|
||||
for i in 1 ..< len(a.typ):
|
||||
var aa = a.typ.sons[i]
|
||||
var bb = b.typ.sons[i]
|
||||
for i in 1..<a.typ.len:
|
||||
var aa = a.typ[i]
|
||||
var bb = b.typ[i]
|
||||
while true:
|
||||
aa = skipTypes(aa, {tyGenericInst, tyAlias})
|
||||
bb = skipTypes(bb, {tyGenericInst, tyAlias})
|
||||
|
|
@ -72,7 +72,7 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
|
|||
bb = bb.lastSon
|
||||
else:
|
||||
break
|
||||
if sameType(a.typ.sons[i], b.typ.sons[i]):
|
||||
if sameType(a.typ[i], b.typ[i]):
|
||||
if aa.kind == tyObject and result != Invalid:
|
||||
result = Yes
|
||||
elif aa.kind == tyObject and bb.kind == tyObject and (i == 1 or multiMethods):
|
||||
|
|
@ -90,22 +90,22 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
|
|||
return No
|
||||
if result == Yes:
|
||||
# check for return type:
|
||||
if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]):
|
||||
if b.typ.sons[0] != nil and b.typ.sons[0].kind == tyUntyped:
|
||||
if not sameTypeOrNil(a.typ[0], b.typ[0]):
|
||||
if b.typ[0] != nil and b.typ[0].kind == tyUntyped:
|
||||
# infer 'auto' from the base to make it consistent:
|
||||
b.typ.sons[0] = a.typ.sons[0]
|
||||
b.typ[0] = a.typ[0]
|
||||
else:
|
||||
return No
|
||||
|
||||
proc attachDispatcher(s: PSym, dispatcher: PNode) =
|
||||
if dispatcherPos < s.ast.len:
|
||||
# we've added a dispatcher already, so overwrite it
|
||||
s.ast.sons[dispatcherPos] = dispatcher
|
||||
s.ast[dispatcherPos] = dispatcher
|
||||
else:
|
||||
setLen(s.ast.sons, dispatcherPos+1)
|
||||
if s.ast[resultPos] == nil:
|
||||
s.ast[resultPos] = newNodeI(nkEmpty, s.info)
|
||||
s.ast.sons[dispatcherPos] = dispatcher
|
||||
s.ast[dispatcherPos] = dispatcher
|
||||
|
||||
proc createDispatcher(s: PSym): PSym =
|
||||
var disp = copySym(s)
|
||||
|
|
@ -115,16 +115,16 @@ proc createDispatcher(s: PSym): PSym =
|
|||
# we can't inline the dispatcher itself (for now):
|
||||
if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault
|
||||
disp.ast = copyTree(s.ast)
|
||||
disp.ast.sons[bodyPos] = newNodeI(nkEmpty, s.info)
|
||||
disp.ast[bodyPos] = newNodeI(nkEmpty, s.info)
|
||||
disp.loc.r = nil
|
||||
if s.typ.sons[0] != nil:
|
||||
if s.typ[0] != nil:
|
||||
if disp.ast.len > resultPos:
|
||||
disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
|
||||
disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym)
|
||||
else:
|
||||
# We've encountered a method prototype without a filled-in
|
||||
# resultPos slot. We put a placeholder in there that will
|
||||
# be updated in fixupDispatcher().
|
||||
disp.ast.addSon(newNodeI(nkEmpty, s.info))
|
||||
disp.ast.add newNodeI(nkEmpty, s.info)
|
||||
attachDispatcher(s, newSymNode(disp))
|
||||
# attach to itself to prevent bugs:
|
||||
attachDispatcher(disp, newSymNode(disp))
|
||||
|
|
@ -137,8 +137,8 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
|
|||
# the lock level of the dispatcher needs to be updated/checked
|
||||
# against that of the method.
|
||||
if disp.ast.len > resultPos and meth.ast.len > resultPos and
|
||||
disp.ast.sons[resultPos].kind == nkEmpty:
|
||||
disp.ast.sons[resultPos] = copyTree(meth.ast.sons[resultPos])
|
||||
disp.ast[resultPos].kind == nkEmpty:
|
||||
disp.ast[resultPos] = copyTree(meth.ast[resultPos])
|
||||
|
||||
# The following code works only with lock levels, so we disable
|
||||
# it when they're not available.
|
||||
|
|
@ -158,13 +158,12 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
|
|||
disp.typ.lockLevel = meth.typ.lockLevel
|
||||
|
||||
proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
||||
let L = len(g.methods)
|
||||
var witness: PSym
|
||||
for i in 0 ..< L:
|
||||
for i in 0..<g.methods.len:
|
||||
let disp = g.methods[i].dispatcher
|
||||
case sameMethodBucket(disp, s, multimethods = optMultiMethods in g.config.globalOptions)
|
||||
of Yes:
|
||||
add(g.methods[i].methods, s)
|
||||
g.methods[i].methods.add(s)
|
||||
attachDispatcher(s, disp.ast[dispatcherPos])
|
||||
fixupDispatcher(s, disp, g.config)
|
||||
#echo "fixup ", disp.name.s, " ", disp.id
|
||||
|
|
@ -178,7 +177,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
|||
of Invalid:
|
||||
if witness.isNil: witness = g.methods[i].methods[0]
|
||||
# create a new dispatcher:
|
||||
add(g.methods, (methods: @[s], dispatcher: createDispatcher(s)))
|
||||
g.methods.add((methods: @[s], dispatcher: createDispatcher(s)))
|
||||
#echo "adding ", s.info
|
||||
#if fromCache:
|
||||
# internalError(s.info, "no method dispatcher found")
|
||||
|
|
@ -190,32 +189,32 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
|||
|
||||
proc relevantCol(methods: seq[PSym], col: int): bool =
|
||||
# returns true iff the position is relevant
|
||||
var t = methods[0].typ.sons[col].skipTypes(skipPtrs)
|
||||
var t = methods[0].typ[col].skipTypes(skipPtrs)
|
||||
if t.kind == tyObject:
|
||||
for i in 1 .. high(methods):
|
||||
let t2 = skipTypes(methods[i].typ.sons[col], skipPtrs)
|
||||
for i in 1..high(methods):
|
||||
let t2 = skipTypes(methods[i].typ[col], skipPtrs)
|
||||
if not sameType(t2, t):
|
||||
return true
|
||||
|
||||
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
|
||||
for col in 1 ..< len(a.typ):
|
||||
for col in 1..<a.typ.len:
|
||||
if contains(relevantCols, col):
|
||||
var aa = skipTypes(a.typ.sons[col], skipPtrs)
|
||||
var bb = skipTypes(b.typ.sons[col], skipPtrs)
|
||||
var aa = skipTypes(a.typ[col], skipPtrs)
|
||||
var bb = skipTypes(b.typ[col], skipPtrs)
|
||||
var d = inheritanceDiff(aa, bb)
|
||||
if (d != high(int)) and d != 0:
|
||||
return d
|
||||
|
||||
proc sortBucket(a: var seq[PSym], relevantCols: IntSet) =
|
||||
# we use shellsort here; fast and simple
|
||||
var n = len(a)
|
||||
var n = a.len
|
||||
var h = 1
|
||||
while true:
|
||||
h = 3 * h + 1
|
||||
if h > n: break
|
||||
while true:
|
||||
h = h div 3
|
||||
for i in h ..< n:
|
||||
for i in h..<n:
|
||||
var v = a[i]
|
||||
var j = i
|
||||
while cmpSignatures(a[j - h], v, relevantCols) >= 0:
|
||||
|
|
@ -228,71 +227,70 @@ proc sortBucket(a: var seq[PSym], relevantCols: IntSet) =
|
|||
proc genDispatcher(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet): PSym =
|
||||
var base = methods[0].ast[dispatcherPos].sym
|
||||
result = base
|
||||
var paramLen = len(base.typ)
|
||||
var paramLen = base.typ.len
|
||||
var nilchecks = newNodeI(nkStmtList, base.info)
|
||||
var disp = newNodeI(nkIfStmt, base.info)
|
||||
var ands = getSysMagic(g, unknownLineInfo(), "and", mAnd)
|
||||
var iss = getSysMagic(g, unknownLineInfo(), "of", mOf)
|
||||
let boolType = getSysType(g, unknownLineInfo(), tyBool)
|
||||
for col in 1 ..< paramLen:
|
||||
for col in 1..<paramLen:
|
||||
if contains(relevantCols, col):
|
||||
let param = base.typ.n.sons[col].sym
|
||||
let param = base.typ.n[col].sym
|
||||
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
|
||||
addSon(nilchecks, newTree(nkCall,
|
||||
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param)))
|
||||
for meth in 0 .. high(methods):
|
||||
nilchecks.add newTree(nkCall,
|
||||
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param))
|
||||
for meth in 0..high(methods):
|
||||
var curr = methods[meth] # generate condition:
|
||||
var cond: PNode = nil
|
||||
for col in 1 ..< paramLen:
|
||||
for col in 1..<paramLen:
|
||||
if contains(relevantCols, col):
|
||||
var isn = newNodeIT(nkCall, base.info, boolType)
|
||||
addSon(isn, newSymNode(iss))
|
||||
let param = base.typ.n.sons[col].sym
|
||||
addSon(isn, newSymNode(param))
|
||||
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
|
||||
isn.add newSymNode(iss)
|
||||
let param = base.typ.n[col].sym
|
||||
isn.add newSymNode(param)
|
||||
isn.add newNodeIT(nkType, base.info, curr.typ[col])
|
||||
if cond != nil:
|
||||
var a = newNodeIT(nkCall, base.info, boolType)
|
||||
addSon(a, newSymNode(ands))
|
||||
addSon(a, cond)
|
||||
addSon(a, isn)
|
||||
a.add newSymNode(ands)
|
||||
a.add cond
|
||||
a.add isn
|
||||
cond = a
|
||||
else:
|
||||
cond = isn
|
||||
let retTyp = base.typ.sons[0]
|
||||
let retTyp = base.typ[0]
|
||||
let call = newNodeIT(nkCall, base.info, retTyp)
|
||||
addSon(call, newSymNode(curr))
|
||||
for col in 1 ..< paramLen:
|
||||
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
|
||||
curr.typ.sons[col], false, g.config))
|
||||
call.add newSymNode(curr)
|
||||
for col in 1..<paramLen:
|
||||
call.add genConv(newSymNode(base.typ.n[col].sym),
|
||||
curr.typ[col], false, g.config)
|
||||
var ret: PNode
|
||||
if retTyp != nil:
|
||||
var a = newNodeI(nkFastAsgn, base.info)
|
||||
addSon(a, newSymNode(base.ast.sons[resultPos].sym))
|
||||
addSon(a, call)
|
||||
a.add newSymNode(base.ast[resultPos].sym)
|
||||
a.add call
|
||||
ret = newNodeI(nkReturnStmt, base.info)
|
||||
addSon(ret, a)
|
||||
ret.add a
|
||||
else:
|
||||
ret = call
|
||||
if cond != nil:
|
||||
var a = newNodeI(nkElifBranch, base.info)
|
||||
addSon(a, cond)
|
||||
addSon(a, ret)
|
||||
addSon(disp, a)
|
||||
a.add cond
|
||||
a.add ret
|
||||
disp.add a
|
||||
else:
|
||||
disp = ret
|
||||
nilchecks.add disp
|
||||
nilchecks.flags.incl nfTransf # should not be further transformed
|
||||
result.ast.sons[bodyPos] = nilchecks
|
||||
result.ast[bodyPos] = nilchecks
|
||||
|
||||
proc generateMethodDispatchers*(g: ModuleGraph): PNode =
|
||||
result = newNode(nkStmtList)
|
||||
for bucket in 0 ..< len(g.methods):
|
||||
for bucket in 0..<g.methods.len:
|
||||
var relevantCols = initIntSet()
|
||||
for col in 1 ..< len(g.methods[bucket].methods[0].typ):
|
||||
for col in 1..<g.methods[bucket].methods[0].typ.len:
|
||||
if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col)
|
||||
if optMultiMethods notin g.config.globalOptions:
|
||||
# if multi-methods are not enabled, we are interested only in the first field
|
||||
break
|
||||
sortBucket(g.methods[bucket].methods, relevantCols)
|
||||
addSon(result,
|
||||
newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols)))
|
||||
result.add newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue