diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-09-24 02:17:14 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-09-24 02:27:12 +0200 |
commit | 66bbf7518e652bfe963f0891a55f45c4711d8be3 (patch) | |
tree | 409527338b7e0ca16e3e4f080fa7e9eaaa9ad676 /lib/system/channels.nim | |
parent | bc53d2c9ded45e790a8424660ff6152b3876fdab (diff) | |
download | Nim-66bbf7518e652bfe963f0891a55f45c4711d8be3.tar.gz |
fixes #4776
Diffstat (limited to 'lib/system/channels.nim')
-rw-r--r-- | lib/system/channels.nim | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/lib/system/channels.nim b/lib/system/channels.nim index caa709229..4d8bc581d 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -52,6 +52,7 @@ proc deinitRawChannel(p: pointer) = proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: LoadStoreMode) {.benign.} + proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, mode: LoadStoreMode) {.benign.} = var @@ -71,6 +72,9 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel, proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, mode: LoadStoreMode) = + template `+!`(p: pointer; x: int): pointer = + cast[pointer](cast[int](p) +% x) + var d = cast[ByteAddress](dest) s = cast[ByteAddress](src) @@ -93,7 +97,9 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, if s2 == nil: unsureAsgnRef(x, s2) else: - unsureAsgnRef(x, copyString(cast[NimString](s2))) + let y = copyDeepString(cast[NimString](s2)) + #echo "loaded ", cast[int](y), " ", cast[string](y) + unsureAsgnRef(x, y) dealloc(t.region, s2) of tySequence: var s2 = cast[PPointer](src)[] @@ -107,26 +113,27 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, else: sysAssert(dest != nil, "dest == nil") if mode == mStore: - x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize) + x[] = alloc0(t.region, seq.len *% mt.base.size +% GenericSeqSize) else: unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize)) var dst = cast[ByteAddress](cast[PPointer](dest)[]) + var dstseq = cast[PGenericSeq](dst) + dstseq.len = seq.len + dstseq.reserved = seq.len for i in 0..seq.len-1: storeAux( cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% GenericSeqSize), mt.base, t, mode) - var dstseq = cast[PGenericSeq](dst) - dstseq.len = seq.len - dstseq.reserved = seq.len if mode != mStore: dealloc(t.region, s2) of tyObject: - # copy type field: - var pint = cast[ptr PNimType](dest) - pint[] = cast[ptr PNimType](src)[] if mt.base != nil: storeAux(dest, src, mt.base, t, mode) + else: + # copy type field: + var pint = cast[ptr PNimType](dest) + pint[] = cast[ptr PNimType](src)[] storeAux(dest, src, mt.node, t, mode) of tyTuple: storeAux(dest, src, mt.node, t, mode) @@ -143,15 +150,24 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel, else: unsureAsgnRef(x, nil) else: - let size = if mt.base.kind == tyObject: cast[ptr PNimType](s)[].size - else: mt.base.size + #let size = if mt.base.kind == tyObject: cast[ptr PNimType](s)[].size + # else: mt.base.size if mode == mStore: - x[] = alloc(t.region, size) + let dyntype = when declared(usrToCell): usrToCell(s).typ + else: mt + let size = dyntype.base.size + # we store the real dynamic 'ref type' at offset 0, so that + # no information is lost + let a = alloc0(t.region, size+sizeof(pointer)) + x[] = a + cast[PPointer](a)[] = dyntype + storeAux(a +! sizeof(pointer), s, dyntype.base, t, mode) else: - var obj = newObj(mt, size) + let dyntype = cast[ptr PNimType](s)[] + var obj = newObj(dyntype, dyntype.base.size) unsureAsgnRef(x, obj) - storeAux(x[], s, mt.base, t, mode) - if mode != mStore: dealloc(t.region, s) + storeAux(x[], s +! sizeof(pointer), dyntype.base, t, mode) + dealloc(t.region, s) else: copyMem(dest, src, mt.size) # copy raw bits @@ -194,10 +210,8 @@ template sendImpl(q: expr) {.immediate.} = if q.mask == ChannelDeadMask: sysFatal(DeadThreadError, "cannot send message; thread died") acquireSys(q.lock) - var m: TMsg - shallowCopy(m, msg) var typ = cast[PNimType](getTypeInfo(msg)) - rawSend(q, addr(m), typ) + rawSend(q, unsafeAddr(msg), typ) q.elemType = typ releaseSys(q.lock) signalSysCond(q.cond) |