From 8fab2f81e3c7bd2630bd53d8c530165808b564c2 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Mon, 18 Jan 2016 13:16:31 +0200 Subject: [PATCH 01/14] Fixed unicode handling in JS. Fixes #3714. --- compiler/jsgen.nim | 20 +++++++++++++++++++- lib/system/jssys.nim | 33 ++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 14cdf0174a..16a03a4ec8 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -163,8 +163,26 @@ proc mangleName(s: PSym): Rope = add(result, rope(s.id)) s.loc.r = result +proc escapeJSString(s: string): string = + result = newStringOfCap(s.len + s.len shr 2) + result.add("\"") + for c in items(s): + case c + of '\l': result.add("\\n") + of '\r': result.add("\\r") + of '\t': result.add("\\t") + of '\b': result.add("\\b") + of '\a': result.add("\\a") + of '\e': result.add("\\e") + of '\v': result.add("\\v") + of '\\': result.add("\\\\") + of '\'': result.add("\\'") + of '\"': result.add("\\\"") + else: add(result, c) + result.add("\"") + proc makeJSString(s: string): Rope = - (if s.isNil: "null".rope else: strutils.escape(s).rope) + (if s.isNil: "null".rope else: escapeJSString(s).rope) include jstypes diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 5bac547728..0bb0ffadee 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -166,14 +166,33 @@ proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = """ proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} = - asm """ - var result = []; - for (var i = 0; i < `c`.length; ++i) { - result[i] = `c`.charCodeAt(i); + {.emit: """ + var ln = `c`.length; + var result = new Array(ln); + var r = 0; + for (var i = 0; i < ln; ++i) { + var ch = `c`.charCodeAt(i); + + if (ch < 128) { + result[r] = ch; } - result[result.length] = 0; // terminating zero - return result; - """ + else if((ch > 127) && (ch < 2048)) { + result[r] = (ch >> 6) | 192; + ++r; + result[r] = (ch & 63) | 128; + } + else { + result[r] = (ch >> 12) | 224; + ++r; + result[r] = ((ch >> 6) & 63) | 128; + ++r; + result[r] = (ch & 63) | 128; + } + ++r; + } + result[r] = 0; // terminating zero + return result; + """.} proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} = asm """ From 74be2ebe0e54af27f5644c25b1206031096616a5 Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Tue, 19 Jan 2016 17:05:22 +0100 Subject: [PATCH 02/14] I added the Gitter Chatroom for Nim which is really nice actually! --- web/community.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/community.txt b/web/community.txt index fba59f946d..f63ad5c250 100644 --- a/web/community.txt +++ b/web/community.txt @@ -86,6 +86,13 @@ Nim's Community The `G+ Nim community `_ is another place where discussions related to the language happen. Read and follow various articles, posts and interesting links about Nim. +.. container:: standout + + Gitter + ------ + + The `Gitter Chatroom for Nim `_ is the persistent logged "natural" chatroom for GitHub repositories and very easy to access for GitHub users. This does not need additional software and can send notifications about messages by email. + .. container:: standout Meetup From df211b24fdc221175fb0ce4dfef12a5293ed0c37 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Wed, 20 Jan 2016 23:52:14 +0200 Subject: [PATCH 03/14] Dont convert string to cstring when writing to stream. --- lib/pure/streams.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 38e91fee48..bb6175a124 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -148,7 +148,10 @@ proc write*[T](s: Stream, x: T) = proc write*(s: Stream, x: string) = ## writes the string `x` to the the stream `s`. No length field or ## terminating zero is written. - writeData(s, cstring(x), x.len) + when nimvm: + writeData(s, cstring(x), x.len) + else: + if x.len > 0: writeData(s, unsafeAddr x[0], x.len) proc writeLn*(s: Stream, args: varargs[string, `$`]) {.deprecated.} = ## **Deprecated since version 0.11.4:** Use **writeLine** instead. From c0d0e5efd935fbcce25de053f0b83bb2bb606faa Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Thu, 21 Jan 2016 01:27:34 +0200 Subject: [PATCH 04/14] Unsigned arith corrected for JS --- compiler/jsgen.nim | 142 ++++++++++----------------------- lib/system/jssys.nim | 36 --------- tests/misc/tunsignedinc.nim | 34 +++++--- tests/testament/categories.nim | 2 +- 4 files changed, 67 insertions(+), 147 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 14cdf0174a..c36f5a5a30 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -273,21 +273,21 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 - ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU - ["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU - ["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU - ["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU - ["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU + ["", "", "", ""], # addU + ["", "", "", ""], # subU + ["", "", "", ""], # mulU + ["", "", "", ""], # divU + ["", "", "($1 % $2)", "($1 % $2)"], # modU ["", "", "($1 == $2)", "($1 == $2)"], # EqI ["", "", "($1 <= $2)", "($1 <= $2)"], # LeI ["", "", "($1 < $2)", "($1 < $2)"], # LtI ["", "", "($1 == $2)", "($1 == $2)"], # EqF64 ["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 ["", "", "($1 < $2)", "($1 < $2)"], # LtF64 - ["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU - ["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU - ["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64 - ["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64 + ["", "", "($1 <= $2)", "($1 <= $2)"], # leU + ["", "", "($1 < $2)", "($1 < $2)"], # ltU + ["", "", "($1 <= $2)", "($1 <= $2)"], # leU64 + ["", "", "($1 < $2)", "($1 < $2)"], # ltU64 ["", "", "($1 == $2)", "($1 == $2)"], # EqEnum ["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum ["", "", "($1 < $2)", "($1 < $2)"], # LtEnum @@ -336,90 +336,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], ["", "", "$1", "$1"]] - luaOps: TMagicOps = [ - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # AddI - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # SubI - ["mulInt", "", "mulInt($1, $2)", "($1 * $2)"], # MulI - ["divInt", "", "divInt($1, $2)", "Math.floor($1 / $2)"], # DivI - ["modInt", "", "modInt($1, $2)", "Math.floor($1 % $2)"], # ModI - ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ - ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred - ["", "", "($1 + $2)", "($1 + $2)"], # AddF64 - ["", "", "($1 - $2)", "($1 - $2)"], # SubF64 - ["", "", "($1 * $2)", "($1 * $2)"], # MulF64 - ["", "", "($1 / $2)", "($1 / $2)"], # DivF64 - ["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI - ["", "", "($1 << $2)", "($1 << $2)"], # ShlI - ["", "", "($1 & $2)", "($1 & $2)"], # BitandI - ["", "", "($1 | $2)", "($1 | $2)"], # BitorI - ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 - ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU - ["subU", "subU", "subU($1, $2)", "subU($1, $2)"], # subU - ["mulU", "mulU", "mulU($1, $2)", "mulU($1, $2)"], # mulU - ["divU", "divU", "divU($1, $2)", "divU($1, $2)"], # divU - ["modU", "modU", "modU($1, $2)", "modU($1, $2)"], # modU - ["", "", "($1 == $2)", "($1 == $2)"], # EqI - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeI - ["", "", "($1 < $2)", "($1 < $2)"], # LtI - ["", "", "($1 == $2)", "($1 == $2)"], # EqF64 - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeF64 - ["", "", "($1 < $2)", "($1 < $2)"], # LtF64 - ["leU", "leU", "leU($1, $2)", "leU($1, $2)"], # leU - ["ltU", "ltU", "ltU($1, $2)", "ltU($1, $2)"], # ltU - ["leU64", "leU64", "leU64($1, $2)", "leU64($1, $2)"], # leU64 - ["ltU64", "ltU64", "ltU64($1, $2)", "ltU64($1, $2)"], # ltU64 - ["", "", "($1 == $2)", "($1 == $2)"], # EqEnum - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeEnum - ["", "", "($1 < $2)", "($1 < $2)"], # LtEnum - ["", "", "($1 == $2)", "($1 == $2)"], # EqCh - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeCh - ["", "", "($1 < $2)", "($1 < $2)"], # LtCh - ["", "", "($1 == $2)", "($1 == $2)"], # EqB - ["", "", "($1 <= $2)", "($1 <= $2)"], # LeB - ["", "", "($1 < $2)", "($1 < $2)"], # LtB - ["", "", "($1 == $2)", "($1 == $2)"], # EqRef - ["", "", "($1 == $2)", "($1 == $2)"], # EqUntracedRef - ["", "", "($1 <= $2)", "($1 <= $2)"], # LePtr - ["", "", "($1 < $2)", "($1 < $2)"], # LtPtr - ["", "", "($1 == $2)", "($1 == $2)"], # EqCString - ["", "", "($1 != $2)", "($1 != $2)"], # Xor - ["", "", "($1 == $2)", "($1 == $2)"], # EqProc - ["negInt", "", "negInt($1)", "-($1)"], # UnaryMinusI - ["negInt64", "", "negInt64($1)", "-($1)"], # UnaryMinusI64 - ["absInt", "", "absInt($1)", "Math.abs($1)"], # AbsI - ["", "", "not ($1)", "not ($1)"], # Not - ["", "", "+($1)", "+($1)"], # UnaryPlusI - ["", "", "~($1)", "~($1)"], # BitnotI - ["", "", "+($1)", "+($1)"], # UnaryPlusF64 - ["", "", "-($1)", "-($1)"], # UnaryMinusF64 - ["", "", "Math.abs($1)", "Math.abs($1)"], # AbsF64 - ["Ze8ToI", "Ze8ToI", "Ze8ToI($1)", "Ze8ToI($1)"], # mZe8ToI - ["Ze8ToI64", "Ze8ToI64", "Ze8ToI64($1)", "Ze8ToI64($1)"], # mZe8ToI64 - ["Ze16ToI", "Ze16ToI", "Ze16ToI($1)", "Ze16ToI($1)"], # mZe16ToI - ["Ze16ToI64", "Ze16ToI64", "Ze16ToI64($1)", "Ze16ToI64($1)"], # mZe16ToI64 - ["Ze32ToI64", "Ze32ToI64", "Ze32ToI64($1)", "Ze32ToI64($1)"], # mZe32ToI64 - ["ZeIToI64", "ZeIToI64", "ZeIToI64($1)", "ZeIToI64($1)"], # mZeIToI64 - ["toU8", "toU8", "toU8($1)", "toU8($1)"], # toU8 - ["toU16", "toU16", "toU16($1)", "toU16($1)"], # toU16 - ["toU32", "toU32", "toU32($1)", "toU32($1)"], # toU32 - ["", "", "$1", "$1"], # ToFloat - ["", "", "$1", "$1"], # ToBiggestFloat - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToInt - ["", "", "Math.floor($1)", "Math.floor($1)"], # ToBiggestInt - ["nimCharToStr", "nimCharToStr", "nimCharToStr($1)", "nimCharToStr($1)"], - ["nimBoolToStr", "nimBoolToStr", "nimBoolToStr($1)", "nimBoolToStr($1)"], [ - "cstrToNimstr", "cstrToNimstr", "cstrToNimstr(($1)+\"\")", - "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", "cstrToNimstr", - "cstrToNimstr(($1)+\"\")", - "cstrToNimstr(($1)+\"\")"], ["cstrToNimstr", - "cstrToNimstr", "cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")"], - ["cstrToNimstr", "cstrToNimstr", "cstrToNimstr($1)", "cstrToNimstr($1)"], - ["", "", "$1", "$1"]] - proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y: TCompRes useMagic(p, magic) @@ -428,6 +344,20 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = r.res = frmt % [x.rdLoc, y.rdLoc] r.kind = resExpr +proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) = + var x, y: TCompRes + gen(p, n.sons[1], x) + gen(p, n.sons[2], y) + let trimmer = case n[1].typ.skipTypes(abstractRange).size + of 1: "& 0xff" + of 2: "& 0xffff" + of 4: ">>> 0" + else: "" + if reassign: + r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + else: + r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y, z: TCompRes useMagic(p, magic) @@ -455,10 +385,16 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic, ops: TMagicOps) = else: gen(p, n.sons[1], r) r.res = ops[op][i + 2] % [r.rdLoc] - r.kind = resExpr proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = - arithAux(p, n, r, op, jsOps | luaOps) + case op + of mAddU: binaryUintExpr(p, n, r, "+") + of mSubU: binaryUintExpr(p, n, r, "-") + of mMulU: binaryUintExpr(p, n, r, "*") + of mDivU: binaryUintExpr(p, n, r, "/") + else: + arithAux(p, n, r, op, jsOps) + r.kind = resExpr proc genLineDir(p: PProc, n: PNode) = let line = toLinenumber(n.info) @@ -1406,11 +1342,17 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = else: unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)") of mInc: - if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2") - else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") + if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + binaryUintExpr(p, n, r, "+", true) + else: + if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2") + else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)") of ast.mDec: - if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") - else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") + if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64: + binaryUintExpr(p, n, r, "-", true) + else: + if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2") + else: binaryExpr(p, n, r, "subInt", "$1 = subInt($1, $2)") of mSetLengthStr: binaryExpr(p, n, r, "", "$1.length = $2+1; $1[$1.length-1] = 0") of mSetLengthSeq: binaryExpr(p, n, r, "", "$1.length = $2") of mCard: unaryExpr(p, n, r, "SetCard", "SetCard($1)") @@ -1635,7 +1577,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = case n.kind of nkSym: genSym(p, n, r) - of nkCharLit..nkInt64Lit: + of nkCharLit..nkUInt32Lit: if n.typ.kind == tyBool: r.res = if n.intVal == 0: rope"false" else: rope"true" else: diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 5bac547728..3df4609529 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -417,42 +417,6 @@ proc absInt(a: int): int {.compilerproc.} = proc absInt64(a: int64): int64 {.compilerproc.} = result = if a < 0: a*(-1) else: a -proc leU(a, b: int): bool {.compilerproc.} = - result = abs(a) <= abs(b) - -proc ltU(a, b: int): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc leU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) <= abs(b) -proc ltU64(a, b: int64): bool {.compilerproc.} = - result = abs(a) < abs(b) - -proc addU(a, b: int): int {.compilerproc.} = - result = abs(a) + abs(b) -proc addU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) + abs(b) - -proc subU(a, b: int): int {.compilerproc.} = - result = abs(a) - abs(b) -proc subU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) - abs(b) - -proc mulU(a, b: int): int {.compilerproc.} = - result = abs(a) * abs(b) -proc mulU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) * abs(b) - -proc divU(a, b: int): int {.compilerproc.} = - result = abs(a) div abs(b) -proc divU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) div abs(b) - -proc modU(a, b: int): int {.compilerproc.} = - result = abs(a) mod abs(b) -proc modU64(a, b: int64): int64 {.compilerproc.} = - result = abs(a) mod abs(b) - proc ze*(a: int): int {.compilerproc.} = result = a diff --git a/tests/misc/tunsignedinc.nim b/tests/misc/tunsignedinc.nim index 95622156f4..60c0559b0f 100644 --- a/tests/misc/tunsignedinc.nim +++ b/tests/misc/tunsignedinc.nim @@ -1,14 +1,28 @@ -discard """ - output: '''253''' -""" -# bug #2427 +block: # bug #2427 + var x = 0'u8 + dec x # OverflowError + x -= 1 # OverflowError + x = x - 1 # No error -import unsigned + doAssert(x == 253'u8) -var x = 0'u8 -dec x # OverflowError -x -= 1 # OverflowError -x = x - 1 # No error +block: + var x = 130'u8 + x += 130'u8 + doAssert(x == 4'u8) -echo x +block: + var x = 40000'u16 + x = x + 40000'u16 + doAssert(x == 14464'u16) + +block: + var x = 4000000000'u32 + x = x + 4000000000'u32 + doAssert(x == 3705032704'u32) + +block: + var x = 123'u16 + x -= 125 + doAssert(x == 65534'u16) diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 73d72289ca..3200c7da91 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -220,7 +220,7 @@ proc jsTests(r: var TResults, cat: Category, options: string) = "actiontable/tactiontable", "method/tmultim1", "method/tmultim3", "method/tmultim4", "varres/tvarres0", "varres/tvarres3", "varres/tvarres4", - "varres/tvartup"]: + "varres/tvartup", "misc/tunsignedinc"]: test "tests/" & testfile & ".nim" for testfile in ["pure/strutils"]: From 5f092520d1f7df15910664d0555bf4c7db8b90d3 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Thu, 21 Jan 2016 22:26:50 +0200 Subject: [PATCH 05/14] Revert "Fixed unicode handling in JS. Fixes #3714." --- compiler/jsgen.nim | 20 +------------------- lib/system/jssys.nim | 33 +++++++-------------------------- 2 files changed, 8 insertions(+), 45 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index efd6e874b7..c36f5a5a30 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -163,26 +163,8 @@ proc mangleName(s: PSym): Rope = add(result, rope(s.id)) s.loc.r = result -proc escapeJSString(s: string): string = - result = newStringOfCap(s.len + s.len shr 2) - result.add("\"") - for c in items(s): - case c - of '\l': result.add("\\n") - of '\r': result.add("\\r") - of '\t': result.add("\\t") - of '\b': result.add("\\b") - of '\a': result.add("\\a") - of '\e': result.add("\\e") - of '\v': result.add("\\v") - of '\\': result.add("\\\\") - of '\'': result.add("\\'") - of '\"': result.add("\\\"") - else: add(result, c) - result.add("\"") - proc makeJSString(s: string): Rope = - (if s.isNil: "null".rope else: escapeJSString(s).rope) + (if s.isNil: "null".rope else: strutils.escape(s).rope) include jstypes diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index abee95f404..3df4609529 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -166,33 +166,14 @@ proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = """ proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} = - {.emit: """ - var ln = `c`.length; - var result = new Array(ln); - var r = 0; - for (var i = 0; i < ln; ++i) { - var ch = `c`.charCodeAt(i); - - if (ch < 128) { - result[r] = ch; + asm """ + var result = []; + for (var i = 0; i < `c`.length; ++i) { + result[i] = `c`.charCodeAt(i); } - else if((ch > 127) && (ch < 2048)) { - result[r] = (ch >> 6) | 192; - ++r; - result[r] = (ch & 63) | 128; - } - else { - result[r] = (ch >> 12) | 224; - ++r; - result[r] = ((ch >> 6) & 63) | 128; - ++r; - result[r] = (ch & 63) | 128; - } - ++r; - } - result[r] = 0; // terminating zero - return result; - """.} + result[result.length] = 0; // terminating zero + return result; + """ proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} = asm """ From 5e8762c21e63c78939688f982b8c4721ac2eed07 Mon Sep 17 00:00:00 2001 From: Nick Greenfield Date: Mon, 18 Jan 2016 20:58:03 -0800 Subject: [PATCH 06/14] Improve warning msg when -d:profiler not passed Partially addresses #3741 --- lib/pure/nimprof.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index e2397b91c0..5a7deaab0e 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -12,7 +12,7 @@ ## report at program exit. when not defined(profiler) and not defined(memProfiler): - {.warning: "Profiling support is turned off!".} + {.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".} # We don't want to profile the profiling code ... {.push profiler: off.} From 9cad19f528f2ca844ba66383bb2eb6cb5c2994d3 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Thu, 21 Jan 2016 22:53:04 +0000 Subject: [PATCH 07/14] Small typo fixes in news. --- web/news.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/news.txt b/web/news.txt index 62c3cef242..61a74127f0 100644 --- a/web/news.txt +++ b/web/news.txt @@ -101,7 +101,7 @@ The following used to work as the environment creation used to be attached to th var s: seq[proc(): int {.closure.}] = @[] for i in 0 ..< 30: let ii = i - s.add(proc(): int = return ii*ii)) + s.add(proc(): int = return ii*ii) This behaviour has changed in 0.13.0 and now needs to be written as: @@ -133,8 +133,6 @@ via a commit, for a full list see (`#3498 `_) - Fixed "multimethods: Error: internal error: cgmeth.genConv" (`#3550 `_) -- Fixed "multimethods: Error: internal error: cgmeth.genConv" - (`#3550 `_) - Fixed "nimscript - SIGSEGV in except block" (`#3546 `_) - Fixed "Bool literals in macros do not work." From c3d09aeeac35d64b3b707b16d53a2945bb5ce348 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Fri, 22 Jan 2016 11:12:34 +0200 Subject: [PATCH 08/14] Fixed unicode strings in JS --- compiler/jsgen.nim | 35 +++++++++++++--- lib/system/jssys.nim | 45 +++++++++++++++++---- tests/js/tstringitems.nim | 84 ++++++++++++++++++++++++++++++++------- 3 files changed, 136 insertions(+), 28 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index c36f5a5a30..1e3adf1a90 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -163,8 +163,31 @@ proc mangleName(s: PSym): Rope = add(result, rope(s.id)) s.loc.r = result -proc makeJSString(s: string): Rope = - (if s.isNil: "null".rope else: strutils.escape(s).rope) +proc escapeJSString(s: string): string = + result = newStringOfCap(s.len + s.len shr 2) + result.add("\"") + for c in items(s): + case c + of '\l': result.add("\\n") + of '\r': result.add("\\r") + of '\t': result.add("\\t") + of '\b': result.add("\\b") + of '\a': result.add("\\a") + of '\e': result.add("\\e") + of '\v': result.add("\\v") + of '\\': result.add("\\\\") + of '\'': result.add("\\'") + of '\"': result.add("\\\"") + else: add(result, c) + result.add("\"") + +proc makeJSString(s: string, escapeNonAscii = true): Rope = + if s.isNil: + result = "null".rope + elif escapeNonAscii: + result = strutils.escape(s).rope + else: + result = escapeJSString(s).rope include jstypes @@ -568,7 +591,7 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) = if stringSwitch: case e.kind of nkStrLit..nkTripleStrLit: addf(p.body, "case $1: ", - [makeJSString(e.strVal)]) + [makeJSString(e.strVal, false)]) else: internalError(e.info, "jsgen.genCaseStmt: 2") else: gen(p, e, cond) @@ -1596,10 +1619,10 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = r.kind = resExpr of nkStrLit..nkTripleStrLit: if skipTypes(n.typ, abstractVarRange).kind == tyString: - useMagic(p, "cstrToNimstr") - r.res = "cstrToNimstr($1)" % [makeJSString(n.strVal)] + useMagic(p, "makeNimstrLit") + r.res = "makeNimstrLit($1)" % [makeJSString(n.strVal)] else: - r.res = makeJSString(n.strVal) + r.res = makeJSString(n.strVal, false) r.kind = resExpr of nkFloatLit..nkFloat64Lit: let f = n.floatVal diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 3df4609529..6eadae17a5 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -165,15 +165,46 @@ proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = return result; """ +proc makeNimstrLit(c: cstring): string {.asmNoStackFrame, compilerproc.} = + {.emit: """ + var ln = `c`.length; + var result = new Array(ln + 1); + var i = 0; + for (; i < ln; ++i) { + result[i] = `c`.charCodeAt(i); + } + result[i] = 0; // terminating zero + return result; + """.} + proc cstrToNimstr(c: cstring): string {.asmNoStackFrame, compilerproc.} = - asm """ - var result = []; - for (var i = 0; i < `c`.length; ++i) { - result[i] = `c`.charCodeAt(i); + {.emit: """ + var ln = `c`.length; + var result = new Array(ln); + var r = 0; + for (var i = 0; i < ln; ++i) { + var ch = `c`.charCodeAt(i); + + if (ch < 128) { + result[r] = ch; } - result[result.length] = 0; // terminating zero - return result; - """ + else if((ch > 127) && (ch < 2048)) { + result[r] = (ch >> 6) | 192; + ++r; + result[r] = (ch & 63) | 128; + } + else { + result[r] = (ch >> 12) | 224; + ++r; + result[r] = ((ch >> 6) & 63) | 128; + ++r; + result[r] = (ch & 63) | 128; + } + ++r; + } + result[r] = 0; // terminating zero + return result; + """.} proc toJSStr(s: string): cstring {.asmNoStackFrame, compilerproc.} = asm """ diff --git a/tests/js/tstringitems.nim b/tests/js/tstringitems.nim index f4ea02fec9..20aed6e8bf 100644 --- a/tests/js/tstringitems.nim +++ b/tests/js/tstringitems.nim @@ -3,22 +3,76 @@ discard """ Hello''' """ -# bug #2581 +block: # bug #2581 + const someVars = [ "Hello" ] + var someVars2 = [ "Hello" ] -const someVars = [ "Hello" ] -var someVars2 = [ "Hello" ] + proc getSomeVar: string = + for i in someVars: + if i == "Hello": + result = i + break -proc getSomeVar: string = - for i in someVars: - if i == "Hello": - result = i - break + proc getSomeVar2: string = + for i in someVars2: + if i == "Hello": + result = i + break -proc getSomeVar2: string = - for i in someVars2: - if i == "Hello": - result = i - break + echo getSomeVar() + echo getSomeVar2() -echo getSomeVar() -echo getSomeVar2() +block: # Test compile-time binary data generation, invalid unicode + proc signatureMaker(): string {. compiletime .} = + const signatureBytes = [137, 80, 78, 71, 13, 10, 26, 10] + result = "" + for c in signatureBytes: result.add chr(c) + + const cSig = signatureMaker() + + var rSig = newString(8) + rSig[0] = chr(137) + rSig[1] = chr(80) + rSig[2] = chr(78) + rSig[3] = chr(71) + rSig[4] = chr(13) + rSig[5] = chr(10) + rSig[6] = chr(26) + rSig[7] = chr(10) + + doAssert(rSig == cSig) + +block: # Test unicode strings + const constStr = "Привет!" + var jsStr : cstring + {.emit: """`jsStr`[0] = "Привет!";""".} + + doAssert($jsStr == constStr) + var runtimeStr = "При" + runtimeStr &= "вет!" + + doAssert(runtimeStr == constStr) + +block: # Conversions from/to cstring + proc stringSaysHelloInRussian(s: cstring): bool = + {.emit: """`result` = (`s` === "Привет!");""".} + + doAssert(stringSaysHelloInRussian("Привет!")) + + const constStr = "Привет!" + doAssert(stringSaysHelloInRussian(constStr)) + + var rtStr = "Привет!" + doAssert(stringSaysHelloInRussian(rtStr)) + +block: # String case of + const constStr = "Привет!" + var s = "Привет!" + + case s + of constStr: discard + else: doAssert(false) + + case s + of "Привет!": discard + else: doAssert(false) From d2ecd84f67c209eac883354c8009b5d6a52faabc Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Fri, 22 Jan 2016 18:30:07 +0200 Subject: [PATCH 09/14] JS: Corrected shift operators. Made casting between ints behave like C does. --- compiler/jsgen.nim | 58 ++++++++++++++++++++++++++++------ doc/tut2.txt | 4 ++- tests/misc/tints.nim | 39 +++++++++++++++++++---- tests/testament/categories.nim | 2 +- 4 files changed, 86 insertions(+), 17 deletions(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index c36f5a5a30..607b859248 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -264,7 +264,7 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 - $2)", "($1 - $2)"], # SubF64 ["", "", "($1 * $2)", "($1 * $2)"], # MulF64 ["", "", "($1 / $2)", "($1 / $2)"], # DivF64 - ["", "", "($1 >>> $2)", "($1 >>> $2)"], # ShrI + ["", "", "", ""], # ShrI ["", "", "($1 << $2)", "($1 << $2)"], # ShlI ["", "", "($1 & $2)", "($1 & $2)"], # BitandI ["", "", "($1 | $2)", "($1 | $2)"], # BitorI @@ -344,19 +344,22 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = r.res = frmt % [x.rdLoc, y.rdLoc] r.kind = resExpr +proc unsignedTrimmer(size: BiggestInt): Rope = + case size + of 1: rope"& 0xff" + of 2: rope"& 0xffff" + of 4: rope">>> 0" + else: rope"" + proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) = var x, y: TCompRes gen(p, n.sons[1], x) gen(p, n.sons[2], y) - let trimmer = case n[1].typ.skipTypes(abstractRange).size - of 1: "& 0xff" - of 2: "& 0xffff" - of 4: ">>> 0" - else: "" + let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size) if reassign: - r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer] else: - r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, rope trimmer] + r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer] proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) = var x, y, z: TCompRes @@ -392,6 +395,12 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = of mSubU: binaryUintExpr(p, n, r, "-") of mMulU: binaryUintExpr(p, n, r, "*") of mDivU: binaryUintExpr(p, n, r, "/") + of mShrI: + var x, y: TCompRes + gen(p, n.sons[1], x) + gen(p, n.sons[2], y) + let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size) + r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc] else: arithAux(p, n, r, op, jsOps) r.kind = resExpr @@ -1569,6 +1578,37 @@ proc genPragma(p: PProc, n: PNode) = of wEmit: genAsmOrEmitStmt(p, it.sons[1]) else: discard +proc genCast(p: PProc, n: PNode, r: var TCompRes) = + var dest = skipTypes(n.typ, abstractVarRange) + var src = skipTypes(n.sons[1].typ, abstractVarRange) + gen(p, n.sons[1], r) + if dest.kind == src.kind: + # no-op conversion + return + let toInt = (dest.kind in tyInt .. tyInt32) + let toUint = (dest.kind in tyUInt .. tyUInt32) + let fromInt = (src.kind in tyInt .. tyInt32) + let fromUint = (src.kind in tyUInt .. tyUInt32) + + if toUint and (fromInt or fromUint): + let trimmer = unsignedTrimmer(dest.size) + r.res = "($1 $2)" % [r.res, trimmer] + elif toInt: + if fromInt: + let trimmer = unsignedTrimmer(dest.size) + r.res = "($1 $2)" % [r.res, trimmer] + elif fromUint: + if src.size == 4 and dest.size == 4: + r.res = "($1|0)" % [r.res] + else: + let trimmer = unsignedTrimmer(dest.size) + let minuend = case dest.size + of 1: "0xfe" + of 2: "0xfffe" + of 4: "0xfffffffe" + else: "" + r.res = "($1 - ($2 $3))" % [rope minuend, r.res, trimmer] + proc gen(p: PProc, n: PNode, r: var TCompRes) = r.typ = etyNone r.kind = resNone @@ -1630,7 +1670,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = of nkCheckedFieldExpr: genCheckedFieldAccess(p, n, r) of nkObjDownConv: gen(p, n.sons[0], r) of nkObjUpConv: upConv(p, n, r) - of nkCast: gen(p, n.sons[1], r) + of nkCast: genCast(p, n, r) of nkChckRangeF: genRangeChck(p, n, r, "chckRangeF") of nkChckRange64: genRangeChck(p, n, r, "chckRange64") of nkChckRange: genRangeChck(p, n, r, "chckRange") diff --git a/doc/tut2.txt b/doc/tut2.txt index 5633445703..f60818da64 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -1000,7 +1000,9 @@ JavaScript-compatible code you should remember the following: - ``addr`` and ``ptr`` have slightly different semantic meaning in JavaScript. It is recommended to avoid those if you're not sure how they are translated to JavaScript. -- ``cast[T](x)`` in JavaScript is translated to ``(x)``. +- ``cast[T](x)`` in JavaScript is translated to ``(x)``, except for casting + between signed/unsigned ints, in which case it behaves as static cast in + C language. - ``cstring`` in JavaScript means JavaScript string. It is a good practice to use ``cstring`` only when it is semantically appropriate. E.g. don't use ``cstring`` as a binary data buffer. diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim index ded24fb5c3..5bfb8a17c4 100644 --- a/tests/misc/tints.nim +++ b/tests/misc/tints.nim @@ -23,24 +23,29 @@ template test(opr, a, b, c: expr): stmt {.immediate.} = test(`+`, 12'i8, -13'i16, -1'i16) test(`shl`, 0b11, 0b100, 0b110000) -test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64) +when not defined(js): + test(`shl`, 0b11'i32, 0b100'i64, 0b110000'i64) test(`shl`, 0b11'i32, 0b100'i32, 0b110000'i32) test(`or`, 0xf0f0'i16, 0x0d0d'i16, 0xfdfd'i16) test(`and`, 0xf0f0'i16, 0xfdfd'i16, 0xf0f0'i16) -test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64) +when not defined(js): + test(`shr`, 0xffffffffffffffff'i64, 0x4'i64, 0x0fffffffffffffff'i64) test(`shr`, 0xffff'i16, 0x4'i16, 0x0fff'i16) test(`shr`, 0xff'i8, 0x4'i8, 0x0f'i8) -test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64) +when not defined(js): + test(`shr`, 0xffffffff'i64, 0x4'i64, 0x0fffffff'i64) test(`shr`, 0xffffffff'i32, 0x4'i32, 0x0fffffff'i32) -test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64) +when not defined(js): + test(`shl`, 0xffffffffffffffff'i64, 0x4'i64, 0xfffffffffffffff0'i64) test(`shl`, 0xffff'i16, 0x4'i16, 0xfff0'i16) test(`shl`, 0xff'i8, 0x4'i8, 0xf0'i8) -test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) +when not defined(js): + test(`shl`, 0xffffffff'i64, 0x4'i64, 0xffffffff0'i64) test(`shl`, 0xffffffff'i32, 0x4'i32, 0xfffffff0'i32) # bug #916 @@ -50,5 +55,27 @@ proc unc(a: float): float = echo int(unc(0.5)), " ", int(unc(-0.5)) echo int(0.5), " ", int(-0.5) -echo("Success") #OUT Success +block: # Casts to uint + template testCast(fromValue: typed, toType: typed, expectedResult: typed) = + let src = fromValue + let dst = cast[toType](src) + if dst != expectedResult: + echo "Casting ", astToStr(fromValue), " to ", astToStr(toType), " = ", dst.int, " instead of ", astToStr(expectedResult) + doAssert(dst == expectedResult) + testCast(-1'i16, uint16, 0xffff'u16) + testCast(0xffff'u16, int16, -1'i16) + + testCast(0xff'u16, uint8, 0xff'u8) + testCast(0xffff'u16, uint8, 0xff'u8) + + testCast(-1'i16, uint32, 0xffffffff'u32) + testCast(0xffffffff'u32, int32, -1) + + testCast(0xfffffffe'u32, int32, -2'i32) + testCast(0xffffff'u32, int16, -1'i32) + + testCast(-5'i32, uint8, 251'u8) + + +echo("Success") #OUT Success diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim index 3200c7da91..ff83379b8c 100644 --- a/tests/testament/categories.nim +++ b/tests/testament/categories.nim @@ -220,7 +220,7 @@ proc jsTests(r: var TResults, cat: Category, options: string) = "actiontable/tactiontable", "method/tmultim1", "method/tmultim3", "method/tmultim4", "varres/tvarres0", "varres/tvarres3", "varres/tvarres4", - "varres/tvartup", "misc/tunsignedinc"]: + "varres/tvartup", "misc/tints", "misc/tunsignedinc"]: test "tests/" & testfile & ".nim" for testfile in ["pure/strutils"]: From 8dbe9ea3ab40984ca6a22e4d2a39e6197a98dcea Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Fri, 22 Jan 2016 19:54:53 +0200 Subject: [PATCH 10/14] Fixed isNil codegen in JS --- compiler/jsgen.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index c36f5a5a30..9e129a6da6 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -1324,7 +1324,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = of mEqStr: binaryExpr(p, n, r, "eqStrings", "eqStrings($1, $2)") of mLeStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) <= 0)") of mLtStr: binaryExpr(p, n, r, "cmpStrings", "(cmpStrings($1, $2) < 0)") - of mIsNil: unaryExpr(p, n, r, "", "$1 == null") + of mIsNil: unaryExpr(p, n, r, "", "($1 === null)") of mEnumToStr: genRepr(p, n, r) of mNew, mNewFinalize: genNew(p, n) of mSizeOf: r.res = rope(getSize(n.sons[1].typ)) From 22a65d12f0ab0009658d49007d1d536ef409ee11 Mon Sep 17 00:00:00 2001 From: Federico Ceratto Date: Sat, 23 Jan 2016 10:45:11 +0000 Subject: [PATCH 11/14] Switch git clone URLs to HTTPS GitHub recommends HTTPS for security reasons. --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 32dbad9f1c..27b2273f0c 100644 --- a/readme.md +++ b/readme.md @@ -39,9 +39,9 @@ To build from source you will need: If you are on a fairly modern *nix system, the following steps should work: ``` -$ git clone git://github.com/nim-lang/Nim.git +$ git clone https://github.com/nim-lang/Nim.git $ cd Nim -$ git clone --depth 1 git://github.com/nim-lang/csources +$ git clone --depth 1 https://github.com/nim-lang/csources $ cd csources && sh build.sh $ cd .. $ bin/nim c koch From 44ad71b7e03fc9b6e7bc94b22dde395ee5ddc4df Mon Sep 17 00:00:00 2001 From: def Date: Sun, 24 Jan 2016 13:55:44 +0100 Subject: [PATCH 12/14] Fix openssl md5 importcs --- lib/wrappers/openssl.nim | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index a227ac98c0..05843e2d3d 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -496,13 +496,12 @@ type data: array[MD5_LBLOCK, MD5_LONG] num: cuint -{.pragma: ic, importc: "$1".} {.push callconv:cdecl, dynlib:DLLUtilName.} -proc md5_Init*(c: var MD5_CTX): cint{.ic.} -proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.ic.} -proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.ic.} -proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.ic.} -proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.ic.} +proc md5_Init*(c: var MD5_CTX): cint{.importc: "MD5_Init".} +proc md5_Update*(c: var MD5_CTX; data: pointer; len: csize): cint{.importc: "MD5_Update".} +proc md5_Final*(md: cstring; c: var MD5_CTX): cint{.importc: "MD5_Final".} +proc md5*(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar{.importc: "MD5".} +proc md5_Transform*(c: var MD5_CTX; b: ptr cuchar){.importc: "MD5_Transform".} {.pop.} from strutils import toHex,toLower From 4e0f8cf595338ac2bd87eca5e3c2cbaacada5736 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 24 Jan 2016 14:02:20 +0100 Subject: [PATCH 13/14] Use ByteAddress instead of deprecated TAddress --- compiler/evalffi.nim | 16 ++++++++-------- lib/system/alloc.nim | 2 +- lib/system/gc.nim | 6 +++--- lib/system/gc_common.nim | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index b1a23802d0..75394c2f34 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -50,10 +50,10 @@ proc importcSymbol*(sym: PSym): PNode = # that contains the address instead: result = newNodeIT(nkPtrLit, sym.info, sym.typ) case name - of "stdin": result.intVal = cast[TAddress](system.stdin) - of "stdout": result.intVal = cast[TAddress](system.stdout) - of "stderr": result.intVal = cast[TAddress](system.stderr) - of "vmErrnoWrapper": result.intVal = cast[TAddress](myerrno) + of "stdin": result.intVal = cast[ByteAddress](system.stdin) + of "stdout": result.intVal = cast[ByteAddress](system.stdout) + of "stderr": result.intVal = cast[ByteAddress](system.stderr) + of "vmErrnoWrapper": result.intVal = cast[ByteAddress](myerrno) else: let lib = sym.annex if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}: @@ -71,7 +71,7 @@ proc importcSymbol*(sym: PSym): PNode = else: lib.path.strVal, sym.info) theAddr = dllhandle.symAddr(name) if theAddr.isNil: globalError(sym.info, "cannot import: " & sym.name.s) - result.intVal = cast[TAddress](theAddr) + result.intVal = cast[ByteAddress](theAddr) proc mapType(t: ast.PType): ptr libffi.TType = if t == nil: return addr libffi.type_void @@ -107,7 +107,7 @@ proc mapCallConv(cc: TCallingConvention, info: TLineInfo): TABI = template rd(T, p: expr): expr {.immediate.} = (cast[ptr T](p))[] template wr(T, p, v: expr) {.immediate.} = (cast[ptr T](p))[] = v template `+!`(x, y: expr): expr {.immediate.} = - cast[pointer](cast[TAddress](x) + y) + cast[pointer](cast[ByteAddress](x) + y) proc packSize(v: PNode, typ: PType): int = ## computes the size of the blob @@ -363,13 +363,13 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode = # in their unboxed representation so nothing it to be unpacked: result = n else: - awi(nkPtrLit, cast[TAddress](p)) + awi(nkPtrLit, cast[ByteAddress](p)) of tyPtr, tyRef, tyVar: let p = rd(pointer, x) if p.isNil: setNil() elif n == nil or n.kind == nkPtrLit: - awi(nkPtrLit, cast[TAddress](p)) + awi(nkPtrLit, cast[ByteAddress](p)) elif n != nil and n.len == 1: internalAssert n.kind == nkRefTy n.sons[0] = unpack(p, typ.lastSon, n.sons[0]) diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index b4462ed839..6de8e19e71 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -688,7 +688,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) = sysAssert(((cast[ByteAddress](p) and PageMask) - smallChunkOverhead()) %% s == 0, "rawDealloc 3") var f = cast[ptr FreeCell](p) - #echo("setting to nil: ", $cast[TAddress](addr(f.zeroField))) + #echo("setting to nil: ", $cast[ByteAddress](addr(f.zeroField))) sysAssert(f.zeroField != 0, "rawDealloc 1") f.zeroField = 0 f.next = c.freeList diff --git a/lib/system/gc.nim b/lib/system/gc.nim index c25cf46062..727b039d75 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -659,7 +659,7 @@ when useMarkForDebug or useBackupGc: proc stackMarkS(gch: var GcHeap, p: pointer) {.inline.} = # the addresses are not as cells on the stack, so turn them to cells: var cell = usrToCell(p) - var c = cast[TAddress](cell) + var c = cast[ByteAddress](cell) if c >% PageSize: # fast check: does it look like a cell? var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) @@ -805,8 +805,8 @@ proc markThreadStacks(gch: var GcHeap) = while it != nil: # mark registers: for i in 0 .. high(it.registers): gcMark(gch, it.registers[i]) - var sp = cast[TAddress](it.stackBottom) - var max = cast[TAddress](it.stackTop) + var sp = cast[ByteAddress](it.stackBottom) + var max = cast[ByteAddress](it.stackTop) # XXX stack direction? # XXX unroll this loop: while sp <=% max: diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim index 47e8b4b1f7..fdedcaf189 100644 --- a/lib/system/gc_common.nim +++ b/lib/system/gc_common.nim @@ -131,9 +131,9 @@ when defined(sparc): # For SPARC architecture. proc isOnStack(p: pointer): bool = var stackTop {.volatile.}: pointer stackTop = addr(stackTop) - var b = cast[TAddress](gch.stackBottom) - var a = cast[TAddress](stackTop) - var x = cast[TAddress](p) + var b = cast[ByteAddress](gch.stackBottom) + var a = cast[ByteAddress](stackTop) + var x = cast[ByteAddress](p) result = a <=% x and x <=% b template forEachStackSlot(gch, gcMark: expr) {.immediate, dirty.} = @@ -150,7 +150,7 @@ when defined(sparc): # For SPARC architecture. # Addresses decrease as the stack grows. while sp <= max: gcMark(gch, sp[]) - sp = cast[PPointer](cast[TAddress](sp) +% sizeof(pointer)) + sp = cast[PPointer](cast[ByteAddress](sp) +% sizeof(pointer)) elif defined(ELATE): {.error: "stack marking code is to be written for this architecture".} From 4246f660ea4ba7bab05811662eb53a87cc0cc049 Mon Sep 17 00:00:00 2001 From: def Date: Sun, 24 Jan 2016 19:18:16 +0100 Subject: [PATCH 14/14] Only use execvpe on linux, execvp elsewhere (fixes #3759) --- lib/pure/osproc.nim | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 8560c3ee44..34fb815205 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -886,7 +886,7 @@ elif not defined(useNimRtl): discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error)) exitnow(1) - when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android): + when not defined(uClibc) and (not defined(linux) or defined(android)): var environ {.importc.}: cstringArray proc startProcessAfterFork(data: ptr StartProcessData) = @@ -916,17 +916,16 @@ elif not defined(useNimRtl): discard fcntl(data.pErrorPipe[writeIdx], F_SETFD, FD_CLOEXEC) if data.optionPoUsePath: - when defined(macosx) or defined(freebsd) or defined(netbsd) or defined(android): + when defined(uClibc): + # uClibc environment (OpenWrt included) doesn't have the full execvpe + discard execve(data.sysCommand, data.sysArgs, data.sysEnv) + elif defined(linux) and not defined(android): + discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv) + else: # MacOSX doesn't have execvpe, so we need workaround. # On MacOSX we can arrive here only from fork, so this is safe: environ = data.sysEnv discard execvp(data.sysCommand, data.sysArgs) - else: - when defined(uClibc): - # uClibc environment (OpenWrt included) doesn't have the full execvpe - discard execve(data.sysCommand, data.sysArgs, data.sysEnv) - else: - discard execvpe(data.sysCommand, data.sysArgs, data.sysEnv) else: discard execve(data.sysCommand, data.sysArgs, data.sysEnv)