diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-10-10 13:18:32 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-10-10 13:18:32 +0200 |
commit | 13f974336eff453fe4384ef2566f069b6fde75a1 (patch) | |
tree | b0849d565dafa26ae4d062e4bd18981c00714241 /compiler | |
parent | 8bd9c7a4e6cb789cd0e37d30c4c59080744cea39 (diff) | |
parent | 91981c07bd9335dbd32afb636bd1437a588f39eb (diff) | |
download | Nim-13f974336eff453fe4384ef2566f069b6fde75a1.tar.gz |
Merge branch 'araq-stringify-array' into devel
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/destroyer.nim | 62 | ||||
-rw-r--r-- | compiler/renderer.nim | 5 | ||||
-rw-r--r-- | compiler/rodutils.nim | 14 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 13 | ||||
-rw-r--r-- | compiler/types.nim | 8 |
6 files changed, 82 insertions, 21 deletions
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 9863e90bb..02c31163a 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -108,3 +108,4 @@ proc initDefines*() = defineSymbol("nimHasCppDefine") defineSymbol("nimGenericInOutFlags") when false: defineSymbol("nimHasOpt") + defineSymbol("nimNoArrayToCstringConversion") diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 2ccef1724..e7ff00bb9 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -39,6 +39,9 @@ ## x = y where y is read only once ## is the same as: move(x, y) ## +## Actually the more general rule is: The *last* read of ``y`` +## can become a move if ``y`` is the result of a construction. +## ## We also need to keep in mind here that the number of reads is ## control flow dependent: ## let x = foo() @@ -183,10 +186,67 @@ when false: of nkVarSection, nkLetSection: collectVarSection(c, n) else: discard +type + Con = object + owner: PSym + g: ControlFlowGraph + tmps: PType + +proc isHarmlessVar*(s: PSym; c: Con): bool = + # 's' is harmless if it used only once and its + # definition/usage are not split by any labels: + # + # let s = foo() + # while true: + # a[i] = s + # + # produces: + # + # def s + # L1: + # use s + # goto L1 + # + # let s = foo() + # if cond: + # a[i] = s + # else: + # a[j] = s + # + # produces: + # + # def s + # fork L2 + # use s + # goto L3 + # L2: + # use s + # L3 + # + # So this analysis is for now overly conservative, but correct. + discard + +template interestingSym(s: PSym): bool = + s.owner == owner and s.kind in InterestingSyms and hasDestructor(s.typ) + +proc p(n, parent: PNode; c: var Con) = + case n.kind + of nkVarSection, nkLetSection: + discard "transform; var x = y to var x; x op y where op is a move or copy" + of nkCallKinds: + if n.typ != nil and hasDestructor(n.typ): + discard "produce temp creation" + of nkAsgn, nkFastAsgn: + if n[0].kind == nkSym and interestingSym(n[0].sym): + discard "use move or assignment" + else: + for i in 0..<n.len: + p(n[i], n, c) + proc injectDestructorCalls*(owner: PSym; n: PNode; disableExceptions = false): PNode = when false: var c = Con(t: initTable[int, VarInfo](), owner: owner) collectData(c, n) var allTemps = createObj(owner, n.info) - + let cfg = constructCfg(owner, n) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index fba4dc9ea..4fbac45ab 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1011,7 +1011,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkPrefix: gsub(g, n, 0) if n.len > 1: - if n[1].kind == nkPrefix: + let opr = if n[0].kind == nkIdent: n[0].ident + elif n[0].kind == nkSym: n[0].sym.name + else: nil + if n[1].kind == nkPrefix or (opr != nil and renderer.isKeyword(opr)): put(g, tkSpaces, Space) if n.sons[1].kind == nkInfix: put(g, tkParLe, "(") diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim index 77f7c844f..0456e9349 100644 --- a/compiler/rodutils.nim +++ b/compiler/rodutils.nim @@ -10,7 +10,7 @@ ## Serialization utilities for the compiler. import strutils -proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", header: "<stdio.h>", nodecl, varargs.} +proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.} proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string = if f != f: @@ -21,9 +21,14 @@ proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string = if f > 0.0: result = "INF" else: result = "-INF" else: - var buf: array[0..80, char] - c_sprintf(buf, "%#.16e" & literalPostfix, f) - result = $buf + when defined(nimNoArrayToCstringConversion): + result = newString(81) + let n = c_snprintf(result.cstring, result.len.uint, "%#.16e%s", f, literalPostfix.cstring) + setLen(result, n) + else: + var buf: array[0..80, char] + discard c_snprintf(buf.cstring, buf.len.uint, "%#.16e%s", f, literalPostfix.cstring) + result = $buf.cstring proc encodeStr*(s: string, result: var string) = for i in countup(0, len(s) - 1): @@ -133,4 +138,3 @@ iterator decodeStrArray*(s: cstring): string = while s[i] != '\0': yield decodeStr(s, i) if s[i] == ' ': inc i - diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f2bc24399..50d4178b6 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1288,12 +1288,13 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType, of tyString: result = isConvertible of tyPtr: # ptr[Tag, char] is not convertible to 'cstring' for now: - if a.len == 1 and a.sons[0].kind == tyChar: result = isConvertible - of tyArray: - if (firstOrd(a.sons[0]) == 0) and - (skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and - (a.sons[1].kind == tyChar): - result = isConvertible + if a.len == 1: + let pointsTo = a.sons[0].skipTypes(abstractInst) + if pointsTo.kind == tyChar: result = isConvertible + elif pointsTo.kind == tyArray and firstOrd(pointsTo.sons[0]) == 0 and + skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and + pointsTo.sons[1].kind == tyChar: + result = isConvertible else: discard of tyEmpty, tyVoid: diff --git a/compiler/types.nim b/compiler/types.nim index 3dbf6fd18..f32b0da18 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -667,14 +667,6 @@ proc lengthOrd*(t: PType): BiggestInt = else: result = lastOrd(t) - firstOrd(t) + 1 -proc isCompatibleToCString*(a: PType): bool = - if a.kind == tyArray: - if (firstOrd(a.sons[0]) == 0) and - (skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in - {tyInt..tyInt64, tyUInt..tyUInt64}) and - (a.sons[1].kind == tyChar): - result = true - # -------------- type equality ----------------------------------------------- type |