From b2dcec7500982b9c45e87b63a25eac779f5d62bf Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 14:08:01 -0800 Subject: [PATCH 01/20] _ --- lib/system.nim | 117 +++++++++++++++++++++++++++++-------- lib/system/comparisons.nim | 38 ------------ lib/system/nimscript.nim | 4 +- 3 files changed, 95 insertions(+), 64 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 92470fbcec703..18bee477eacc4 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -234,7 +234,6 @@ type ## pointer to the array data and a ## length field. varargs*[T]{.magic: "Varargs".} ## Generic type to construct a varargs type. - seq*[T]{.magic: "Seq".} ## Generic type to construct sequences. set*[T]{.magic: "Set".} ## Generic type to construct bit sets. when defined(nimUncheckedArrayTyp): @@ -518,8 +517,6 @@ type RootRef* = ref RootObj ## Reference to `RootObj`. -include "system/exceptions" - when defined(js) or defined(nimdoc): type JsRoot* = ref object of RootObj @@ -574,24 +571,87 @@ when defined(nimtypedescfixed): proc sizeof*(x: typedesc): int {.magic: "SizeOf", noSideEffect.} -proc newSeq*[T](s: var seq[T], len: Natural) {.magic: "NewSeq", noSideEffect.} - ## Creates a new sequence of type ``seq[T]`` with length ``len``. - ## - ## This is equivalent to ``s = @[]; setlen(s, len)``, but more - ## efficient since no reallocation is needed. - ## - ## Note that the sequence will be filled with zeroed entries. - ## After the creation of the sequence you should assign entries to - ## the sequence instead of adding them. Example: - ## - ## .. code-block:: Nim - ## var inputStrings : seq[string] - ## newSeq(inputStrings, 3) - ## assert len(inputStrings) == 3 - ## inputStrings[0] = "The fourth" - ## inputStrings[1] = "assignment" - ## inputStrings[2] = "would crash" - ## #inputStrings[3] = "out of bounds" +type seq*[T] = object + capacity: int + size: int + elems: ptr T + +template `+`[T](p: ptr T, off: int): ptr T = + cast[ptr T](cast[ByteAddress](p) +% off * sizeof(T)) + +proc len*[T](a: seq[T]): int = a.size + +proc checkAux(cond: bool) + +proc `[]`*[T](a: seq[T], index: int): var T = + # TODO: instead RangeCheck + checkAux(index >= 0) + checkAux(index < a.size) + (a.elems + index)[] + +proc `[]=`*[T](a: seq[T], index: int, val: T) = + checkAux(index >= 0) + checkAux(index < a.size) + (a.elems + index)[] = val + +iterator items*[T](a: seq[T]): T = + var i=0 + while i < len(a): + yield (a.elems + i)[] + i.inc + +proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = + ## Generic equals operator for sequences: relies on a equals operator for + ## the element type `T`. + when nimvm: + when not defined(nimNoNil): + if x.isNil and y.isNil: + return true + else: + if x.len == 0 and y.len == 0: + return true + else: + when not defined(js): + proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} = + when defined(nimSeqsV2): + result = cast[NimSeqV2[T]](x).p + else: + result = cast[pointer](x) + + if seqToPtr(x) == seqToPtr(y): + return true + else: + var sameObject = false + asm """`sameObject` = `x` === `y`""" + if sameObject: return true + + when not defined(nimNoNil): + if x.isNil or y.isNil: + return false + + if x.len != y.len: + return false + + for i in 0..x.len-1: + if x[i] != y[i]: + return false + + return true + +include "system/exceptions" + +proc resizeShared[T](p: ptr T, newSize: Natural): ptr T {.inline, raises: [].} +proc freeShared[T](p: ptr T) {.inline, benign, raises: [].} +proc createShared(T: typedesc, size = 1.Positive): ptr T {.inline.} + +proc newSeq*[T](s: var seq[T], len: Natural) {.noSideEffect.} = + if len > s.capacity: + # CHECKME: shared or not? + {.noSideEffect.}: + s.elems = resizeShared(s.elems, len) + s.capacity = len + s.size = len + # TODO: destroy/release other elems? proc newSeq*[T](len = 0.Natural): seq[T] = ## Creates a new sequence of type ``seq[T]`` with length ``len``. @@ -613,8 +673,7 @@ proc newSeq*[T](len = 0.Natural): seq[T] = ## #inputStrings[3] = "out of bounds" newSeq(result, len) -proc newSeqOfCap*[T](cap: Natural): seq[T] {. - magic: "NewSeqOfCap", noSideEffect.} = +proc newSeqOfCap*[T](cap: Natural): seq[T] {.noSideEffect.} = ## Creates a new sequence of type ``seq[T]`` with length zero and capacity ## ``cap``. ## @@ -623,7 +682,8 @@ proc newSeqOfCap*[T](cap: Natural): seq[T] {. ## assert len(x) == 0 ## x.add(10) ## assert len(x) == 1 - discard + result.elems = createShared(T, cap) + result.capacity = cap when not defined(js): proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] = @@ -676,6 +736,7 @@ proc len*(x: (type array)|array): int {.magic: "LengthArray", noSideEffect.} ## echo len(arr) # => 5 ## echo len(array[3..8, int]) # => 6 +# when false: # PRTEMP proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.} ## Returns the length of a sequence. ## @@ -1447,6 +1508,11 @@ const include "system/memalloc" + +proc `=destroy`*[T](x: var seq[T]) = + # echo "in destroy" + freeShared(x.elems) + proc `|`*(a, b: typedesc): typedesc = discard include "system/iterators_1" @@ -1680,6 +1746,9 @@ when defined(nimV2): import system/assertions export assertions +proc checkAux(cond: bool) = + assert(cond) + import system/iterators export iterators diff --git a/lib/system/comparisons.nim b/lib/system/comparisons.nim index 787820989e93e..aa3047bd74708 100644 --- a/lib/system/comparisons.nim +++ b/lib/system/comparisons.nim @@ -271,41 +271,3 @@ proc `==`*[T](x, y: openArray[T]): bool = return false result = true - -proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = - ## Generic equals operator for sequences: relies on a equals operator for - ## the element type `T`. - when nimvm: - when not defined(nimNoNil): - if x.isNil and y.isNil: - return true - else: - if x.len == 0 and y.len == 0: - return true - else: - when not defined(js): - proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} = - when defined(nimSeqsV2): - result = cast[NimSeqV2[T]](x).p - else: - result = cast[pointer](x) - - if seqToPtr(x) == seqToPtr(y): - return true - else: - var sameObject = false - asm """`sameObject` = `x` === `y`""" - if sameObject: return true - - when not defined(nimNoNil): - if x.isNil or y.isNil: - return false - - if x.len != y.len: - return false - - for i in 0..x.len-1: - if x[i] != y[i]: - return false - - return true diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim index 719e92c4a505f..c0985c63477ac 100644 --- a/lib/system/nimscript.nim +++ b/lib/system/nimscript.nim @@ -406,8 +406,8 @@ when not defined(nimble): backend*: string ## Nimble support: The package's backend. skipDirs*, skipFiles*, skipExt*, installDirs*, installFiles*, - installExt*, bin*: seq[string] = @[] ## Nimble metadata. - requiresData*: seq[string] = @[] ## Exposes the list of requirements for read + installExt*, bin*: seq[string] ## Nimble metadata. + requiresData*: seq[string] ## Exposes the list of requirements for read ## and write accesses. proc requires*(deps: varargs[string]) = From 7082bd816153667c52f5555a69369ea45977b0ee Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 14:08:04 -0800 Subject: [PATCH 02/20] _ --- lib/system.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/system.nim b/lib/system.nim index 18bee477eacc4..416f3ea39b51e 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -644,6 +644,8 @@ proc resizeShared[T](p: ptr T, newSize: Natural): ptr T {.inline, raises: [].} proc freeShared[T](p: ptr T) {.inline, benign, raises: [].} proc createShared(T: typedesc, size = 1.Positive): ptr T {.inline.} +proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} + proc newSeq*[T](s: var seq[T], len: Natural) {.noSideEffect.} = if len > s.capacity: # CHECKME: shared or not? From c4925c1f48106e46821dc780f170b88f49e7ae97 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 14:56:45 -0800 Subject: [PATCH 03/20] _ --- lib/pure/strutils.nim | 2 +- lib/pure/unicode.nim | 3 +- lib/system.nim | 76 ++++++++++++++++++++++--------------------- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 535af2b318c6b..9b572c98e45cc 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -407,7 +407,7 @@ template oldSplit(s, seps, maxsplit) = dec(splits) template accResult(iter: untyped) = - result = @[] + result = default(type(result)) for x in iter: add(result, x) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 8d76cc787c751..335ff13f8b63f 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1004,7 +1004,8 @@ iterator splitWhitespace*(s: string): string = splitCommon(s, unicodeSpaces, -1) template accResult(iter: untyped) = - result = @[] + # result = @[] + result = default(type(result)) for x in iter: add(result, x) proc splitWhitespace*(s: string): seq[string] {.noSideEffect, diff --git a/lib/system.nim b/lib/system.nim index 416f3ea39b51e..83acac4949375 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -581,6 +581,12 @@ template `+`[T](p: ptr T, off: int): ptr T = proc len*[T](a: seq[T]): int = a.size +proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.magic: "Slice".} +# proc toOpenArray*[T](x: seq[T]; first, last: int): var openArray[T] {.magic: "Slice".} +# converter toOpenArray2*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) +# converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) +converter toOpenArray2*[T](a: seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) + proc checkAux(cond: bool) proc `[]`*[T](a: seq[T], index: int): var T = @@ -594,12 +600,6 @@ proc `[]=`*[T](a: seq[T], index: int, val: T) = checkAux(index < a.size) (a.elems + index)[] = val -iterator items*[T](a: seq[T]): T = - var i=0 - while i < len(a): - yield (a.elems + i)[] - i.inc - proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = ## Generic equals operator for sequences: relies on a equals operator for ## the element type `T`. @@ -640,20 +640,12 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = include "system/exceptions" -proc resizeShared[T](p: ptr T, newSize: Natural): ptr T {.inline, raises: [].} -proc freeShared[T](p: ptr T) {.inline, benign, raises: [].} -proc createShared(T: typedesc, size = 1.Positive): ptr T {.inline.} - -proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} +# proc resizeShared[T](p: ptr T, newSize: Natural): ptr T {.inline, raises: [].} +# proc freeShared[T](p: ptr T) {.inline, benign, raises: [].} +# proc createShared(T: typedesc, size = 1.Positive): ptr T {.inline.} -proc newSeq*[T](s: var seq[T], len: Natural) {.noSideEffect.} = - if len > s.capacity: - # CHECKME: shared or not? - {.noSideEffect.}: - s.elems = resizeShared(s.elems, len) - s.capacity = len - s.size = len - # TODO: destroy/release other elems? +proc newSeq*[T](s: var seq[T], len: Natural) {.noSideEffect.} +proc newSeqOfCap*[T](cap: Natural): seq[T] {.noSideEffect.} proc newSeq*[T](len = 0.Natural): seq[T] = ## Creates a new sequence of type ``seq[T]`` with length ``len``. @@ -675,18 +667,6 @@ proc newSeq*[T](len = 0.Natural): seq[T] = ## #inputStrings[3] = "out of bounds" newSeq(result, len) -proc newSeqOfCap*[T](cap: Natural): seq[T] {.noSideEffect.} = - ## Creates a new sequence of type ``seq[T]`` with length zero and capacity - ## ``cap``. - ## - ## .. code-block:: Nim - ## var x = newSeqOfCap[int](5) - ## assert len(x) == 0 - ## x.add(10) - ## assert len(x) == 1 - result.elems = createShared(T, cap) - result.capacity = cap - when not defined(js): proc newSeqUninitialized*[T: SomeNumber](len: Natural): seq[T] = ## Creates a new sequence of type ``seq[T]`` with length ``len``. @@ -738,15 +718,14 @@ proc len*(x: (type array)|array): int {.magic: "LengthArray", noSideEffect.} ## echo len(arr) # => 5 ## echo len(array[3..8, int]) # => 6 -# when false: # PRTEMP -proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.} +when false: # PRTEMP + proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.} ## Returns the length of a sequence. ## ## .. code-block:: Nim ## var s = @[1, 1, 1, 1, 1] ## echo len(s) # => 5 - proc ord*[T: Ordinal|enum](x: T): int {.magic: "Ord", noSideEffect.} ## Returns the internal `int` value of an ordinal value ``x``. ## @@ -1509,11 +1488,34 @@ const include "system/memalloc" +proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} = + if len > s.capacity: + # CHECKME: shared or not? + {.noSideEffect.}: + when declared(resizeShared): # PRTEMP + s.elems = resizeShared(s.elems, len) + s.capacity = len + s.size = len + # TODO: destroy/release other elems? + +proc newSeqOfCap[T](cap: Natural): seq[T] {.noSideEffect.} = + ## Creates a new sequence of type ``seq[T]`` with length zero and capacity + ## ``cap``. + ## + ## .. code-block:: Nim + ## var x = newSeqOfCap[int](5) + ## assert len(x) == 0 + ## x.add(10) + ## assert len(x) == 1 + when declared(createShared): # PRTEMP + result.elems = createShared(T, cap) + result.capacity = cap proc `=destroy`*[T](x: var seq[T]) = # echo "in destroy" - freeShared(x.elems) + when declared(freeShared): # PRTEMP + freeShared(x.elems) proc `|`*(a, b: typedesc): typedesc = discard @@ -2969,8 +2971,8 @@ when not defined(js): proc toOpenArrayByte*(x: cstring; first, last: int): openArray[byte] {. magic: "Slice".} -proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {. - magic: "Slice".} +# proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {. +# magic: "Slice".} proc toOpenArray*[T](x: openArray[T]; first, last: int): openArray[T] {. magic: "Slice".} proc toOpenArray*[I, T](x: array[I, T]; first, last: I): openArray[T] {. From f44f16fc2e796af7b971f039335049c9fc91afb2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 15:16:16 -0800 Subject: [PATCH 04/20] _ --- lib/pure/os.nim | 2 -- lib/pure/strutils.nim | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 452c856a60463..0a05d12b15c54 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -2518,7 +2518,6 @@ proc parseCmdLine*(c: string): seq[string] {. ## * `paramStr proc <#paramStr,int>`_ ## * `commandLineParams proc <#commandLineParams>`_ - result = @[] var i = 0 var a = "" while true: @@ -2719,7 +2718,6 @@ when declared(paramCount) or defined(nimdoc): ## # Use commandLineParams() here ## else: ## # Do something else! - result = @[] for i in 1..paramCount(): result.add(paramStr(i)) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 9b572c98e45cc..5c0a265eda1c6 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -782,7 +782,7 @@ proc rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] ## * `splitLines proc<#splitLines,string>`_ ## * `splitWhitespace proc<#splitWhitespace,string,int>`_ accResult(rsplit(s, sep, maxsplit)) - result.reverse() + # result.reverse() proc rsplit*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[string] @@ -810,7 +810,7 @@ proc rsplit*(s: string, seps: set[char] = Whitespace, ## * `splitLines proc<#splitLines,string>`_ ## * `splitWhitespace proc<#splitWhitespace,string,int>`_ accResult(rsplit(s, seps, maxsplit)) - result.reverse() + # result.reverse() proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuRSplitString".} = @@ -846,7 +846,7 @@ proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] doAssert "a largely spaced sentence".rsplit(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] accResult(rsplit(s, sep, maxsplit)) - result.reverse() + # result.reverse() proc splitLines*(s: string, keepEol = false): seq[string] {.noSideEffect, rtl, extern: "nsuSplitLines".} = From 0a615add6253be02f25e5f7cc773386fbae3e9fc Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 16:11:21 -0800 Subject: [PATCH 05/20] _ --- lib/system.nim | 35 +++++++++++++++++++++++++++++------ lib/system/iterators.nim | 1 + 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 83acac4949375..b195f680cfeb7 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -585,7 +585,8 @@ proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.magic: "Slice" # proc toOpenArray*[T](x: seq[T]; first, last: int): var openArray[T] {.magic: "Slice".} # converter toOpenArray2*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) # converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) -converter toOpenArray2*[T](a: seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) +converter toOpenArray3*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) +converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) proc checkAux(cond: bool) @@ -908,8 +909,8 @@ proc cmp*(x, y: string): int {.noSideEffect, procvar.} ## can differ between operating systems! when defined(nimHasDefault): - proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {. - magic: "ArrToSeq", noSideEffect.} + # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.} + proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = ## Turns an array into a sequence. ## ## This most often useful for constructing @@ -923,6 +924,13 @@ when defined(nimHasDefault): ## ## echo @a # => @[1, 3, 5] ## echo @b # => @['f', 'o', 'o'] + var i=0 + let n = len(a) + let first = low(a) # IMPROVE SPEED when... + result = newSeq[T](n) + while i Date: Mon, 3 Feb 2020 16:11:28 -0800 Subject: [PATCH 06/20] _ --- lib/system.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index b195f680cfeb7..7c97253bcbad9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -583,8 +583,6 @@ proc len*[T](a: seq[T]): int = a.size proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.magic: "Slice".} # proc toOpenArray*[T](x: seq[T]; first, last: int): var openArray[T] {.magic: "Slice".} -# converter toOpenArray2*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) -# converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) converter toOpenArray3*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) From 10dbbe5229a049bfbd736a464f538b2583aa6ff9 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:03:19 -0800 Subject: [PATCH 07/20] _ --- compiler/semexprs.nim | 18 +++++++++++++++ lib/system.nim | 54 +++++++++++++++++++++++++++++++++---------- lib/system/gc.nim | 9 +++++++- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index cbdb5ce77c9e2..de8a610c0d828 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1633,6 +1633,24 @@ proc goodLineInfo(arg: PNode): TLineInfo = proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = checkSonsLen(n, 2, c.config) var a = n[0] + if n[1].renderTree == "@[]": # HACK + var n2 = newNodeI(nkCall, n.info) + n2.add newIdentNode(getIdent(c.cache, "reset"), n.info) + n2.add a + echo0b n2.renderTree + # n2.add newIdentNode(c.p.resultSym) + # n2.add newSymNode(c.p.resultSym) + # var call = newNodeIT(nkCall, n.info, n.typ) + # call.add(n[0]) + + # var n2 = newNodeI(nkAsgn, n.info) + # a.add newSymNode(c.p.resultSym) + # n2.add n[0] + # n2.add n[0] + # n[0] = semAsgn(c, a) + return semAsgn(c, n2, mode) + # return semAsgn(c, n, mode) + case a.kind of nkDotExpr: # r.f = x diff --git a/lib/system.nim b/lib/system.nim index 7c97253bcbad9..4b293c9749266 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -54,6 +54,11 @@ type include "system/basic_types" +type + ByteAddress* = int + ## is the signed integer type that should be used for converting + ## pointers to integer addresses for readability. + {.push warning[GcMem]: off, warning[Uninit]: off.} {.push hints: off.} @@ -906,9 +911,11 @@ proc cmp*(x, y: string): int {.noSideEffect, procvar.} ## **Note**: The precise result values depend on the used C runtime library and ## can differ between operating systems! +type VoidSeq* = object when defined(nimHasDefault): # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.} - proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = + # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = + proc `@`* [IDX, T](a: sink array[IDX, T]): auto {.noSideEffect.} = ## Turns an array into a sequence. ## ## This most often useful for constructing @@ -922,13 +929,18 @@ when defined(nimHasDefault): ## ## echo @a # => @[1, 3, 5] ## echo @b # => @['f', 'o', 'o'] - var i=0 - let n = len(a) - let first = low(a) # IMPROVE SPEED when... - result = newSeq[T](n) - while i 0: + var i=0 + let first = low(a) # IMPROVE SPEED when... + result = newSeq[T](n) + while i but expected 'seq[system.int]' + a.setLen 0 + proc setLen*[T](s: var seq[T], newlen: Natural) {.noSideEffect.} = ## Sets the length of seq `s` to `newlen`. ``T`` may be any sequence type. ## @@ -1342,10 +1363,6 @@ when not defined(nimV2): ## echo repr(i) # => 0x1055ed050[1, 2, 3, 4, 5] type - ByteAddress* = int - ## is the signed integer type that should be used for converting - ## pointers to integer addresses for readability. - BiggestFloat* = float64 ## is an alias for the biggest floating point type the Nim ## compiler supports. Currently this is ``float64``, but it is @@ -1509,12 +1526,15 @@ const include "system/memalloc" +# proc nimGCref*(p: pointer) {.compilerproc.} +proc nimGCrefImpl(p: pointer) {.importc: "nimGCrefImpl2".} proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} = if len > s.capacity: # CHECKME: shared or not? {.noSideEffect.}: when declared(resizeShared): # PRTEMP s.elems = resizeShared(s.elems, len) + nimGCrefImpl(s.elems) s.capacity = len s.size = len # TODO: destroy/release other elems? @@ -1530,13 +1550,23 @@ proc newSeqOfCap[T](cap: Natural): seq[T] {.noSideEffect.} = ## assert len(x) == 1 when declared(createShared): # PRTEMP result.elems = createShared(T, cap) + nimGCrefImpl(result.elems) result.capacity = cap proc `=destroy`*[T](x: var seq[T]) = # echo "in destroy" + var i=0 + while i < len(x): + # `=destroy`(x[i]) + reset(x[i]) + i.inc + # for i in 0..high(x): + # # `=destroy`(x[i]) + # reset(x[i]) when declared(freeShared): # PRTEMP freeShared(x.elems) + x.elems = nil proc `|`*(a, b: typedesc): typedesc = discard diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 7be9f4b1fc4b5..afbaadcd6686c 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -185,12 +185,19 @@ proc incRef(c: PCell) {.inline.} = # and not colorMask logCell("incRef", c) -proc nimGCref(p: pointer) {.compilerproc.} = +proc nimGCref*(p: pointer) {.compilerproc.} = +# proc nimGCref*(p: pointer) {.compilerproc, exportc.} = +# proc nimGCref(p: pointer) {.compilerproc, exportc.} = # we keep it from being collected by pretending it's not even allocated: let c = usrToCell(p) add(gch.additionalRoots, c) incRef(c) +# when not declared(nimGCrefImpl): +static: echo "D20200203T175609: nimGCrefImpl" +# proc nimGCrefImpl(p: pointer) {.exportc.} = nimGCref(p) +proc nimGCrefImpl2(p: pointer) {.exportc.} = nimGCref(p) + proc rtlAddZCT(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! addZCT(gch.zct, c) From 9b1d065e64274ccd40b5104812b137b2db4603ea Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:21:45 -0800 Subject: [PATCH 08/20] _ --- compiler/semexprs.nim | 7 ++++++- lib/system.nim | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index de8a610c0d828..fa03ff0c6ea7d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1634,6 +1634,10 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = checkSonsLen(n, 2, c.config) var a = n[0] if n[1].renderTree == "@[]": # HACK + echo0b n.renderTree + echo0b n[0].renderTree + echo0b n[1].renderTree + echo0b n.len var n2 = newNodeI(nkCall, n.info) n2.add newIdentNode(getIdent(c.cache, "reset"), n.info) n2.add a @@ -1648,7 +1652,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = # n2.add n[0] # n2.add n[0] # n[0] = semAsgn(c, a) - return semAsgn(c, n2, mode) + return semExpr(c, n2) + # return semAsgn(c, n2, mode) # return semAsgn(c, n, mode) case a.kind diff --git a/lib/system.nim b/lib/system.nim index 4b293c9749266..1a3637830dca4 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1565,7 +1565,8 @@ proc `=destroy`*[T](x: var seq[T]) = # # `=destroy`(x[i]) # reset(x[i]) when declared(freeShared): # PRTEMP - freeShared(x.elems) + if x.elems != nil: + freeShared(x.elems) x.elems = nil proc `|`*(a, b: typedesc): typedesc = discard From a52f532a05d9cd1affa205d2b0b56b5a08c87bd8 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:23:33 -0800 Subject: [PATCH 09/20] _ --- compiler/semexprs.nim | 17 ----------------- lib/pure/os.nim | 2 ++ 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fa03ff0c6ea7d..5e9d9829f739b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1634,27 +1634,10 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = checkSonsLen(n, 2, c.config) var a = n[0] if n[1].renderTree == "@[]": # HACK - echo0b n.renderTree - echo0b n[0].renderTree - echo0b n[1].renderTree - echo0b n.len var n2 = newNodeI(nkCall, n.info) n2.add newIdentNode(getIdent(c.cache, "reset"), n.info) n2.add a - echo0b n2.renderTree - # n2.add newIdentNode(c.p.resultSym) - # n2.add newSymNode(c.p.resultSym) - # var call = newNodeIT(nkCall, n.info, n.typ) - # call.add(n[0]) - - # var n2 = newNodeI(nkAsgn, n.info) - # a.add newSymNode(c.p.resultSym) - # n2.add n[0] - # n2.add n[0] - # n[0] = semAsgn(c, a) return semExpr(c, n2) - # return semAsgn(c, n2, mode) - # return semAsgn(c, n, mode) case a.kind of nkDotExpr: diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 0a05d12b15c54..452c856a60463 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -2518,6 +2518,7 @@ proc parseCmdLine*(c: string): seq[string] {. ## * `paramStr proc <#paramStr,int>`_ ## * `commandLineParams proc <#commandLineParams>`_ + result = @[] var i = 0 var a = "" while true: @@ -2718,6 +2719,7 @@ when declared(paramCount) or defined(nimdoc): ## # Use commandLineParams() here ## else: ## # Do something else! + result = @[] for i in 1..paramCount(): result.add(paramStr(i)) From f305fd97a352e6910309fd3b1cea46fac445ffb3 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:24:13 -0800 Subject: [PATCH 10/20] _ --- lib/pure/unicode.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 335ff13f8b63f..8d76cc787c751 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1004,8 +1004,7 @@ iterator splitWhitespace*(s: string): string = splitCommon(s, unicodeSpaces, -1) template accResult(iter: untyped) = - # result = @[] - result = default(type(result)) + result = @[] for x in iter: add(result, x) proc splitWhitespace*(s: string): seq[string] {.noSideEffect, From b370b3239108801875542680f35bcc24136dde21 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:24:52 -0800 Subject: [PATCH 11/20] _ --- lib/pure/strutils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 5c0a265eda1c6..09871a6ddebe9 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -407,7 +407,7 @@ template oldSplit(s, seps, maxsplit) = dec(splits) template accResult(iter: untyped) = - result = default(type(result)) + result = @[] for x in iter: add(result, x) From fc1b45780c372524681fadc003986765bb9517ea Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:34:42 -0800 Subject: [PATCH 12/20] _ --- lib/system.nim | 16 ++++++---------- lib/system/gc.nim | 7 +------ lib/system/iterators.nim | 1 - 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 1a3637830dca4..92e442731590e 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -586,10 +586,9 @@ template `+`[T](p: ptr T, off: int): ptr T = proc len*[T](a: seq[T]): int = a.size -proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {.magic: "Slice".} -# proc toOpenArray*[T](x: seq[T]; first, last: int): var openArray[T] {.magic: "Slice".} -converter toOpenArray3*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) -converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) +when false: + converter toOpenArray3*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) + converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) proc checkAux(cond: bool) @@ -912,6 +911,7 @@ proc cmp*(x, y: string): int {.noSideEffect, procvar.} ## can differ between operating systems! type VoidSeq* = object + when defined(nimHasDefault): # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.} # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = @@ -957,10 +957,6 @@ else: else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} -# proc `=`*[T](a: var seq[T], b: type(@[])) = -# proc `=`*[T](a: var seq[T], b: type(@[])) = -# proc `=`*[T](a: var seq[T], b: seq[VoidSeq]) = -# proc `=`*[T](a: var T, b: seq[VoidSeq]) = when false: proc `=`*[T](a: var T, b: VoidSeq) = # BUG: doesn't seem to work for: `var a = @[1,2]; a = @[]`; gives: type mismatch: got but expected 'seq[system.int]' @@ -3023,8 +3019,8 @@ when not defined(js): proc toOpenArrayByte*(x: cstring; first, last: int): openArray[byte] {. magic: "Slice".} -# proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {. -# magic: "Slice".} +proc toOpenArray*[T](x: seq[T]; first, last: int): openArray[T] {. + magic: "Slice".} proc toOpenArray*[T](x: openArray[T]; first, last: int): openArray[T] {. magic: "Slice".} proc toOpenArray*[I, T](x: array[I, T]; first, last: I): openArray[T] {. diff --git a/lib/system/gc.nim b/lib/system/gc.nim index afbaadcd6686c..1677457b9510d 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -185,17 +185,12 @@ proc incRef(c: PCell) {.inline.} = # and not colorMask logCell("incRef", c) -proc nimGCref*(p: pointer) {.compilerproc.} = -# proc nimGCref*(p: pointer) {.compilerproc, exportc.} = -# proc nimGCref(p: pointer) {.compilerproc, exportc.} = +proc nimGCref(p: pointer) {.compilerproc.} = # we keep it from being collected by pretending it's not even allocated: let c = usrToCell(p) add(gch.additionalRoots, c) incRef(c) -# when not declared(nimGCrefImpl): -static: echo "D20200203T175609: nimGCrefImpl" -# proc nimGCrefImpl(p: pointer) {.exportc.} = nimGCref(p) proc nimGCrefImpl2(p: pointer) {.exportc.} = nimGCref(p) proc rtlAddZCT(c: PCell) {.rtl, inl.} = diff --git a/lib/system/iterators.nim b/lib/system/iterators.nim index b6a16090a1680..53b287db000aa 100644 --- a/lib/system/iterators.nim +++ b/lib/system/iterators.nim @@ -184,7 +184,6 @@ iterator items*[T](a: seq[T]): T {.inline.} = var i = 0 let L = len(a) while i < L: - # echo (L, i) yield a[i] inc(i) assert(len(a) == L, "the length of the seq changed while iterating over it") From 85b0a27ac5d3ec985ab2cdc5471dc0c6e9dc4ae9 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:40:15 -0800 Subject: [PATCH 13/20] _ --- lib/pure/strutils.nim | 6 +++--- lib/system.nim | 24 +++++++----------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 09871a6ddebe9..ca0f702ead8b0 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -782,7 +782,7 @@ proc rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] ## * `splitLines proc<#splitLines,string>`_ ## * `splitWhitespace proc<#splitWhitespace,string,int>`_ accResult(rsplit(s, sep, maxsplit)) - # result.reverse() + # result.reverse() # TODO proc rsplit*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[string] @@ -810,7 +810,7 @@ proc rsplit*(s: string, seps: set[char] = Whitespace, ## * `splitLines proc<#splitLines,string>`_ ## * `splitWhitespace proc<#splitWhitespace,string,int>`_ accResult(rsplit(s, seps, maxsplit)) - # result.reverse() + # result.reverse() # TODO proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] {.noSideEffect, rtl, extern: "nsuRSplitString".} = @@ -846,7 +846,7 @@ proc rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] doAssert "a largely spaced sentence".rsplit(" ") == @["a", "", "largely", "", "", "", "spaced", "sentence"] accResult(rsplit(s, sep, maxsplit)) - # result.reverse() + # result.reverse() # TODO proc splitLines*(s: string, keepEol = false): seq[string] {.noSideEffect, rtl, extern: "nsuSplitLines".} = diff --git a/lib/system.nim b/lib/system.nim index 92e442731590e..989b6a7a1f60b 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -643,10 +643,6 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = include "system/exceptions" -# proc resizeShared[T](p: ptr T, newSize: Natural): ptr T {.inline, raises: [].} -# proc freeShared[T](p: ptr T) {.inline, benign, raises: [].} -# proc createShared(T: typedesc, size = 1.Positive): ptr T {.inline.} - proc newSeq*[T](s: var seq[T], len: Natural) {.noSideEffect.} proc newSeqOfCap*[T](cap: Natural): seq[T] {.noSideEffect.} @@ -910,8 +906,6 @@ proc cmp*(x, y: string): int {.noSideEffect, procvar.} ## **Note**: The precise result values depend on the used C runtime library and ## can differ between operating systems! -type VoidSeq* = object - when defined(nimHasDefault): # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.} # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = @@ -931,16 +925,12 @@ when defined(nimHasDefault): ## echo @b # => @['f', 'o', 'o'] {.noSideEffect.}: # IMPROVE" should move this to the relevant proc const n = len(a) - when n > 0: - var i=0 - let first = low(a) # IMPROVE SPEED when... - result = newSeq[T](n) - while i but expected 'seq[system.int]' a.setLen 0 From 08ab5ecbbf990aedc43633bd7ef45b9a67517ce0 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:44:51 -0800 Subject: [PATCH 14/20] _ --- lib/system.nim | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 989b6a7a1f60b..ff94862e8d4d9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -725,6 +725,7 @@ when false: # PRTEMP ## var s = @[1, 1, 1, 1, 1] ## echo len(s) # => 5 + proc ord*[T: Ordinal|enum](x: T): int {.magic: "Ord", noSideEffect.} ## Returns the internal `int` value of an ordinal value ``x``. ## @@ -907,9 +908,7 @@ proc cmp*(x, y: string): int {.noSideEffect, procvar.} ## can differ between operating systems! when defined(nimHasDefault): - # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.magic: "ArrToSeq", noSideEffect.} - # proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = - proc `@`* [IDX, T](a: sink array[IDX, T]): auto {.noSideEffect.} = + proc `@`* [IDX, T](a: sink array[IDX, T]): seq[T] {.noSideEffect.} = ## Turns an array into a sequence. ## ## This most often useful for constructing @@ -1224,28 +1223,17 @@ when notJSnotNims and hostOS != "standalone" and hostOS != "any": when notJSnotNims and hasAlloc and not defined(nimSeqsV2): proc addChar(s: NimString, c: char): NimString {.compilerproc, benign.} -when false: - when defined(nimscript) or not defined(nimSeqsV2): - proc add*[T](x: var seq[T], y: T) {.magic: "AppendSeqElem", noSideEffect.} - ## Generic proc for adding a data item `y` to a container `x`. - ## - ## For containers that have an order, `add` means *append*. New generic - ## containers should also call their adding proc `add` for consistency. - ## Generic code becomes much easier to write if the Nim naming scheme is - ## respected. - -when defined(nimscript) or not defined(nimSeqsV2): - proc add*[T](x: var seq[T], y: T) {.noSideEffect.} = - ## Generic proc for adding a data item `y` to a container `x`. - ## - ## For containers that have an order, `add` means *append*. New generic - ## containers should also call their adding proc `add` for consistency. - ## Generic code becomes much easier to write if the Nim naming scheme is - ## respected. - # CHECKME: SPEED: use doubling - let length = x.len - newSeq[T](x, length + 1) - x[length] = y +proc add*[T](x: var seq[T], y: T) {.noSideEffect.} = + ## Generic proc for adding a data item `y` to a container `x`. + ## + ## For containers that have an order, `add` means *append*. New generic + ## containers should also call their adding proc `add` for consistency. + ## Generic code becomes much easier to write if the Nim naming scheme is + ## respected. + # CHECKME: SPEED: use doubling + let length = x.len + newSeq[T](x, length + 1) + x[length] = y proc add*[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} = From 27c0a0019ddf3d55ffa849be42a50df2eb3c64cc Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:47:02 -0800 Subject: [PATCH 15/20] _ --- lib/system.nim | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index ff94862e8d4d9..ad9fada85c959 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -584,8 +584,6 @@ type seq*[T] = object template `+`[T](p: ptr T, off: int): ptr T = cast[ptr T](cast[ByteAddress](p) +% off * sizeof(T)) -proc len*[T](a: seq[T]): int = a.size - when false: converter toOpenArray3*[T](a: seq[T]): openArray[T] = toOpenArray(a, 0, len(a)-1) converter toOpenArray2*[T](a: var seq[T]): var openArray[T] = toOpenArray(a, 0, len(a)-1) @@ -717,13 +715,13 @@ proc len*(x: (type array)|array): int {.magic: "LengthArray", noSideEffect.} ## echo len(arr) # => 5 ## echo len(array[3..8, int]) # => 6 -when false: # PRTEMP - proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.} +proc len*[T](x: seq[T]): int {.noSideEffect.} = ## Returns the length of a sequence. ## ## .. code-block:: Nim ## var s = @[1, 1, 1, 1, 1] ## echo len(s) # => 5 + x.size proc ord*[T: Ordinal|enum](x: T): int {.magic: "Ord", noSideEffect.} From 3696123dd4b4c08063d5c8507096af97a85b8e2c Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:54:05 -0800 Subject: [PATCH 16/20] _ --- compiler/semexprs.nim | 2 +- lib/system.nim | 14 ++++++-------- lib/system/gc.nim | 2 -- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 5e9d9829f739b..7c9921c9a962f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1633,7 +1633,7 @@ proc goodLineInfo(arg: PNode): TLineInfo = proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = checkSonsLen(n, 2, c.config) var a = n[0] - if n[1].renderTree == "@[]": # HACK + if n[1].renderTree == "@[]": # HACK D20200203T184833:here var n2 = newNodeI(nkCall, n.info) n2.add newIdentNode(getIdent(c.cache, "reset"), n.info) n2.add a diff --git a/lib/system.nim b/lib/system.nim index ad9fada85c959..57b3942107158 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -945,9 +945,10 @@ else: proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} when false: - proc `=`*[T](a: var T, b: type(@[])) = - # BUG: doesn't seem to work for: `var a = @[1,2]; a = @[]`; gives: type mismatch: got but expected 'seq[system.int]' - a.setLen 0 + # attempt at fixing this: + # `var a = @[1,2]; a = @[]`; gives: type mismatch: got but expected 'seq[system.int]' + # this workaround didn't work, instead see HACK D20200203T184833 + proc `=`*[T](a: var T, b: type(@[])) = a.setLen 0 proc setLen*[T](s: var seq[T], newlen: Natural) {.noSideEffect.} = ## Sets the length of seq `s` to `newlen`. ``T`` may be any sequence type. @@ -1498,15 +1499,12 @@ const include "system/memalloc" -# proc nimGCref*(p: pointer) {.compilerproc.} -proc nimGCrefImpl(p: pointer) {.importc: "nimGCrefImpl2".} proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} = if len > s.capacity: - # CHECKME: shared or not? {.noSideEffect.}: - when declared(resizeShared): # PRTEMP + # CHECKME: shared or not? + when declared(resizeShared): s.elems = resizeShared(s.elems, len) - nimGCrefImpl(s.elems) s.capacity = len s.size = len # TODO: destroy/release other elems? diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 1677457b9510d..7be9f4b1fc4b5 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -191,8 +191,6 @@ proc nimGCref(p: pointer) {.compilerproc.} = add(gch.additionalRoots, c) incRef(c) -proc nimGCrefImpl2(p: pointer) {.exportc.} = nimGCref(p) - proc rtlAddZCT(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! addZCT(gch.zct, c) From 1d13ed2f5d9bbf939010417c22a2b5a3cd8118b6 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 18:55:59 -0800 Subject: [PATCH 17/20] _ --- lib/system.nim | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 57b3942107158..a503ac09aab72 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1528,13 +1528,9 @@ proc `=destroy`*[T](x: var seq[T]) = # echo "in destroy" var i=0 while i < len(x): - # `=destroy`(x[i]) reset(x[i]) i.inc - # for i in 0..high(x): - # # `=destroy`(x[i]) - # reset(x[i]) - when declared(freeShared): # PRTEMP + when declared(freeShared): if x.elems != nil: freeShared(x.elems) x.elems = nil From eceb8818d54859b1607874f65ea0ae6acd5b7c40 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 19:35:52 -0800 Subject: [PATCH 18/20] _ --- lib/system.nim | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index a503ac09aab72..4a6ae4d4879c9 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -604,32 +604,6 @@ proc `[]=`*[T](a: seq[T], index: int, val: T) = proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} = ## Generic equals operator for sequences: relies on a equals operator for ## the element type `T`. - when nimvm: - when not defined(nimNoNil): - if x.isNil and y.isNil: - return true - else: - if x.len == 0 and y.len == 0: - return true - else: - when not defined(js): - proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} = - when defined(nimSeqsV2): - result = cast[NimSeqV2[T]](x).p - else: - result = cast[pointer](x) - - if seqToPtr(x) == seqToPtr(y): - return true - else: - var sameObject = false - asm """`sameObject` = `x` === `y`""" - if sameObject: return true - - when not defined(nimNoNil): - if x.isNil or y.isNil: - return false - if x.len != y.len: return false @@ -1499,12 +1473,28 @@ const include "system/memalloc" +proc c_printf(frmt: cstring): cint {.importc: "printf", header: "", varargs, discardable.} + proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} = + let oldLen = s.len if len > s.capacity: {.noSideEffect.}: # CHECKME: shared or not? when declared(resizeShared): - s.elems = resizeShared(s.elems, len) + discard c_printf("len: %d %d %x\n", cast[int](len), cast[int](oldLen), s.elems) + # s.elems = resizeShared(s.elems, len) + s.elems = cast[ptr T](reallocShared0(s.elems, T.sizeof * s.capacity, T.sizeof * len)) + discard c_printf("len.2: %d %d %x\n", cast[int](len), cast[int](oldLen), s.elems) + when T is int: + s.size = len + for i in 0 .. (len-1): + # let ci = s.elems[i] + let ci = s[i] + discard c_printf("leni.3: i:%d %d\n", cast[cint](i), cast[cint](ci)) + + # for i in s.capacity .. (len-1): + # s.elems[i] + s.capacity = len s.size = len # TODO: destroy/release other elems? From 5a2c08cfe378cefcdddfb217b16376a46bd16221 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 19:39:34 -0800 Subject: [PATCH 19/20] _ --- lib/system.nim | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 4a6ae4d4879c9..245fd5deeb610 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1481,20 +1481,8 @@ proc newSeq[T](s: var seq[T], len: Natural) {.noSideEffect.} = {.noSideEffect.}: # CHECKME: shared or not? when declared(resizeShared): - discard c_printf("len: %d %d %x\n", cast[int](len), cast[int](oldLen), s.elems) - # s.elems = resizeShared(s.elems, len) + # BUG: this doesn't zero elements: s.elems = resizeShared(s.elems, len) s.elems = cast[ptr T](reallocShared0(s.elems, T.sizeof * s.capacity, T.sizeof * len)) - discard c_printf("len.2: %d %d %x\n", cast[int](len), cast[int](oldLen), s.elems) - when T is int: - s.size = len - for i in 0 .. (len-1): - # let ci = s.elems[i] - let ci = s[i] - discard c_printf("leni.3: i:%d %d\n", cast[cint](i), cast[cint](ci)) - - # for i in s.capacity .. (len-1): - # s.elems[i] - s.capacity = len s.size = len # TODO: destroy/release other elems? From d3fec981a131c2d7f80c4159329920310c7a8f04 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 3 Feb 2020 19:58:56 -0800 Subject: [PATCH 20/20] add test --- tests/seq/tseq2.nim | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/seq/tseq2.nim diff --git a/tests/seq/tseq2.nim b/tests/seq/tseq2.nim new file mode 100644 index 0000000000000..8295bf1846e39 --- /dev/null +++ b/tests/seq/tseq2.nim @@ -0,0 +1,23 @@ +proc main() = + var a = @[10,11] + a.add 12 + doAssert $a == "@[10, 11, 12]" + doAssert type(a) is seq[int] + doAssert type(a) is seq + var a2 = default(type(a)) + for ai in a: + a2.add ai*10 + doAssert a2 == @[100, 110, 120] + var a3 = newSeq[int](1) + doAssert a3 == @[0] + a3.add 17 + a3.newSeq(4) + doAssert a3 == @[0, 17, 0, 0] + var a4 = @["foo"] & @["bar"] + a4[0] = "FOO" + a4[1].add "t" + doAssert a4 == @["FOO", "bart"] + a4 = @[] + doAssert a4.len == 0 + +main()