added 'system.shallow'
This commit is contained in:
parent
b458dc7009
commit
fb35b855d5
9 changed files with 85 additions and 68 deletions
|
|
@ -411,7 +411,9 @@ var
|
||||||
|
|
||||||
proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
||||||
result.fullPath = fullPath
|
result.fullPath = fullPath
|
||||||
|
shallow(result.fullPath)
|
||||||
result.projPath = projPath
|
result.projPath = projPath
|
||||||
|
shallow(result.projPath)
|
||||||
|
|
||||||
proc fileInfoIdx*(filename: string): int32 =
|
proc fileInfoIdx*(filename: string): int32 =
|
||||||
var
|
var
|
||||||
|
|
@ -420,6 +422,7 @@ proc fileInfoIdx*(filename: string): int32 =
|
||||||
|
|
||||||
try:
|
try:
|
||||||
canon = canonicalizePath(filename)
|
canon = canonicalizePath(filename)
|
||||||
|
shallow(canon)
|
||||||
except:
|
except:
|
||||||
canon = filename
|
canon = filename
|
||||||
# The compiler uses "filenames" such as `command line` or `stdin`
|
# The compiler uses "filenames" such as `command line` or `stdin`
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const
|
||||||
defaultAsmMarkerSymbol* = '!'
|
defaultAsmMarkerSymbol* = '!'
|
||||||
VersionMajor* = 0
|
VersionMajor* = 0
|
||||||
VersionMinor* = 8
|
VersionMinor* = 8
|
||||||
VersionPatch* = 14
|
VersionPatch* = 15
|
||||||
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
|
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
|
||||||
|
|
||||||
RodFileVersion* = "1209" # modify this if the rod-format changes!
|
RodFileVersion* = "1209" # modify this if the rod-format changes!
|
||||||
|
|
|
||||||
|
|
@ -1507,7 +1507,7 @@ Syntax::
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc p(x, y: int): int {.optional.} =
|
proc p(x, y: int): int =
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
discard p(3, 4) # discard the return value of `p`
|
discard p(3, 4) # discard the return value of `p`
|
||||||
|
|
@ -3473,6 +3473,8 @@ a `thead-local`:idx: variable then:
|
||||||
Actor model
|
Actor model
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
**Caution**: This section is already outdated! XXX
|
||||||
|
|
||||||
Nimrod supports the `actor model`:idx: of concurrency natively:
|
Nimrod supports the `actor model`:idx: of concurrency natively:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
In this directory you will find several examples for how to use the Nimrod
|
In this directory you will find several examples for how to use the Nimrod
|
||||||
library.
|
library.
|
||||||
|
|
||||||
Copyright (c) 2004-2009 Andreas Rumpf.
|
Copyright (c) 2004-2012 Andreas Rumpf.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -145,13 +145,15 @@ proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} =
|
||||||
when not defined(EcmaScript) and not defined(NimrodVM):
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
type
|
type
|
||||||
TGenericSeq {.compilerproc, pure.} = object
|
TGenericSeq {.compilerproc, pure.} = object
|
||||||
len, space: int
|
len, reserved: int
|
||||||
PGenericSeq {.exportc.} = ptr TGenericSeq
|
PGenericSeq {.exportc.} = ptr TGenericSeq
|
||||||
# len and space without counting the terminating zero:
|
# len and space without counting the terminating zero:
|
||||||
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
|
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
|
||||||
data: array[0..100_000_000, char]
|
data: array[0..100_000_000, char]
|
||||||
NimString = ptr NimStringDesc
|
NimString = ptr NimStringDesc
|
||||||
|
|
||||||
|
template space(s: PGenericSeq): int = s.reserved and not seqShallowFlag
|
||||||
|
|
||||||
include "system/hti"
|
include "system/hti"
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -775,6 +777,8 @@ const
|
||||||
## a string that describes the application type. Possible values:
|
## a string that describes the application type. Possible values:
|
||||||
## "console", "gui", "lib".
|
## "console", "gui", "lib".
|
||||||
|
|
||||||
|
seqShallowFlag = 1 shl (sizeof(int)*8-1)
|
||||||
|
|
||||||
proc compileOption*(option: string): bool {.
|
proc compileOption*(option: string): bool {.
|
||||||
magic: "CompileOption", noSideEffect.}
|
magic: "CompileOption", noSideEffect.}
|
||||||
## can be used to determine an on|off compile-time option. Example:
|
## can be used to determine an on|off compile-time option. Example:
|
||||||
|
|
@ -2185,6 +2189,23 @@ template doAssert*(cond: expr, msg = "") =
|
||||||
raiseAssert(astToStr(cond) & ' ' & msg)
|
raiseAssert(astToStr(cond) & ' ' & msg)
|
||||||
|
|
||||||
|
|
||||||
|
proc shallow*[T](s: seq[T]) {.noSideEffect, inline.} =
|
||||||
|
## marks a sequence `s` as `shallow`:idx:. Subsequent assignments will not
|
||||||
|
## perform deep copies of `s`. This is only useful for optimization
|
||||||
|
## purposes.
|
||||||
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
|
var s = cast[PGenericSeq](s)
|
||||||
|
s.reserved = s.reserved or seqShallowFlag
|
||||||
|
|
||||||
|
proc shallow*(s: string) {.noSideEffect, inline.} =
|
||||||
|
## marks a string `s` as `shallow`:idx:. Subsequent assignments will not
|
||||||
|
## perform deep copies of `s`. This is only useful for optimization
|
||||||
|
## purposes.
|
||||||
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
|
var s = cast[PGenericSeq](s)
|
||||||
|
s.reserved = s.reserved or seqShallowFlag
|
||||||
|
|
||||||
|
|
||||||
when defined(initDebugger):
|
when defined(initDebugger):
|
||||||
initDebugger()
|
initDebugger()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
|
||||||
of tyString:
|
of tyString:
|
||||||
var x = cast[ppointer](dest)
|
var x = cast[ppointer](dest)
|
||||||
var s2 = cast[ppointer](s)[]
|
var s2 = cast[ppointer](s)[]
|
||||||
if s2 == nil or shallow:
|
if s2 == nil or shallow or (
|
||||||
|
cast[PGenericSeq](s2).reserved and seqShallowFlag) != 0:
|
||||||
unsureAsgnRef(x, s2)
|
unsureAsgnRef(x, s2)
|
||||||
else:
|
else:
|
||||||
unsureAsgnRef(x, copyString(cast[NimString](s2)))
|
unsureAsgnRef(x, copyString(cast[NimString](s2)))
|
||||||
|
|
@ -46,7 +47,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
|
||||||
var s2 = cast[ppointer](src)[]
|
var s2 = cast[ppointer](src)[]
|
||||||
var seq = cast[PGenericSeq](s2)
|
var seq = cast[PGenericSeq](s2)
|
||||||
var x = cast[ppointer](dest)
|
var x = cast[ppointer](dest)
|
||||||
if s2 == nil or shallow:
|
if s2 == nil or shallow or (seq.reserved and seqShallowFlag) != 0:
|
||||||
# this can happen! nil sequences are allowed
|
# this can happen! nil sequences are allowed
|
||||||
unsureAsgnRef(x, s2)
|
unsureAsgnRef(x, s2)
|
||||||
return
|
return
|
||||||
|
|
@ -61,7 +62,7 @@ proc genericAssignAux(dest, src: Pointer, mt: PNimType, shallow: bool) =
|
||||||
mt.Base, shallow)
|
mt.Base, shallow)
|
||||||
var dstseq = cast[PGenericSeq](dst)
|
var dstseq = cast[PGenericSeq](dst)
|
||||||
dstseq.len = seq.len
|
dstseq.len = seq.len
|
||||||
dstseq.space = seq.len
|
dstseq.reserved = seq.len
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
# we don't need to copy m_type field for tyObject, as they are equal anyway
|
# we don't need to copy m_type field for tyObject, as they are equal anyway
|
||||||
genericAssignAux(dest, src, mt.node, shallow)
|
genericAssignAux(dest, src, mt.node, shallow)
|
||||||
|
|
|
||||||
|
|
@ -426,7 +426,7 @@ proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
||||||
# `newObj` already uses locks, so no need for them here.
|
# `newObj` already uses locks, so no need for them here.
|
||||||
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
result = newObj(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
||||||
cast[PGenericSeq](result).len = len
|
cast[PGenericSeq](result).len = len
|
||||||
cast[PGenericSeq](result).space = len
|
cast[PGenericSeq](result).reserved = len
|
||||||
|
|
||||||
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
# generates a new object and sets its reference counter to 1
|
# generates a new object and sets its reference counter to 1
|
||||||
|
|
@ -457,7 +457,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||||
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
||||||
result = newObjRC1(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
result = newObjRC1(typ, addInt(mulInt(len, typ.base.size), GenericSeqSize))
|
||||||
cast[PGenericSeq](result).len = len
|
cast[PGenericSeq](result).len = len
|
||||||
cast[PGenericSeq](result).space = len
|
cast[PGenericSeq](result).reserved = len
|
||||||
|
|
||||||
proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
acquire(gch)
|
acquire(gch)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ proc rawNewString(space: int): NimString {.compilerProc.} =
|
||||||
var s = space
|
var s = space
|
||||||
if s < 8: s = 7
|
if s < 8: s = 7
|
||||||
result = allocStr(sizeof(TGenericSeq) + s + 1)
|
result = allocStr(sizeof(TGenericSeq) + s + 1)
|
||||||
result.space = s
|
result.reserved = s
|
||||||
|
|
||||||
proc mnewString(len: int): NimString {.compilerProc.} =
|
proc mnewString(len: int): NimString {.compilerProc.} =
|
||||||
result = rawNewString(len)
|
result = rawNewString(len)
|
||||||
|
|
@ -73,7 +73,9 @@ proc cstrToNimstr(str: CString): NimString {.compilerProc.} =
|
||||||
result = toNimstr(str, c_strlen(str))
|
result = toNimstr(str, c_strlen(str))
|
||||||
|
|
||||||
proc copyString(src: NimString): NimString {.compilerProc.} =
|
proc copyString(src: NimString): NimString {.compilerProc.} =
|
||||||
if src != nil:
|
if (src.reserved and seqShallowFlag) != 0:
|
||||||
|
result = src
|
||||||
|
elif src != nil:
|
||||||
result = rawNewString(src.space)
|
result = rawNewString(src.space)
|
||||||
result.len = src.len
|
result.len = src.len
|
||||||
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
||||||
|
|
@ -87,7 +89,7 @@ proc copyStringRC1(src: NimString): NimString {.compilerProc.} =
|
||||||
s+1))
|
s+1))
|
||||||
else:
|
else:
|
||||||
result = allocStr(sizeof(TGenericSeq) + s + 1)
|
result = allocStr(sizeof(TGenericSeq) + s + 1)
|
||||||
result.space = s
|
result.reserved = s
|
||||||
result.len = src.len
|
result.len = src.len
|
||||||
c_memcpy(result.data, src.data, src.len + 1)
|
c_memcpy(result.data, src.data, src.len + 1)
|
||||||
|
|
||||||
|
|
@ -108,13 +110,9 @@ proc addChar(s: NimString, c: char): NimString =
|
||||||
# is compilerproc!
|
# is compilerproc!
|
||||||
result = s
|
result = s
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
result.space = resize(result.space)
|
result.reserved = resize(result.space)
|
||||||
result = cast[NimString](growObj(result,
|
result = cast[NimString](growObj(result,
|
||||||
sizeof(TGenericSeq) + (result.space+1) * sizeof(char)))
|
sizeof(TGenericSeq) + (result.reserved+1) * sizeof(char)))
|
||||||
#var space = resize(result.space)
|
|
||||||
#result = rawNewString(space)
|
|
||||||
#copyMem(result, s, s.len * sizeof(char) + sizeof(TGenericSeq))
|
|
||||||
#result.space = space
|
|
||||||
result.data[result.len] = c
|
result.data[result.len] = c
|
||||||
result.data[result.len+1] = '\0'
|
result.data[result.len+1] = '\0'
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
|
|
@ -156,7 +154,7 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerproc.} =
|
||||||
else: # slow path:
|
else: # slow path:
|
||||||
var sp = max(resize(dest.space), dest.len + addLen)
|
var sp = max(resize(dest.space), dest.len + addLen)
|
||||||
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1))
|
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) + sp + 1))
|
||||||
result.space = sp
|
result.reserved = sp
|
||||||
#result = rawNewString(sp)
|
#result = rawNewString(sp)
|
||||||
#copyMem(result, dest, dest.len * sizeof(char) + sizeof(TGenericSeq))
|
#copyMem(result, dest, dest.len * sizeof(char) + sizeof(TGenericSeq))
|
||||||
# DO NOT UPDATE LEN YET: dest.len = newLen
|
# DO NOT UPDATE LEN YET: dest.len = newLen
|
||||||
|
|
@ -188,43 +186,19 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
||||||
# add(seq, x) generates:
|
# add(seq, x) generates:
|
||||||
# seq = incrSeq(seq, sizeof(x));
|
# seq = incrSeq(seq, sizeof(x));
|
||||||
# seq[seq->len-1] = x;
|
# seq[seq->len-1] = x;
|
||||||
when false:
|
|
||||||
# broken version:
|
|
||||||
result = seq
|
result = seq
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
var s = resize(result.space)
|
result.reserved = resize(result.space)
|
||||||
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
result = cast[PGenericSeq](growObj(result, elemSize * result.reserved +
|
||||||
genericSeqAssign(result, seq, XXX)
|
|
||||||
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
|
||||||
inc(result.len)
|
|
||||||
else:
|
|
||||||
result = seq
|
|
||||||
if result.len >= result.space:
|
|
||||||
result.space = resize(result.space)
|
|
||||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
|
||||||
GenericSeqSize))
|
GenericSeqSize))
|
||||||
# set new elements to zero:
|
|
||||||
#var s = cast[TAddress](result)
|
|
||||||
#zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
|
||||||
# (result.space - result.len) * elemSize)
|
|
||||||
# for i in len .. space-1:
|
|
||||||
# seq->data[i] = 0
|
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
|
|
||||||
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
compilerRtl.} =
|
compilerRtl.} =
|
||||||
when false:
|
|
||||||
# broken version:
|
|
||||||
result = seq
|
result = seq
|
||||||
if result.space < newLen:
|
if result.space < newLen:
|
||||||
var s = max(resize(result.space), newLen)
|
result.reserved = max(resize(result.space), newLen)
|
||||||
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
result = cast[PGenericSeq](growObj(result, elemSize * result.reserved +
|
||||||
result.len = newLen
|
|
||||||
else:
|
|
||||||
result = seq
|
|
||||||
if result.space < newLen:
|
|
||||||
result.space = max(resize(result.space), newLen)
|
|
||||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
|
||||||
GenericSeqSize))
|
GenericSeqSize))
|
||||||
elif newLen < result.len:
|
elif newLen < result.len:
|
||||||
# we need to decref here, otherwise the GC leaks!
|
# we need to decref here, otherwise the GC leaks!
|
||||||
|
|
|
||||||
18
web/news.txt
18
web/news.txt
|
|
@ -2,10 +2,26 @@
|
||||||
News
|
News
|
||||||
====
|
====
|
||||||
|
|
||||||
|
2012-XX-XX Version 0.8.XX released
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Version 0.8.XX has been released! Get it `here <download.html>`_.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
|
||||||
|
Library Additions
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- Added ``system.shallow`` that can be used to speed up string and sequence
|
||||||
|
assignments.
|
||||||
|
|
||||||
|
|
||||||
2012-02-09 Version 0.8.14 released
|
2012-02-09 Version 0.8.14 released
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
Version 0.8.14 has been released! Get it `here <download.html>`_.
|
Version 0.8.14 has been released!
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
--------
|
--------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue