From 981a8950c61afb7814976333945b53f1799ad81a Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Tue, 9 Aug 2016 22:17:05 +0800 Subject: remove keepAlive and friends --- compiler/ccgcalls.nim | 5 ----- compiler/ccgexprs.nim | 27 +++++++-------------------- compiler/cgen.nim | 27 +-------------------------- 3 files changed, 8 insertions(+), 51 deletions(-) (limited to 'compiler') diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index dffb8a9a5..408a0c09c 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -536,8 +536,6 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) = else: genPrefixCall(p, nil, e, d) postStmtActions(p) - when false: - if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = if ri.sons[0].typ.skipTypes({tyGenericInst}).callConv == ccClosure: @@ -549,6 +547,3 @@ proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = else: genPrefixCall(p, le, ri, d) postStmtActions(p) - when false: - if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) - diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 7a60e1ef7..67debfe4f 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -171,7 +171,6 @@ proc getStorageLoc(n: PNode): TStorageLoc = proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if dest.s == OnStack or not usesNativeGC(): linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) - if needToKeepAlive in flags: keepAlive(p, dest) elif dest.s == OnHeap: # location is on heap # now the writer barrier is inlined for performance: @@ -198,7 +197,6 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, $2);$n", addrLoc(dest), rdLoc(src)) - if needToKeepAlive in flags: keepAlive(p, dest) proc asgnComplexity(n: PNode): int = if n != nil: @@ -268,7 +266,6 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", addrLoc(dest), addrLoc(src), rdLoc(dest)) - if needToKeepAlive in flags: keepAlive(p, dest) else: linefmt(p, cpsStmts, "#genericShallowAssign((void*)$1, (void*)$2, $3);$n", addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)) @@ -299,7 +296,6 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: if dest.s == OnStack or not usesNativeGC(): linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc) - if needToKeepAlive in flags: keepAlive(p, dest) elif dest.s == OnHeap: # we use a temporary to care for the dreaded self assignment: var tmp: TLoc @@ -310,7 +306,6 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n", addrLoc(dest), rdLoc(src)) - if needToKeepAlive in flags: keepAlive(p, dest) of tyProc: if needsComplexAssignment(dest.t): # optimize closure assignment: @@ -1006,9 +1001,8 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = add(p.s(cpsStmts), appends) if d.k == locNone: d = tmp - keepAlive(p, tmp) else: - genAssignment(p, d, tmp, {needToKeepAlive}) # no need for deep copying + genAssignment(p, d, tmp, {}) # no need for deep copying gcUsage(e) proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = @@ -1045,7 +1039,6 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = rdLoc(dest), rdLoc(a))) linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n", rdLoc(dest), lens, rope(L)) - keepAlive(p, dest) add(p.s(cpsStmts), appends) gcUsage(e) @@ -1065,7 +1058,6 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = rdLoc(a), getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)), getTypeDesc(p.module, bt)]) - keepAlive(p, a) #if bt != b.t: # echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t) initLoc(dest, locExpr, bt, OnHeap) @@ -1092,7 +1084,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = genTypeInfo(p.module, refType), sizeExpr] if a.s == OnHeap and usesNativeGC(): - # use newObjRC1 as an optimization; and we don't need 'keepAlive' either + # use newObjRC1 as an optimization if canFormAcycle(a.t): linefmt(p, cpsStmts, "if ($1) #nimGCunref($1);$n", a.rdLoc) else: @@ -1101,7 +1093,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = linefmt(p, cpsStmts, "$1 = $2;$n", a.rdLoc, b.rdLoc) else: b.r = ropecg(p.module, "($1) #newObj($2, $3)", args) - genAssignment(p, a, b, {needToKeepAlive}) # set the object type: + genAssignment(p, a, b, {}) # set the object type: let bt = skipTypes(refType.sons[0], abstractRange) genObjectInit(p, cpsStmts, bt, a, false) @@ -1132,7 +1124,7 @@ proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) = linefmt(p, cpsStmts, "$1 = $2;$n", dest.rdLoc, call.rdLoc) else: call.r = ropecg(p.module, "($1) #newSeq($2, $3)", args) - genAssignment(p, dest, call, {needToKeepAlive}) + genAssignment(p, dest, call, {}) proc genNewSeq(p: BProc, e: PNode) = var a, b: TLoc @@ -1254,7 +1246,7 @@ proc genNewFinalize(p: BProc, e: PNode) = b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ getTypeDesc(p.module, refType), ti, getTypeDesc(p.module, skipTypes(refType.lastSon, abstractRange))]) - genAssignment(p, a, b, {needToKeepAlive}) # set the object type: + genAssignment(p, a, b, {}) # set the object type: bt = skipTypes(refType.lastSon, abstractRange) genObjectInit(p, cpsStmts, bt, a, false) gcUsage(e) @@ -1364,7 +1356,7 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = initLocExpr(p, n.sons[1], a) a.r = ropecg(p.module, frmt, [rdLoc(a)]) if d.k == locNone: getTemp(p, n.typ, d) - genAssignment(p, d, a, {needToKeepAlive}) + genAssignment(p, d, a, {}) gcUsage(n) proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = @@ -1406,12 +1398,10 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) = lineCg(p, cpsStmts, setLenPattern, [ rdLoc(a), rdLoc(b), getTypeDesc(p.module, t), getTypeDesc(p.module, t.sons[0])]) - keepAlive(p, a) gcUsage(e) proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) = binaryStmt(p, e, d, "$1 = #setLengthStr($1, $2);$n") - keepAlive(p, d) gcUsage(e) proc genSwap(p: BProc, e: PNode, d: var TLoc) = @@ -1719,10 +1709,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = getTypeDesc(p.module, ranged), res]) of mConStrStr: genStrConcat(p, e, d) - of mAppendStrCh: - binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n") - # strictly speaking we need to generate "keepAlive" here too, but this - # very likely not needed and would slow down the code too much I fear + of mAppendStrCh: binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n") of mAppendStrStr: genStrAppend(p, e, d) of mAppendSeqElem: genSeqElemAppend(p, e, d) of mEqStr: genStrEquals(p, e, d) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 9851ab0e2..878ee1cd8 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -260,7 +260,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, type TAssignmentFlag = enum needToCopy, needForSubtypeCheck, afDestIsNil, afDestIsNotNil, afSrcIsNil, - afSrcIsNotNil, needToKeepAlive + afSrcIsNotNil TAssignmentFlags = set[TAssignmentFlag] proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) @@ -338,31 +338,6 @@ proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) = result.flags = {} constructLoc(p, result, not needsInit) -proc keepAlive(p: BProc, toKeepAlive: TLoc) = - when false: - # deactivated because of the huge slowdown this causes; GC will take care - # of interior pointers instead - if optRefcGC notin gGlobalOptions: return - var result: TLoc - var fid = rope(p.gcFrameId) - result.r = "GCFRAME.F" & fid - addf(p.gcFrameType, " $1 F$2;$n", - [getTypeDesc(p.module, toKeepAlive.t), fid]) - inc(p.gcFrameId) - result.k = locTemp - #result.a = -1 - result.t = toKeepAlive.t - result.s = OnStack - result.flags = {} - - if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)): - linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive)) - else: - useStringh(p.module) - linefmt(p, cpsStmts, - "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n", - addrLoc(result), addrLoc(toKeepAlive), rdLoc(result)) - proc initGCFrame(p: BProc): Rope = if p.gcFrameId > 0: result = "struct {$1} GCFRAME;$n" % [p.gcFrameType] -- cgit 1.4.1-2-gfad0 From 3cd4cf4320cba2795d2a9021c55a20cbbe2b04ae Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Tue, 9 Aug 2016 22:54:27 +0800 Subject: remove unused stuff --- compiler/ast.nim | 23 --------------- compiler/astalgo.nim | 77 -------------------------------------------------- compiler/ccgcalls.nim | 4 +-- compiler/ccgexprs.nim | 25 ---------------- compiler/ccgstmts.nim | 12 -------- compiler/ccgtypes.nim | 11 -------- compiler/cgen.nim | 10 +------ compiler/extccomp.nim | 4 --- compiler/idgen.nim | 2 +- compiler/lexer.nim | 9 ------ compiler/modules.nim | 9 ------ compiler/msgs.nim | 2 -- compiler/nimblecmd.nim | 12 -------- compiler/parser.nim | 20 ------------- compiler/renderer.nim | 21 +------------- compiler/sem.nim | 2 -- compiler/semexprs.nim | 12 -------- compiler/semfold.nim | 26 ----------------- compiler/seminst.nim | 30 -------------------- compiler/semmagic.nim | 7 ----- compiler/sempass2.nim | 7 ----- compiler/semstmts.nim | 12 -------- compiler/semtempl.nim | 29 ------------------- compiler/transf.nim | 7 ----- compiler/types.nim | 20 ------------- compiler/vmdeps.nim | 4 --- compiler/vmgen.nim | 14 --------- 27 files changed, 5 insertions(+), 406 deletions(-) (limited to 'compiler') diff --git a/compiler/ast.nim b/compiler/ast.nim index 277a21ba5..a5357b2b4 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -862,9 +862,6 @@ type key*, val*: RootRef TPairSeq* = seq[TPair] - TTable* = object # the same as table[PObject] of PObject - counter*: int - data*: TPairSeq TIdPair* = object key*: PIdObj @@ -1108,12 +1105,6 @@ proc copyIdTable*(dest: var TIdTable, src: TIdTable) = newSeq(dest.data, len(src.data)) for i in countup(0, high(src.data)): dest.data[i] = src.data[i] -proc copyTable*(dest: var TTable, src: TTable) = - dest.counter = src.counter - if isNil(src.data): return - setLen(dest.data, len(src.data)) - for i in countup(0, high(src.data)): dest.data[i] = src.data[i] - proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) = dest.counter = src.counter if isNil(src.data): return @@ -1327,10 +1318,6 @@ proc initStrTable*(x: var TStrTable) = proc newStrTable*: TStrTable = initStrTable(result) -proc initTable(x: var TTable) = - x.counter = 0 - newSeq(x.data, StartSize) - proc initIdTable*(x: var TIdTable) = x.counter = 0 newSeq(x.data, StartSize) @@ -1511,16 +1498,6 @@ proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool = return true result = false -proc replaceSons(n: PNode, oldKind, newKind: TNodeKind) = - for i in countup(0, sonsLen(n) - 1): - if n.sons[i].kind == oldKind: n.sons[i].kind = newKind - -proc sonsNotNil(n: PNode): bool = - for i in countup(0, sonsLen(n) - 1): - if n.sons[i] == nil: - return false - result = true - proc getInt*(a: PNode): BiggestInt = case a.kind of nkIntLit..nkUInt64Lit: result = a.intVal diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 3ca44ea7e..7c07b2995 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -31,17 +31,6 @@ proc objectSetIncl*(t: var TObjectSet, obj: RootRef) proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool # more are not needed ... -# ----------------------- (key, val)-Hashtables ---------------------------- -proc tablePut*(t: var TTable, key, val: RootRef) -proc tableGet*(t: TTable, key: RootRef): RootRef -type - TCmpProc* = proc (key, closure: RootRef): bool {.nimcall.} # true if found - -proc tableSearch*(t: TTable, key, closure: RootRef, - comparator: TCmpProc): RootRef - # return val as soon as comparator returns true; if this never happens, - # nil is returned - # ----------------------- str table ----------------------------------------- proc strTableContains*(t: TStrTable, n: PSym): bool proc strTableAdd*(t: var TStrTable, n: PSym) @@ -251,20 +240,6 @@ proc symToYamlAux(n: PSym, marker: var IntSet, indent, maxRecDepth: int): Rope proc typeToYamlAux(n: PType, marker: var IntSet, indent, maxRecDepth: int): Rope -proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int, - maxRecDepth: int): Rope = - var istr = rspaces(indent + 2) - result = rope("[") - var mycount = 0 - for i in countup(0, high(n.data)): - if n.data[i] != nil: - if mycount > 0: add(result, ",") - addf(result, "$N$1$2", - [istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)]) - inc(mycount) - if mycount > 0: addf(result, "$N$1", [rspaces(indent)]) - add(result, "]") - assert(mycount == n.counter) proc ropeConstr(indent: int, c: openArray[Rope]): Rope = # array of (name, value) pairs @@ -463,9 +438,6 @@ proc debug(n: PType) = proc debug(n: PNode) = echo($debugTree(n, 0, 100)) -const - EmptySeq = @[] - proc nextTry(h, maxHash: Hash): Hash = result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times @@ -519,55 +491,6 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool = inc(t.counter) result = false -proc tableRawGet(t: TTable, key: RootRef): int = - var h: Hash = hashNode(key) and high(t.data) # start with real hash value - while t.data[h].key != nil: - if t.data[h].key == key: - return h - h = nextTry(h, high(t.data)) - result = -1 - -proc tableSearch(t: TTable, key, closure: RootRef, - comparator: TCmpProc): RootRef = - var h: Hash = hashNode(key) and high(t.data) # start with real hash value - while t.data[h].key != nil: - if t.data[h].key == key: - if comparator(t.data[h].val, closure): - # BUGFIX 1 - return t.data[h].val - h = nextTry(h, high(t.data)) - result = nil - -proc tableGet(t: TTable, key: RootRef): RootRef = - var index = tableRawGet(t, key) - if index >= 0: result = t.data[index].val - else: result = nil - -proc tableRawInsert(data: var TPairSeq, key, val: RootRef) = - var h: Hash = hashNode(key) and high(data) - while data[h].key != nil: - assert(data[h].key != key) - h = nextTry(h, high(data)) - assert(data[h].key == nil) - data[h].key = key - data[h].val = val - -proc tableEnlarge(t: var TTable) = - var n: TPairSeq - newSeq(n, len(t.data) * GrowthFactor) - for i in countup(0, high(t.data)): - if t.data[i].key != nil: tableRawInsert(n, t.data[i].key, t.data[i].val) - swap(t.data, n) - -proc tablePut(t: var TTable, key, val: RootRef) = - var index = tableRawGet(t, key) - if index >= 0: - t.data[index].val = val - else: - if mustRehash(len(t.data), t.counter): tableEnlarge(t) - tableRawInsert(t.data, key, val) - inc(t.counter) - proc strTableContains(t: TStrTable, n: PSym): bool = var h: Hash = n.name.h and high(t.data) # start with real hash value while t.data[h] != nil: diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 408a0c09c..48157925c 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -411,7 +411,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope = add(result, substr(pat, start, i - 1)) proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = - var op, a: TLoc + var op: TLoc initLocExpr(p, ri.sons[0], op) # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) @@ -458,7 +458,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = # generates a crappy ObjC call - var op, a: TLoc + var op: TLoc initLocExpr(p, ri.sons[0], op) var pl = ~"[" # getUniqueType() is too expensive here: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 67debfe4f..8d0ead368 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -30,19 +30,6 @@ proc intLiteral(i: BiggestInt): Rope = else: result = ~"(IL64(-9223372036854775807) - IL64(1))" -proc int32Literal(i: int): Rope = - if i == int(low(int32)): - result = ~"(-2147483647 -1)" - else: - result = rope(i) - -proc genHexLiteral(v: PNode): Rope = - # hex literals are unsigned in C - # so we don't generate hex literals any longer. - if v.kind notin {nkIntLit..nkUInt64Lit}: - internalError(v.info, "genHexLiteral") - result = intLiteral(v.intVal) - proc getStrLit(m: BModule, s: string): Rope = discard cgsym(m, "TGenericSeq") result = getTempName(m) @@ -395,9 +382,6 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) = linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) else: internalError("genDeepCopy: " & $ty.kind) -proc getDestLoc(p: BProc, d: var TLoc, typ: PType) = - if d.k == locNone: getTemp(p, typ, d) - proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) = if d.k != locNone: if lfNoDeepCopy in d.flags: genAssignment(p, d, s, {}) @@ -448,13 +432,6 @@ proc unaryStmt(p: BProc, e: PNode, d: var TLoc, frmt: string) = initLocExpr(p, e.sons[1], a) lineCg(p, cpsStmts, frmt, [rdLoc(a)]) -proc binaryStmtChar(p: BProc, e: PNode, d: var TLoc, frmt: string) = - var a, b: TLoc - if (d.k != locNone): internalError(e.info, "binaryStmtChar") - initLocExpr(p, e.sons[1], a) - initLocExpr(p, e.sons[2], b) - lineCg(p, cpsStmts, frmt, [rdCharLoc(a), rdCharLoc(b)]) - proc binaryExpr(p: BProc, e: PNode, d: var TLoc, frmt: string) = var a, b: TLoc assert(e.sons[1].typ != nil) @@ -1236,7 +1213,6 @@ proc genNewFinalize(p: BProc, e: PNode) = a, b, f: TLoc refType, bt: PType ti: Rope - oldModule: BModule refType = skipTypes(e.sons[1].typ, abstractVarRange) initLocExpr(p, e.sons[1], a) initLocExpr(p, e.sons[2], f) @@ -1671,7 +1647,6 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) = binaryArith(p, e, d, m) proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = - var line, filen: Rope case op of mOr, mAnd: genAndOr(p, e, d, op) of mNot..mToBiggestInt: unaryArith(p, e, d, op) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index a5ce147c3..e1734bc52 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -459,7 +459,6 @@ proc genWhileStmt(p: BProc, t: PNode) = # significantly worse code var a: TLoc - labl: TLabel assert(sonsLen(t) == 2) inc(p.withinLoop) genLineDir(p, t) @@ -757,16 +756,6 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) = else: genOrdinalCase(p, t, d) -proc hasGeneralExceptSection(t: PNode): bool = - var length = sonsLen(t) - var i = 1 - while (i < length) and (t.sons[i].kind == nkExceptBranch): - var blen = sonsLen(t.sons[i]) - if blen == 1: - return true - inc(i) - result = false - proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = # code to generate: # @@ -1089,7 +1078,6 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType, proc asgnFieldDiscriminant(p: BProc, e: PNode) = var a, tmp: TLoc var dotExpr = e.sons[0] - var d: PSym if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr.sons[0] initLocExpr(p, e.sons[0], a) getTemp(p, a.t, tmp) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 3d1c2affc..e30395d2e 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -744,14 +744,6 @@ proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope = "void* ClEnv;$n} $1;$n", [result, rettype, desc]) -proc getTypeDesc(m: BModule, magic: string): Rope = - var sym = magicsys.getCompilerProc(magic) - if sym != nil: - result = getTypeDesc(m, sym.typ) - else: - rawMessage(errSystemNeeds, magic) - result = nil - proc finishTypeDescriptions(m: BModule) = var i = 0 while i < len(m.typeStack): @@ -1000,9 +992,6 @@ proc fakeClosureType(owner: PSym): PType = type TTypeInfoReason = enum ## for what do we need the type info? tiNew, ## for 'new' - tiNewSeq, ## for 'newSeq' - tiNonVariantAsgn, ## for generic assignment without variants - tiVariantAsgn ## for generic assignment with variants include ccgtrav diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 878ee1cd8..b68bf64bb 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -167,10 +167,6 @@ proc linefmt(p: BProc, s: TCProcSection, frmt: FormatStr, args: varargs[Rope]) = add(p.s(s), indentLine(p, ropecg(p.module, frmt, args))) -proc appLineCg(p: BProc, r: var Rope, frmt: FormatStr, - args: varargs[Rope]) = - add(r, indentLine(p, ropecg(p.module, frmt, args))) - proc safeLineNm(info: TLineInfo): int = result = toLinenumber(info) if result < 0: result = 0 # negative numbers are not allowed in #line @@ -259,8 +255,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, type TAssignmentFlag = enum - needToCopy, needForSubtypeCheck, afDestIsNil, afDestIsNotNil, afSrcIsNil, - afSrcIsNotNil + needToCopy, afDestIsNil, afDestIsNotNil, afSrcIsNil, afSrcIsNotNil TAssignmentFlags = set[TAssignmentFlag] proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) @@ -595,9 +590,6 @@ proc generateHeaders(m: BModule) = addf(m.s[cfsHeaders], "#include $1$N", [rope(it.data)]) it = PStrEntry(it.next) -proc retIsNotVoid(s: PSym): bool = - result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0]) - proc initFrame(p: BProc, procname, filename: Rope): Rope = discard cgsym(p.module, "nimFrame") if p.maxFrameLen > 0: diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 2dcfc0226..6f8b0b197 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -505,10 +505,6 @@ proc noAbsolutePaths: bool {.inline.} = # `optGenMapping` is included here for niminst. result = gGlobalOptions * {optGenScript, optGenMapping} != {} -const - specialFileA = 42 - specialFileB = 42 - var fileCounter: int proc add(s: var string, many: openArray[string]) = diff --git a/compiler/idgen.nim b/compiler/idgen.nim index 333772705..c6b1a4d07 100644 --- a/compiler/idgen.nim +++ b/compiler/idgen.nim @@ -54,6 +54,6 @@ proc loadMaxIds*(project: string) = if f.readLine(line): var frontEndId = parseInt(line) if f.readLine(line): - var backEndId = parseInt(line) + # var backEndId = parseInt(line) gFrontEndId = max(gFrontEndId, frontEndId) f.close() diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 0eee5004e..9c513034b 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -211,9 +211,6 @@ proc closeLexer*(lex: var TLexer) = inc(gLinesCompiled, lex.lineNumber) closeBaseLexer(lex) -proc getColumn(L: TLexer): int = - result = getColNumber(L, L.bufpos) - proc getLineInfo(L: TLexer): TLineInfo = result = newLineInfo(L.fileIdx, L.lineNumber, getColNumber(L, L.bufpos)) @@ -237,12 +234,6 @@ proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = proc matchTwoChars(L: TLexer, first: char, second: set[char]): bool = result = (L.buf[L.bufpos] == first) and (L.buf[L.bufpos + 1] in second) -proc isFloatLiteral(s: string): bool = - for i in countup(0, len(s) - 1): - if s[i] in {'.', 'e', 'E'}: - return true - result = false - {.push overflowChecks: off.} # We need to parse the largest uint literal without overflow checks proc unsafeParseUInt(s: string, b: var BiggestInt, start = 0): int = diff --git a/compiler/modules.nim b/compiler/modules.nim index 9120bd1b6..aa12325f4 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -38,9 +38,6 @@ proc getModule*(fileIdx: int32): PSym = if fileIdx >= 0 and fileIdx < gCompiledModules.len: result = gCompiledModules[fileIdx] -template hash(x: PSym): untyped = - gMemCacheData[x.position].hash - proc hashChanged(fileIdx: int32): bool = internalAssert fileIdx >= 0 and fileIdx < gMemCacheData.len @@ -220,12 +217,6 @@ proc includeModule*(s: PSym, fileIdx: int32): PNode {.procvar.} = addDep(s, fileIdx) doHash(fileIdx) -proc `==^`(a, b: string): bool = - try: - result = sameFile(a, b) - except OSError: - result = false - proc compileSystemModule* = if magicsys.systemModule == nil: systemFileIdx = fileInfoIdx(options.libpath/"system.nim") diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 4a9980066..a926f0f49 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -660,8 +660,6 @@ const WarningColor = fgYellow HintTitle = "Hint: " HintColor = fgGreen - InfoTitle = "Info: " - InfoColor = fgCyan proc getInfoContextLen*(): int = return msgContext.len proc setInfoContextLen*(L: int) = setLen(msgContext, L) diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim index c6c2ab058..9c5c17287 100644 --- a/compiler/nimblecmd.nim +++ b/compiler/nimblecmd.nim @@ -63,18 +63,6 @@ proc addNimblePath(p: string, info: TLineInfo) = message(info, hintPath, p) lists.prependStr(options.lazyPaths, p) -proc addPathWithNimFiles(p: string, info: TLineInfo) = - proc hasNimFile(dir: string): bool = - for kind, path in walkDir(dir): - if kind == pcFile and path.endsWith(".nim"): - result = true - break - if hasNimFile(p): - addNimblePath(p, info) - else: - for kind, p2 in walkDir(p): - if hasNimFile(p2): addNimblePath(p2, info) - proc addPathRec(dir: string, info: TLineInfo) = var packages = newStringTable(modeStyleInsensitive) var pos = dir.len-1 diff --git a/compiler/parser.nim b/compiler/parser.nim index 19ef0960a..40862eb63 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -340,26 +340,6 @@ proc parseSymbol(p: var TParser, allowNil = false): PNode = if not isKeyword(p.tok.tokType): getTok(p) result = ast.emptyNode -proc indexExpr(p: var TParser): PNode = - #| indexExpr = expr - result = parseExpr(p) - -proc indexExprList(p: var TParser, first: PNode, k: TNodeKind, - endToken: TTokType): PNode = - #| indexExprList = indexExpr ^+ comma - result = newNodeP(k, p) - addSon(result, first) - getTok(p) - optInd(p, result) - while p.tok.tokType notin {endToken, tkEof}: - var a = indexExpr(p) - addSon(result, a) - if p.tok.tokType != tkComma: break - getTok(p) - skipComment(p, a) - optPar(p) - eat(p, endToken) - proc colonOrEquals(p: var TParser, a: PNode): PNode = if p.tok.tokType == tkColon: result = newNodeP(nkExprColonExpr, p) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 0e733d643..a116a8afe 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -146,12 +146,6 @@ proc put(g: var TSrcGen, kind: TTokType, s: string) = else: g.pendingWhitespace = s.len -proc putLong(g: var TSrcGen, kind: TTokType, s: string, lineLen: int) = - # use this for tokens over multiple lines. - addPendingNL(g) - addTok(g, kind, s) - g.lineLen = lineLen - proc toNimChar(c: char): string = case c of '\0': result = "\\0" @@ -264,9 +258,6 @@ proc pushCom(g: var TSrcGen, n: PNode) = proc popAllComs(g: var TSrcGen) = setLen(g.comStack, 0) -proc popCom(g: var TSrcGen) = - setLen(g.comStack, len(g.comStack) - 1) - const Space = " " @@ -492,7 +483,7 @@ proc fits(g: TSrcGen, x: int): bool = type TSubFlag = enum - rfLongMode, rfNoIndent, rfInConstExpr + rfLongMode, rfInConstExpr TSubFlags = set[TSubFlag] TContext = tuple[spacing: int, flags: TSubFlags] @@ -675,16 +666,6 @@ proc gfor(g: var TSrcGen, n: PNode) = gcoms(g) gstmts(g, n.sons[length - 1], c) -proc gmacro(g: var TSrcGen, n: PNode) = - var c: TContext - initContext(c) - gsub(g, n.sons[0]) - putWithSpace(g, tkColon, ":") - if longMode(n) or (lsub(n.sons[1]) + g.lineLen > MaxLineLen): - incl(c.flags, rfLongMode) - gcoms(g) - gsons(g, n, c, 1) - proc gcase(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) diff --git a/compiler/sem.nim b/compiler/sem.nim index 7db4ae47e..ccbd665e9 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -39,7 +39,6 @@ proc semStmt(c: PContext, n: PNode): PNode proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) proc addParams(c: PContext, n: PNode, kind: TSymKind) proc maybeAddResult(c: PContext, s: PSym, n: PNode) -proc instGenericContainer(c: PContext, n: PNode, header: PType): PType proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode proc activate(c: PContext, n: PNode) proc semQuoteAst(c: PContext, n: PNode): PNode @@ -187,7 +186,6 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, # identifier with visibility proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym -proc semStmtScope(c: PContext, n: PNode): PNode proc typeAllowedCheck(info: TLineInfo; typ: PType; kind: TSymKind) = let t = typeAllowed(typ, kind) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fc31829ba..99bfa9b51 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -414,8 +414,6 @@ proc arrayConstrType(c: PContext, n: PNode): PType = if sonsLen(n) == 0: rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype! else: - var x = n.sons[0] - var lastIndex: BiggestInt = sonsLen(n) - 1 var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyOrdinal}) addSonSkipIntLit(typ, t) typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info) @@ -512,16 +510,6 @@ proc fixAbstractType(c: PContext, n: PNode) = #if (it.typ == nil): # InternalError(it.info, "fixAbstractType: " & renderTree(it)) -proc skipObjConv(n: PNode): PNode = - case n.kind - of nkHiddenStdConv, nkHiddenSubConv, nkConv: - if skipTypes(n.sons[1].typ, abstractPtrs).kind in {tyTuple, tyObject}: - result = n.sons[1] - else: - result = n - of nkObjUpConv, nkObjDownConv: result = n.sons[0] - else: result = n - proc isAssignable(c: PContext, n: PNode; isUnsafeAddr=false): TAssignableResult = result = parampatterns.isAssignable(c.p.owner, n, isUnsafeAddr) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 02f238ae6..1cb726053 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -458,32 +458,6 @@ proc getConstIfExpr(c: PSym, n: PNode): PNode = if result == nil: result = getConstExpr(c, it.sons[0]) else: internalError(it.info, "getConstIfExpr()") -proc partialAndExpr(c: PSym, n: PNode): PNode = - # partial evaluation - result = n - var a = getConstExpr(c, n.sons[1]) - var b = getConstExpr(c, n.sons[2]) - if a != nil: - if getInt(a) == 0: result = a - elif b != nil: result = b - else: result = n.sons[2] - elif b != nil: - if getInt(b) == 0: result = b - else: result = n.sons[1] - -proc partialOrExpr(c: PSym, n: PNode): PNode = - # partial evaluation - result = n - var a = getConstExpr(c, n.sons[1]) - var b = getConstExpr(c, n.sons[2]) - if a != nil: - if getInt(a) != 0: result = a - elif b != nil: result = b - else: result = n.sons[2] - elif b != nil: - if getInt(b) != 0: result = b - else: result = n.sons[1] - proc leValueConv(a, b: PNode): bool = result = false case a.kind diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 460db4f7c..959908564 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -97,22 +97,6 @@ proc genericCacheGet(genericSym: PSym, entry: TInstantiation; if inst.compilesId == id and sameInstantiation(entry, inst[]): return inst.sym -proc removeDefaultParamValues(n: PNode) = - # we remove default params, because they cannot be instantiated properly - # and they are not needed anyway for instantiation (each param is already - # provided). - when false: - for i in countup(1, sonsLen(n)-1): - var a = n.sons[i] - if a.kind != nkIdentDefs: IllFormedAst(a) - var L = a.len - if a.sons[L-1].kind != nkEmpty and a.sons[L-2].kind != nkEmpty: - # ``param: typ = defaultVal``. - # We don't need defaultVal for semantic checking and it's wrong for - # ``cmp: proc (a, b: T): int = cmp``. Hm, for ``cmp = cmp`` that is - # not possible... XXX We don't solve this issue here. - a.sons[L-1] = ast.emptyNode - proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) = # we need to create a fresh set of gensym'ed symbols: if n.kind == nkSym and sfGenSym in n.sym.flags and n.sym.owner == orig: @@ -128,17 +112,6 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) = proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) -proc addProcDecls(c: PContext, fn: PSym) = - # get the proc itself in scope (e.g. for recursion) - addDecl(c, fn) - - for i in 1 .. Date: Sat, 13 Aug 2016 20:26:25 +0700 Subject: fixed #4459 -- VS2010 error C2275 --- compiler/ccgstmts.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index a5ce147c3..9056a61cb 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -21,7 +21,7 @@ proc registerGcRoot(p: BProc, v: PSym) = # we register a specialized marked proc here; this has the advantage # that it works out of the box for thread local storage then :-) let prc = genTraverseProcForGlobal(p.module, v) - appcg(p.module, p.module.initProc.procSec(cpsStmts), + appcg(p.module, p.module.initProc.procSec(cpsInit), "#nimRegisterGlobalMarker($1);$n", [prc]) proc isAssignedImmediately(n: PNode): bool {.inline.} = -- cgit 1.4.1-2-gfad0 From 618e264b5812f1b215fab9672300f492275c4f38 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Wed, 17 Aug 2016 18:58:35 +0800 Subject: remove TLoc.heapRoot --- compiler/ast.nim | 3 --- compiler/ccgexprs.nim | 5 ----- 2 files changed, 8 deletions(-) (limited to 'compiler') diff --git a/compiler/ast.nim b/compiler/ast.nim index a5357b2b4..5ed458aff 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -726,9 +726,6 @@ type flags*: TLocFlags # location's flags t*: PType # type of location r*: Rope # rope value of location (code generators) - heapRoot*: Rope # keeps track of the enclosing heap object that - # owns this location (required by GC algorithms - # employing heap snapshots or sliding views) # ---------------- end of backend information ------------------------------ diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 4761b725c..dccb89d6b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -203,7 +203,6 @@ proc optAsgnLoc(a: TLoc, t: PType, field: Rope): TLoc = result.s = a.s result.t = t result.r = rdLoc(a) & "." & field - result.heapRoot = a.heapRoot proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = let newflags = @@ -698,8 +697,6 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = template inheritLocation(d: var TLoc, a: TLoc) = if d.k == locNone: d.s = a.s - if d.heapRoot == nil: - d.heapRoot = if a.heapRoot != nil: a.heapRoot else: a.r proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = initLocExpr(p, e.sons[0], a) @@ -863,7 +860,6 @@ proc genSeqElem(p: BProc, x, y: PNode, d: var TLoc) = "if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", rdLoc(b), rdLoc(a), lenField(p)) if d.k == locNone: d.s = OnHeap - d.heapRoot = a.r if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: a.r = rfmt(nil, "(*$1)", a.r) putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), @@ -1166,7 +1162,6 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = tmp2.k = locTemp tmp2.t = field.loc.t tmp2.s = if isRef: OnHeap else: OnStack - tmp2.heapRoot = tmp.r expr(p, it.sons[1], tmp2) if d.k == locNone: -- cgit 1.4.1-2-gfad0 From b0c12a7dc4065372960a696907947812b4c01e0d Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sun, 21 Aug 2016 12:41:55 +1000 Subject: Optimise pickBestCandidate: reduce heap allocations. --- compiler/semcall.nim | 104 +++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 61 deletions(-) (limited to 'compiler') diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 97209167d..b83872fe9 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -40,67 +40,49 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, filter: TSymKinds, best, alt: var TCandidate, errors: var CandidateErrors) = - var o: TOverloadIter - # thanks to the lazy semchecking for operands, we need to iterate over the - # symbol table *before* any call to 'initCandidate' which might invoke - # semExpr which might modify the symbol table in cases like - # 'init(a, 1, (var b = new(Type2); b))'. - var symx = initOverloadIter(o, c, headSymbol) - let symScope = o.lastOverloadScope - - var syms: seq[tuple[a: PSym, b: int]] = @[] - while symx != nil: - if symx.kind in filter: - syms.add((symx, o.lastOverloadScope)) - symx = nextOverloadIter(o, c, headSymbol) - if syms.len == 0: - when false: - if skIterator notin filter: - # also try iterators, but these are 2nd class: - symx = initOverloadIter(o, c, headSymbol) - while symx != nil: - if symx.kind == skIterator: - syms.add((symx, 100)) - symx = nextOverloadIter(o, c, headSymbol) - if syms.len == 0: return - else: - return - - var z: TCandidate - initCandidate(c, best, syms[0][0], initialBinding, symScope) - initCandidate(c, alt, syms[0][0], initialBinding, symScope) - best.state = csNoMatch - - for i in 0 .. Date: Sun, 21 Aug 2016 14:13:42 +1000 Subject: Add comments to clarify the roles of abstractX and typedescX types. --- compiler/types.nim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'compiler') diff --git a/compiler/types.nim b/compiler/types.nim index ff60730f0..312e36ae5 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -48,6 +48,8 @@ proc isOrdinalType*(t: PType): bool proc enumHasHoles*(t: PType): bool const + # TODO: Remove tyTypeDesc from each abstractX and (where necessary) + # replace with typedescX abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable, tyTypeDesc} abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, @@ -61,6 +63,7 @@ const skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable, tyTypeDesc} + # typedescX is used if we're sure tyTypeDesc should be included (or skipped) typedescPtrs* = abstractPtrs + {tyTypeDesc} typedescInst* = abstractInst + {tyTypeDesc} -- cgit 1.4.1-2-gfad0 From 9c9a7b6520e45cc71f071e82e8306ad276d72258 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 22 Aug 2016 18:31:15 +0200 Subject: fixes #3221 --- compiler/transf.nim | 12 +++++++++++- tests/iter/tcomplex_openarray.nim | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 tests/iter/tcomplex_openarray.nim (limited to 'compiler') diff --git a/compiler/transf.nim b/compiler/transf.nim index d64276cfb..fc400c524 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -474,12 +474,14 @@ proc transformConv(c: PTransf, n: PNode): PTransNode = type TPutArgInto = enum - paDirectMapping, paFastAsgn, paVarAsgn + paDirectMapping, paFastAsgn, paVarAsgn, paComplexOpenarray proc putArgInto(arg: PNode, formal: PType): TPutArgInto = # This analyses how to treat the mapping "formal <-> arg" in an # inline context. if skipTypes(formal, abstractInst).kind in {tyOpenArray, tyVarargs}: + if arg.kind == nkStmtListExpr: + return paComplexOpenarray return paDirectMapping # XXX really correct? # what if ``arg`` has side-effects? case arg.kind @@ -569,6 +571,14 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = assert(skipTypes(formal.typ, abstractInst).kind == tyVar) idNodeTablePut(newC.mapping, formal, arg) # XXX BUG still not correct if the arg has a side effect! + of paComplexOpenarray: + let typ = newType(tySequence, formal.owner) + addSonSkipIntLit(typ, formal.typ.sons[0]) + var temp = newTemp(c, typ, formal.info) + addVar(v, temp) + add(stmtList, newAsgnStmt(c, temp, arg.PTransNode)) + idNodeTablePut(newC.mapping, formal, temp) + var body = iter.getBody.copyTree pushInfoContext(n.info) # XXX optimize this somehow. But the check "c.inlining" is not correct: diff --git a/tests/iter/tcomplex_openarray.nim b/tests/iter/tcomplex_openarray.nim new file mode 100644 index 000000000..6fc191e90 --- /dev/null +++ b/tests/iter/tcomplex_openarray.nim @@ -0,0 +1,33 @@ + +# bug #3221 + +import algorithm, math, sequtils + + +iterator permutations[T](ys: openarray[T]): seq[T] = + var + d = 1 + c = newSeq[int](ys.len) + xs = newSeq[T](ys.len) + for i, y in ys: xs[i] = y + yield xs + block outer: + while true: + while d > 1: + dec d + c[d] = 0 + while c[d] >= d: + inc d + if d >= ys.len: break outer + let i = if (d and 1) == 1: c[d] else: 0 + swap xs[i], xs[d] + yield xs + inc c[d] + +proc dig_vectors(): void = + var v_nums: seq[int] + v_nums = newSeq[int](1) + for perm in permutations(toSeq(0 .. 1)): + v_nums[0] = 1 + +dig_vectors() -- cgit 1.4.1-2-gfad0 From e9e413552af0480747d025d422a0ea9500c582a2 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 23 Aug 2016 01:10:34 +0200 Subject: fixes #4619 --- compiler/semstmts.nim | 10 ++++++++-- tests/vm/tconst_float_as_int.nim | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/vm/tconst_float_as_int.nim (limited to 'compiler') diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 5d1770a32..5f9989ea2 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -304,8 +304,14 @@ proc semTry(c: PContext, n: PNode): PNode = proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode = result = fitNode(c, typ, n) if result.kind in {nkHiddenStdConv, nkHiddenSubConv}: - changeType(result.sons[1], typ, check=true) - result = result.sons[1] + let r1 = result.sons[1] + if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}: + result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal) + result.info = n.info + result.typ = typ + else: + changeType(r1, typ, check=true) + result = r1 elif not sameType(result.typ, typ): changeType(result, typ, check=false) diff --git a/tests/vm/tconst_float_as_int.nim b/tests/vm/tconst_float_as_int.nim new file mode 100644 index 000000000..ed84ec194 --- /dev/null +++ b/tests/vm/tconst_float_as_int.nim @@ -0,0 +1,3 @@ + +# bug #4619 +const x: float = 0 -- cgit 1.4.1-2-gfad0 From 55e86184a5289ee61b6105ed4ddb2cc1ca4f76dc Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 23 Aug 2016 01:29:30 +0200 Subject: fixes #4600 --- compiler/semgnrc.nim | 13 +++++++------ tests/generics/ttempl_in_generic.nim | 8 ++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 tests/generics/ttempl_in_generic.nim (limited to 'compiler') diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 9ea3efd0c..b8451865e 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -202,24 +202,25 @@ proc semGenericStmt(c: PContext, n: PNode, if s != nil: incl(s.flags, sfUsed) mixinContext = s.magic in {mDefined, mDefinedInScope, mCompiles} - let scOption = if s.name.id in ctx.toMixin: scForceOpen else: scOpen + let sc = symChoice(c, fn, s, + if s.name.id in ctx.toMixin: scForceOpen else: scOpen) case s.kind of skMacro: - if macroToExpand(s): + if macroToExpand(s) and sc.safeLen <= 1: styleCheckUse(fn.info, s) result = semMacroExpr(c, n, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, flags, ctx) else: - n.sons[0] = symChoice(c, fn, s, scOption) + n.sons[0] = sc result = n mixinContext = true of skTemplate: - if macroToExpand(s): + if macroToExpand(s) and sc.safeLen <= 1: styleCheckUse(fn.info, s) result = semTemplateExpr(c, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, flags, ctx) else: - n.sons[0] = symChoice(c, fn, s, scOption) + n.sons[0] = sc result = n # BUGFIX: we must not return here, we need to do first phase of # symbol lookup. Also since templates and macros can do scope injections @@ -230,7 +231,7 @@ proc semGenericStmt(c: PContext, n: PNode, # Leave it as an identifier. discard of skProc, skMethod, skIterator, skConverter, skModule: - result.sons[0] = symChoice(c, fn, s, scOption) + result.sons[0] = sc # do not check of 's.magic==mRoof' here because it might be some # other '^' but after overload resolution the proper one: if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^": diff --git a/tests/generics/ttempl_in_generic.nim b/tests/generics/ttempl_in_generic.nim new file mode 100644 index 000000000..f04b9d216 --- /dev/null +++ b/tests/generics/ttempl_in_generic.nim @@ -0,0 +1,8 @@ + +# bug #4600 +template foo(x: untyped): untyped = echo 1 +template foo(x,y: untyped): untyped = echo 2 + +proc bar1[T](x: T) = foo(x) +proc bar2(x: float) = foo(x,x) +proc bar3[T](x: T) = foo(x,x) -- cgit 1.4.1-2-gfad0 From f439a2f25f8e2aac2278322aa7ee351390d8161c Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 23 Aug 2016 10:13:37 +0200 Subject: fixes #4579 --- compiler/pragmas.nim | 55 ++++++++++++++++++++++++---------------------------- doc/manual/ffi.txt | 26 ++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 33 deletions(-) (limited to 'compiler') diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 1f93f5317..db5f8e727 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -90,43 +90,38 @@ proc pragmaAsm*(c: PContext, n: PNode): char = else: invalidPragma(it) -proc setExternName(s: PSym, extname: string) = - s.loc.r = rope(extname % s.name.s) +proc setExternName(s: PSym, extname: string, info: TLineInfo) = + # special cases to improve performance: + if extname == "$1": + s.loc.r = rope(s.name.s) + elif '$' notin extname: + s.loc.r = rope(extname) + else: + try: + s.loc.r = rope(extname % s.name.s) + except ValueError: + localError(info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)") if gCmd == cmdPretty and '$' notin extname: # note that '{.importc.}' is transformed into '{.importc: "$1".}' s.loc.flags.incl(lfFullExternalName) -proc makeExternImport(s: PSym, extname: string) = - setExternName(s, extname) +proc makeExternImport(s: PSym, extname: string, info: TLineInfo) = + setExternName(s, extname, info) incl(s.flags, sfImportc) excl(s.flags, sfForward) -proc validateExternCName(s: PSym, info: TLineInfo) = - ## Validates that the symbol name in s.loc.r is a valid C identifier. - ## - ## Valid identifiers are those alphanumeric including the underscore not - ## starting with a number. If the check fails, a generic error will be - ## displayed to the user. - let target = $s.loc.r - if target.len < 1 or target[0] notin IdentStartChars or - not target.allCharsInSet(IdentChars): - localError(info, errGenerated, "invalid exported symbol") - proc makeExternExport(s: PSym, extname: string, info: TLineInfo) = - setExternName(s, extname) - # XXX to fix make it work with nimrtl. - #if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC}: - # validateExternCName(s, info) + setExternName(s, extname, info) incl(s.flags, sfExportc) -proc processImportCompilerProc(s: PSym, extname: string) = - setExternName(s, extname) +proc processImportCompilerProc(s: PSym, extname: string, info: TLineInfo) = + setExternName(s, extname, info) incl(s.flags, sfImportc) excl(s.flags, sfForward) incl(s.loc.flags, lfImportCompilerProc) -proc processImportCpp(s: PSym, extname: string) = - setExternName(s, extname) +proc processImportCpp(s: PSym, extname: string, info: TLineInfo) = + setExternName(s, extname, info) incl(s.flags, sfImportc) incl(s.flags, sfInfixCall) excl(s.flags, sfForward) @@ -134,8 +129,8 @@ proc processImportCpp(s: PSym, extname: string) = incl(m.flags, sfCompileToCpp) extccomp.gMixedMode = true -proc processImportObjC(s: PSym, extname: string) = - setExternName(s, extname) +proc processImportObjC(s: PSym, extname: string, info: TLineInfo) = + setExternName(s, extname, info) incl(s.flags, sfImportc) incl(s.flags, sfNamedParamCall) excl(s.flags, sfForward) @@ -623,10 +618,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, of wExportc: makeExternExport(sym, getOptionalStr(c, it, "$1"), it.info) incl(sym.flags, sfUsed) # avoid wrong hints - of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1")) + of wImportc: makeExternImport(sym, getOptionalStr(c, it, "$1"), it.info) of wImportCompilerProc: - processImportCompilerProc(sym, getOptionalStr(c, it, "$1")) - of wExtern: setExternName(sym, expectStrLit(c, it)) + processImportCompilerProc(sym, getOptionalStr(c, it, "$1"), it.info) + of wExtern: setExternName(sym, expectStrLit(c, it), it.info) of wImmediate: if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate) @@ -637,9 +632,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, if sym.kind == skTemplate: incl(sym.flags, sfDirty) else: invalidPragma(it) of wImportCpp: - processImportCpp(sym, getOptionalStr(c, it, "$1")) + processImportCpp(sym, getOptionalStr(c, it, "$1"), it.info) of wImportObjC: - processImportObjC(sym, getOptionalStr(c, it, "$1")) + processImportObjC(sym, getOptionalStr(c, it, "$1"), it.info) of wAlign: if sym.typ == nil: invalidPragma(it) var align = expectIntLit(c, it) diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt index 5055f18af..d7d9596d2 100644 --- a/doc/manual/ffi.txt +++ b/doc/manual/ffi.txt @@ -16,12 +16,20 @@ spelled*: .. code-block:: proc printf(formatstr: cstring) {.header: "", importc: "printf", varargs.} -Note that this pragma is somewhat of a misnomer: Other backends will provide +Note that this pragma is somewhat of a misnomer: Other backends do provide the same feature under the same name. Also, if one is interfacing with C++ the `ImportCpp pragma `_ and interfacing with Objective-C the `ImportObjC pragma `_ can be used. +The string literal passed to ``importc`` can be a format string: + +.. code-block:: Nim + proc p(s: cstring) {.importc: "prefix$1".} + +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. + Exportc pragma -------------- @@ -33,9 +41,19 @@ name is the Nim identifier *exactly as spelled*: .. code-block:: Nim proc callme(formatstr: cstring) {.exportc: "callMe", varargs.} -Note that this pragma is somewhat of a misnomer: Other backends will provide +Note that this pragma is somewhat of a misnomer: Other backends do provide the same feature under the same name. +The string literal passed to ``exportc`` can be a format string: + +.. code-block:: Nim + proc p(s: string) {.exportc: "prefix$1".} = + echo s + +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. + + Extern pragma ------------- @@ -46,7 +64,9 @@ mangling. The string literal passed to ``extern`` can be a format string: proc p(s: string) {.extern: "prefix$1".} = echo s -In the example the external name of ``p`` is set to ``prefixp``. +In the example the external name of ``p`` is set to ``prefixp``. Only ``$1`` +is available and a literal dollar sign must be written as ``$$``. + Bycopy pragma -- cgit 1.4.1-2-gfad0 From 200ccff015e2e085a260e948eed50dfaf4cc6e8c Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 23 Aug 2016 17:11:10 +0200 Subject: fixes #4632 --- compiler/jsgen.nim | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'compiler') diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a0b54812f..1790daf7a 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1280,14 +1280,15 @@ proc genInfixCall(p: PProc, n: PNode, r: var TCompRes) = assert(typ.kind == tyProc) genPatternCall(p, n, pat, typ, r) return - gen(p, n.sons[1], r) - if r.typ == etyBaseIndex: - if r.address == nil: - globalError(n.info, "cannot invoke with infix syntax") - r.res = "$1[$2]" % [r.address, r.res] - r.address = nil - r.typ = etyNone - add(r.res, "." | "->") + if n.len != 1: + gen(p, n.sons[1], r) + if r.typ == etyBaseIndex: + if r.address == nil: + globalError(n.info, "cannot invoke with infix syntax") + r.res = "$1[$2]" % [r.address, r.res] + r.address = nil + r.typ = etyNone + add(r.res, "." | "->") var op: TCompRes if p.target == targetPHP: op.kind = resCallee -- cgit 1.4.1-2-gfad0 From 636e74fe397a7e93dd1955be549c901b3e9c8312 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 24 Aug 2016 11:27:14 +0200 Subject: overloading resolution: scoping is considered after typing (needs to be documented) --- compiler/sigmatch.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'compiler') diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ce4f893ea..ec429968c 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -221,13 +221,14 @@ proc cmpCandidates*(a, b: TCandidate): int = if result != 0: return result = a.convMatches - b.convMatches if result != 0: return - result = a.calleeScope - b.calleeScope - if result != 0: return # the other way round because of other semantics: result = b.inheritancePenalty - a.inheritancePenalty if result != 0: return # prefer more specialized generic over more general generic: result = complexDisambiguation(a.callee, b.callee) + # only as a last resort, consider scoping: + if result != 0: return + result = a.calleeScope - b.calleeScope proc writeMatches*(c: TCandidate) = writeLine(stdout, "exact matches: " & $c.exactMatches) -- cgit 1.4.1-2-gfad0 From 18e37cad0829e2f8eb1d8733f91d5d3ec79a94c9 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 24 Aug 2016 11:48:21 +0200 Subject: fixes #4653 --- compiler/ccgexprs.nim | 2 ++ tests/ccgbugs/twrong_rc_for_refarray.nim | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ccgbugs/twrong_rc_for_refarray.nim (limited to 'compiler') diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index f9fa1a0f6..6c96f209e 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -670,6 +670,8 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) = #if e[0].kind != nkBracketExpr: # message(e.info, warnUser, "CAME HERE " & renderTree(e)) expr(p, e.sons[0], d) + if e.sons[0].typ.skipTypes(abstractInst).kind == tyRef: + d.s = OnHeap else: var a: TLoc let typ = skipTypes(e.sons[0].typ, abstractInst) diff --git a/tests/ccgbugs/twrong_rc_for_refarray.nim b/tests/ccgbugs/twrong_rc_for_refarray.nim new file mode 100644 index 000000000..99bdac5e1 --- /dev/null +++ b/tests/ccgbugs/twrong_rc_for_refarray.nim @@ -0,0 +1,26 @@ +discard """ + output: '''m[0][0] = 1.0 +m[0][0] = 2.0''' +""" +# bug #4653 +type + Vector = ref array[2, float64] + Matrix = ref array[2, Vector] + +proc newVector(): Vector = + new(result) + +proc newMatrix(): Matrix = + new(result) + for ix in 0 .. 1: + result[ix] = newVector() + +let m = newMatrix() + +m[0][0] = 1.0 +echo "m[0][0] = ", m[0][0] + +GC_fullCollect() + +m[0][0] = 2.0 +echo "m[0][0] = ", m[0][0] -- cgit 1.4.1-2-gfad0 From 84a09d2f5b0866491e55fef0fef541e8cc548852 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 24 Aug 2016 11:48:40 +0200 Subject: minor things --- compiler/jsgen.nim | 2 +- todo.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 1790daf7a..80bcd2b0e 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -8,7 +8,7 @@ # # This is the JavaScript code generator. -# Soon also a PHP code generator. ;-) +# Also a PHP code generator. ;-) discard """ The JS code generator contains only 2 tricks: diff --git a/todo.txt b/todo.txt index 86bffcc3d..106f2bb34 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 1.0 battle plan ======================= +- iters for js - fix "high priority" bugs - try to fix as many compiler crashes as reasonable -- cgit 1.4.1-2-gfad0 From f1e4d8ed74549a868be58c15fc8cfe04159c52fd Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 25 Aug 2016 16:33:38 +0200 Subject: side-effect computation now done in the proper pass; fixes #4254 --- compiler/semexprs.nim | 9 --------- compiler/seminst.nim | 7 ++++--- compiler/sempass2.nim | 34 ++++++++++++++++++++++++++++++++-- tests/effects/tsidee4.nim | 6 +++--- 4 files changed, 39 insertions(+), 17 deletions(-) (limited to 'compiler') diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fc31829ba..e3552f94e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -701,9 +701,6 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, # error correction, prevents endless for loop elimination in transf. # See bug #2051: result.sons[0] = newSymNode(errorSym(c, n)) - if sfNoSideEffect notin callee.flags: - if {sfImportc, sfSideEffect} * callee.flags != {}: - incl(c.p.owner.flags, sfSideEffect) proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode @@ -804,9 +801,6 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = else: result = m.call instGenericConvertersSons(c, result, m) - # we assume that a procedure that calls something indirectly - # has side-effects: - if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) elif t != nil and t.kind == tyTypeDesc: if n.len == 1: return semObjConstr(c, n, flags) return semConv(c, n) @@ -1040,9 +1034,6 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = markUsed(n.info, s) styleCheckUse(n.info, s) - # if a proc accesses a global variable, it is not side effect free: - if sfGlobal in s.flags: - incl(c.p.owner.flags, sfSideEffect) result = newSymNode(s, n.info) # We cannot check for access to outer vars for example because it's still # not sure the symbol really ends up being used: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 460db4f7c..a57b8e520 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -172,9 +172,10 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) = popInfoContext() proc sideEffectsCheck(c: PContext, s: PSym) = - if {sfNoSideEffect, sfSideEffect} * s.flags == - {sfNoSideEffect, sfSideEffect}: - localError(s.info, errXhasSideEffects, s.name.s) + when false: + if {sfNoSideEffect, sfSideEffect} * s.flags == + {sfNoSideEffect, sfSideEffect}: + localError(s.info, errXhasSideEffects, s.name.s) proc instGenericContainer(c: PContext, info: TLineInfo, header: PType, allowMetaTypes = false): PType = diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index b12ab5e96..6d2e82ef0 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -59,7 +59,7 @@ type init: seq[int] # list of initialized variables guards: TModel # nested guards locked: seq[PNode] # locked locations - gcUnsafe, isRecursive, isToplevel: bool + gcUnsafe, isRecursive, isToplevel, hasSideEffect: bool maxLockLevel, currLockLevel: TLockLevel PEffects = var TEffects @@ -192,6 +192,14 @@ proc markGcUnsafe(a: PEffects; reason: PNode) = a.owner.gcUnsafetyReason = newSym(skUnknown, getIdent(""), a.owner, reason.info) +when true: + template markSideEffect(a: PEffects; reason: typed) = + a.hasSideEffect = true +else: + template markSideEffect(a: PEffects; reason: typed) = + a.hasSideEffect = true + markGcUnsafe(a, reason) + proc listGcUnsafety(s: PSym; onlyWarning: bool; cycleCheck: var IntSet) = let u = s.gcUnsafetyReason if u != nil and not cycleCheck.containsOrIncl(u.id): @@ -226,12 +234,16 @@ proc useVar(a: PEffects, n: PNode) = message(n.info, warnUninit, s.name.s) # prevent superfluous warnings about the same variable: a.init.add s.id - if {sfGlobal, sfThread} * s.flags != {} and s.kind in {skVar, skLet}: + if {sfGlobal, sfThread} * s.flags != {} and s.kind in {skVar, skLet} and + s.magic != mNimVm: if s.guard != nil: guardGlobal(a, n, s.guard) if {sfGlobal, sfThread} * s.flags == {sfGlobal} and (tfHasGCedMem in s.typ.flags or s.typ.isGCedMem): #if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) markGcUnsafe(a, s) + else: + markSideEffect(a, s) + type TIntersection = seq[tuple[id, count: int]] # a simple count table @@ -495,6 +507,8 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = if notGcSafe(s.typ) and sfImportc notin s.flags: if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) markGcUnsafe(tracked, s) + if tfNoSideEffect notin s.typ.flags: + markSideEffect(tracked, s) mergeLockLevels(tracked, n, s.getLockLevel) proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) = @@ -550,12 +564,16 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) = if notGcSafe(op) and not isOwnedProcVar(a, tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) markGcUnsafe(tracked, a) + elif tfNoSideEffect notin op.flags and not isOwnedProcVar(a, tracked.owner): + markSideEffect(tracked, a) else: mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) if notGcSafe(op): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) markGcUnsafe(tracked, a) + elif tfNoSideEffect notin op.flags: + markSideEffect(tracked, a) notNilCheck(tracked, n, paramType) proc breaksBlock(n: PNode): bool = @@ -684,6 +702,7 @@ proc track(tracked: PEffects, n: PNode) = if a.sym == tracked.owner: tracked.isRecursive = true # even for recursive calls we need to check the lock levels (!): mergeLockLevels(tracked, n, a.sym.getLockLevel) + if sfSideEffect in a.sym.flags: markSideEffect(tracked, a) else: mergeLockLevels(tracked, n, op.lockLevel) var effectList = op.n.sons[0] @@ -702,6 +721,10 @@ proc track(tracked: PEffects, n: PNode) = if not (a.kind == nkSym and a.sym == tracked.owner): if warnGcUnsafe in gNotes: warnAboutGcUnsafe(n) markGcUnsafe(tracked, a) + if tfNoSideEffect notin op.flags and not importedFromC(a): + # and it's not a recursive call: + if not (a.kind == nkSym and a.sym == tracked.owner): + markSideEffect(tracked, a) for i in 1 .. s.typ.lockLevel: diff --git a/tests/effects/tsidee4.nim b/tests/effects/tsidee4.nim index 2cb88a23e..ecc79580c 100644 --- a/tests/effects/tsidee4.nim +++ b/tests/effects/tsidee4.nim @@ -1,13 +1,13 @@ discard """ file: "tsidee4.nim" - line: 15 - errormsg: "type mismatch" + line: 12 + errormsg: "'noSideEffect' can have side effects" """ var global: int -proc dontcare(x: int): int = return x +proc dontcare(x: int): int = return global proc noSideEffect(x, y: int, p: proc (a: int): int {.noSideEffect.}): int {.noSideEffect.} = return x + y + dontcare(x) -- cgit 1.4.1-2-gfad0 From 89f3e21fc876e589de62f81aa1aa67e36eacc22e Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 13:02:52 +0200 Subject: fixes #4658 --- compiler/semstmts.nim | 5 +++++ tests/generics/tlamba_in_generic.nim | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/generics/tlamba_in_generic.nim (limited to 'compiler') diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f836d1803..f1f863924 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1396,6 +1396,11 @@ proc semMacroDef(c: PContext, n: PNode): PNode = if namePos >= result.safeLen: return result var s = result.sons[namePos].sym var t = s.typ + var allUntyped = true + for i in 1 .. t.n.len-1: + let param = t.n.sons[i].sym + if param.typ.kind != tyExpr: allUntyped = false + if allUntyped: incl(s.flags, sfAllUntyped) if t.sons[0] == nil: localError(n.info, errXNeedsReturnType, "macro") if n.sons[bodyPos].kind == nkEmpty: localError(n.info, errImplOfXexpected, s.name.s) diff --git a/tests/generics/tlamba_in_generic.nim b/tests/generics/tlamba_in_generic.nim new file mode 100644 index 000000000..91d417b5e --- /dev/null +++ b/tests/generics/tlamba_in_generic.nim @@ -0,0 +1,13 @@ +discard """ + output: '''!!Hi!!''' +""" +# bug #4658 +import future + +var x = 123 + +proc twice[T](f: T -> T): T -> T = (x: T) => f(f(x)) + +proc quote(s: string): string = "!" & s & "!" + +echo twice(quote)("Hi") -- cgit 1.4.1-2-gfad0 From e16bd735c48464ef5efcc48afbcbbd49cbf3cc74 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 13:23:15 +0200 Subject: explicit side-effects override the inferred effect; refs #4659 --- compiler/sempass2.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index a8fb9ef91..3908fa26e 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -935,7 +935,7 @@ proc trackProc*(s: PSym, body: PNode) = localError(s.info, errXhasSideEffects, s.name.s) if not t.gcUnsafe: s.typ.flags.incl tfGcSafe - if not t.hasSideEffect: + if not t.hasSideEffect and sfSideEffect notin s.flags: s.typ.flags.incl tfNoSideEffect if s.typ.lockLevel == UnspecifiedLockLevel: s.typ.lockLevel = t.maxLockLevel -- cgit 1.4.1-2-gfad0 From 969981c1da0e07d9d6867609a335c625779c04c3 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 13:32:52 +0200 Subject: fixes #3606 --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/ast.nim b/compiler/ast.nim index 5ed458aff..d301417ac 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1497,7 +1497,7 @@ proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool = proc getInt*(a: PNode): BiggestInt = case a.kind - of nkIntLit..nkUInt64Lit: result = a.intVal + of nkCharLit..nkUInt64Lit: result = a.intVal else: internalError(a.info, "getInt") result = 0 -- cgit 1.4.1-2-gfad0 From 4d4a993e7f47354b3de80c3f307a7a8d2b50e99b Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 13:51:58 +0200 Subject: fixes #2865 --- compiler/types.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/types.nim b/compiler/types.nim index ca2718ed1..c06e906e5 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -653,7 +653,14 @@ proc lengthOrd(t: PType): BiggestInt = case t.kind of tyInt64, tyInt32, tyInt: result = lastOrd(t) of tyDistinct, tyConst, tyMutable: result = lengthOrd(t.sons[0]) - else: result = lastOrd(t) - firstOrd(t) + 1 + else: + let last = lastOrd t + let first = firstOrd t + # XXX use a better overflow check here: + if last == high(BiggestInt) and first <= 0: + result = last + else: + result = lastOrd(t) - firstOrd(t) + 1 # -------------- type equality ----------------------------------------------- -- cgit 1.4.1-2-gfad0 From 1d1253c87f2cba4e498db48d16cbe88fb0d8850b Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 14:04:56 +0200 Subject: fixes #4253 --- compiler/types.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler') diff --git a/compiler/types.nim b/compiler/types.nim index c06e906e5..4690d5a1f 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1057,10 +1057,10 @@ proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind, of nkNone..nkNilLit: discard else: + if n.kind == nkRecCase and kind in {skProc, skConst}: + return n[0].typ for i in countup(0, sonsLen(n) - 1): let it = n.sons[i] - if it.kind == nkRecCase and kind in {skProc, skConst}: - return n.typ result = typeAllowedNode(marker, it, kind, flags) if result != nil: break -- cgit 1.4.1-2-gfad0 From 98859a72486038995f66d499f76172bb6e670a22 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 14:36:46 +0200 Subject: fixes #4292 --- compiler/sigmatch.nim | 9 +-------- tests/template/ttemp_in_varargs.nim | 9 +++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 tests/template/ttemp_in_varargs.nim (limited to 'compiler') diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ec429968c..949d4dc19 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1310,7 +1310,7 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, var call = newNodeI(nkCall, arg.info) call.add(f.n.copyTree) call.add(arg.copyTree) - result = c.semOverloadedCall(c, call, call, routineKinds) + result = c.semExpr(c, call) if result != nil: # resulting type must be consistent with the other arguments: var r = typeRel(m, f.sons[0], result.typ) @@ -1320,13 +1320,6 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, if r == isGeneric: result.typ = getInstantiatedType(c, arg, m, base(f)) m.baseTypeMatch = true - # bug #4545: allow the call to go through a 'var T': - let vt = result.sons[0].typ.sons[1] - if vt.kind == tyVar: - let x = result.sons[1] - let va = newNodeIT(nkHiddenAddr, x.info, vt) - va.add x - result.sons[1] = va proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) = case r diff --git a/tests/template/ttemp_in_varargs.nim b/tests/template/ttemp_in_varargs.nim new file mode 100644 index 000000000..be78e6ef2 --- /dev/null +++ b/tests/template/ttemp_in_varargs.nim @@ -0,0 +1,9 @@ +discard """ + output: '''a''' +""" + +# bug #4292 + +template foo(s: string): string = s +proc variadicProc*(v: varargs[string, foo]) = echo v[0] +variadicProc("a") -- cgit 1.4.1-2-gfad0 From be4748eb5728f2fe9fdfa2c56f6abbd617e55a83 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 14:57:59 +0200 Subject: do not crash on #3928 --- compiler/sigmatch.nim | 1 + 1 file changed, 1 insertion(+) (limited to 'compiler') diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 949d4dc19..7cdaa197d 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1312,6 +1312,7 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, call.add(arg.copyTree) result = c.semExpr(c, call) if result != nil: + if result.typ == nil: return nil # resulting type must be consistent with the other arguments: var r = typeRel(m, f.sons[0], result.typ) if r < isGeneric: return nil -- cgit 1.4.1-2-gfad0 From d3888577e9f0802abfcc92b9b7bda8b7f45996ed Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 15:15:18 +0200 Subject: fixes #3928 --- compiler/semcall.nim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'compiler') diff --git a/compiler/semcall.nim b/compiler/semcall.nim index b83872fe9..19c3f0bf9 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -444,3 +444,6 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = var resolved = semOverloadedCall(c, call, call, {fn.kind}) if resolved != nil: result = resolved.sons[0].sym + if not compareTypes(result.typ.sons[0], fn.typ.sons[0], dcEqIgnoreDistinct): + result = nil + -- cgit 1.4.1-2-gfad0 From da8f6e16cc2107db029a240e5c4d3f02ba707ba8 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 15:19:32 +0200 Subject: fixes #4491 --- compiler/semcall.nim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'compiler') diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 19c3f0bf9..b3fc020b1 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -446,4 +446,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = result = resolved.sons[0].sym if not compareTypes(result.typ.sons[0], fn.typ.sons[0], dcEqIgnoreDistinct): result = nil + elif result.magic in {mArrPut, mArrGet}: + # cannot borrow these magics for now + result = nil -- cgit 1.4.1-2-gfad0 From afb0d2e145a86964dfe23c19c4005874a0e16652 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 15:39:21 +0200 Subject: partial fix for #4623 --- compiler/semtypes.nim | 2 ++ 1 file changed, 2 insertions(+) (limited to 'compiler') diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 9d00c06ca..3834d0b51 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -110,6 +110,8 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, result = newOrPrevType(kind, prev, c) if sonsLen(n) == 2: var base = semTypeNode(c, n.sons[1], nil) + if base.kind == tyVoid: + localError(n.info, errTIsNotAConcreteType, typeToString(base)) addSonSkipIntLit(result, base) else: localError(n.info, errXExpectsOneTypeParam, kindStr) -- cgit 1.4.1-2-gfad0 From 976e95e17ca741dbae5ff33852e725104771ac4c Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 15:49:03 +0200 Subject: fixes #4580 --- compiler/msgs.nim | 4 ++-- compiler/semstmts.nim | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'compiler') diff --git a/compiler/msgs.nim b/compiler/msgs.nim index a926f0f49..c10c26ec5 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -65,7 +65,7 @@ type errPureTypeMismatch, errTypeMismatch, errButExpected, errButExpectedX, errAmbiguousCallXYZ, errWrongNumberOfArguments, errXCannotBePassedToProcVar, - errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProc, errImplOfXNotAllowed, + errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProcX, errImplOfXNotAllowed, errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValueX, errInvalidDiscard, errIllegalConvFromXtoY, errCannotBindXTwice, errInvalidOrderInArrayConstructor, @@ -274,7 +274,7 @@ const errWrongNumberOfArguments: "wrong number of arguments", errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar", errXCannotBeInParamDecl: "$1 cannot be declared in parameter declaration", - errPragmaOnlyInHeaderOfProc: "pragmas are only allowed in the header of a proc", + errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", errImplOfXNotAllowed: "implementation of \'$1\' is not allowed", errImplOfXexpected: "implementation of \'$1\' expected", errNoSymbolToBorrowFromFound: "no symbol to borrow from found", diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f1f863924..cd96600ec 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1227,7 +1227,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, implicitPragmas(c, s, n, validPragmas) else: if n.sons[pragmasPos].kind != nkEmpty: - localError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProc) + localError(n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX, + "'" & proto.name.s & "' from " & $proto.info) if sfForward notin proto.flags: wrongRedefinition(n.info, proto.name.s) excl(proto.flags, sfForward) -- cgit 1.4.1-2-gfad0 From 2b0e9aa16701e83c1f54f029cf44f5717740dbfa Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 16:48:42 +0200 Subject: fixes regression --- compiler/vmgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 3fc3f7556..6bfc33f00 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -748,7 +748,7 @@ proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = let tmp = c.genx(arg) if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opc, dest, tmp) - c.gABx(n, opc, 0, genType(c, n.typ)) + c.gABx(n, opc, 0, genType(c, n.typ.skipTypes({tyStatic}))) c.gABx(n, opc, 0, genType(c, arg.typ.skipTypes({tyStatic}))) c.freeTemp(tmp) -- cgit 1.4.1-2-gfad0 From b4d7ab3caab6b4e1b00d29071ebee7f0372f3512 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 17:29:56 +0200 Subject: fixes #4179; disallow assignments to openarrays --- compiler/semexprs.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'compiler') diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 16dc159bd..274bb15b9 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1400,8 +1400,9 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = # a = b # both are vars, means: a[] = b[] # a = b # b no 'var T' means: a = addr(b) var le = a.typ - if skipTypes(le, {tyGenericInst}).kind != tyVar and - isAssignable(c, a) == arNone: + if (skipTypes(le, {tyGenericInst}).kind != tyVar and + isAssignable(c, a) == arNone) or + skipTypes(le, abstractVar).kind in {tyOpenArray, tyVarargs}: # Direct assignment to a discriminant is allowed! localError(a.info, errXCannotBeAssignedTo, renderTree(a, {renderNoComments})) -- cgit 1.4.1-2-gfad0 From ff3cf001a39028601b295160492d90deeeb4b030 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 26 Aug 2016 18:00:12 +0200 Subject: fixes #4656; ropes.nim checks properly for file equality --- compiler/ropes.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'compiler') diff --git a/compiler/ropes.nim b/compiler/ropes.nim index bfae7aaa4..d84b59f78 100644 --- a/compiler/ropes.nim +++ b/compiler/ropes.nim @@ -310,15 +310,19 @@ proc equalsFile*(r: Rope, f: File): bool = buf: array[bufSize, char] bpos = buf.len blen = buf.len + btotal = 0 + rtotal = 0 for s in leaves(r): var spos = 0 let slen = s.len + rtotal += slen while spos < slen: if bpos == blen: # Read more data bpos = 0 blen = readBuffer(f, addr(buf[0]), buf.len) + btotal += blen if blen == 0: # no more data in file result = false return @@ -330,7 +334,8 @@ proc equalsFile*(r: Rope, f: File): bool = spos += n bpos += n - result = readBuffer(f, addr(buf[0]), 1) == 0 # check that we've read all + result = readBuffer(f, addr(buf[0]), 1) == 0 and + btotal == rtotal # check that we've read all proc equalsFile*(r: Rope, filename: string): bool = ## returns true if the contents of the file `f` equal `r`. If `f` does not -- cgit 1.4.1-2-gfad0 From 7e643d73788fd0799cc970601bc75592e9610039 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 27 Aug 2016 01:10:21 +0200 Subject: koch nsis: don't hardcode the path to NSIS --- compiler/installer.ini | 1 - 1 file changed, 1 deletion(-) (limited to 'compiler') diff --git a/compiler/installer.ini b/compiler/installer.ini index b802f08f1..4fc03dd1d 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -116,7 +116,6 @@ path = r"c:\Program Files (x86)\Inno Setup 5\iscc.exe" flags = "/Q" [NSIS] -path = r"c:\Program Files (x86)\NSIS\makensis.exe" flags = "/V0" [C_Compiler] -- cgit 1.4.1-2-gfad0