Fixed copying of aggregates in JS.
This commit is contained in:
parent
a041ef68a1
commit
6436d1920c
3 changed files with 45 additions and 24 deletions
|
|
@ -817,7 +817,7 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
addf(p.body, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
addf(p.body, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||||
else:
|
else:
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
addf(p.body, "$1 = nimCopy($2, $3);$n",
|
addf(p.body, "$1 = nimCopy($1, $2, $3);$n",
|
||||||
[a.res, b.res, genTypeInfo(p, y.typ)])
|
[a.res, b.res, genTypeInfo(p, y.typ)])
|
||||||
of etyBaseIndex:
|
of etyBaseIndex:
|
||||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||||
|
|
@ -1206,7 +1206,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||||
s = a.res
|
s = a.res
|
||||||
else:
|
else:
|
||||||
useMagic(p, "nimCopy")
|
useMagic(p, "nimCopy")
|
||||||
s = "nimCopy($1, $2)" % [a.res, genTypeInfo(p, n.typ)]
|
s = "nimCopy(null, $1, $2)" % [a.res, genTypeInfo(p, n.typ)]
|
||||||
of etyBaseIndex:
|
of etyBaseIndex:
|
||||||
if (a.typ != etyBaseIndex): internalError(n.info, "genVarInit")
|
if (a.typ != etyBaseIndex): internalError(n.info, "genVarInit")
|
||||||
if {sfAddrTaken, sfGlobal} * v.flags != {}:
|
if {sfAddrTaken, sfGlobal} * v.flags != {}:
|
||||||
|
|
|
||||||
|
|
@ -517,62 +517,70 @@ proc isFatPointer(ti: PNimType): bool =
|
||||||
tyArray, tyArrayConstr, tyTuple,
|
tyArray, tyArrayConstr, tyTuple,
|
||||||
tyOpenArray, tySet, tyVar, tyRef, tyPtr}
|
tyOpenArray, tySet, tyVar, tyRef, tyPtr}
|
||||||
|
|
||||||
proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
|
proc nimCopy(dest, src: pointer, ti: PNimType): pointer {.compilerproc.}
|
||||||
|
|
||||||
proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} =
|
proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone: sysAssert(false, "nimCopyAux")
|
of nkNone: sysAssert(false, "nimCopyAux")
|
||||||
of nkSlot:
|
of nkSlot:
|
||||||
asm "`dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ);"
|
asm """
|
||||||
|
var ddest = `dest`[`n`.offset];
|
||||||
|
if (ddest === undefined) ddest = null;
|
||||||
|
`dest`[`n`.offset] = nimCopy(ddest, `src`[`n`.offset], `n`.typ);
|
||||||
|
"""
|
||||||
of nkList:
|
of nkList:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
nimCopyAux(dest, src, n.sons[i])
|
nimCopyAux(dest, src, n.sons[i])
|
||||||
of nkCase:
|
of nkCase:
|
||||||
asm """
|
asm """
|
||||||
`dest`[`n`.offset] = nimCopy(`src`[`n`.offset], `n`.typ);
|
var ddest = `dest`[`n`.offset];
|
||||||
|
if (ddest === undefined) ddest = null;
|
||||||
|
`dest`[`n`.offset] = nimCopy(ddest, `src`[`n`.offset], `n`.typ);
|
||||||
for (var i = 0; i < `n`.sons.length; ++i) {
|
for (var i = 0; i < `n`.sons.length; ++i) {
|
||||||
nimCopyAux(`dest`, `src`, `n`.sons[i][1]);
|
nimCopyAux(`dest`, `src`, `n`.sons[i][1]);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc nimCopy(x: pointer, ti: PNimType): pointer =
|
proc nimCopy(dest, src: pointer, ti: PNimType): pointer =
|
||||||
case ti.kind
|
case ti.kind
|
||||||
of tyPtr, tyRef, tyVar, tyNil:
|
of tyPtr, tyRef, tyVar, tyNil:
|
||||||
if not isFatPointer(ti):
|
if not isFatPointer(ti):
|
||||||
result = x
|
result = src
|
||||||
else:
|
else:
|
||||||
asm """
|
asm "`result` = [`src`[0], `src`[1]];"
|
||||||
`result` = [null, 0];
|
|
||||||
`result`[0] = `x`[0];
|
|
||||||
`result`[1] = `x`[1];
|
|
||||||
"""
|
|
||||||
of tySet:
|
of tySet:
|
||||||
asm """
|
asm """
|
||||||
`result` = {};
|
`result` = {};
|
||||||
for (var key in `x`) { `result`[key] = `x`[key]; }
|
for (var key in `src`) { `result`[key] = `src`[key]; }
|
||||||
"""
|
"""
|
||||||
of tyTuple, tyObject:
|
of tyTuple, tyObject:
|
||||||
if ti.base != nil: result = nimCopy(x, ti.base)
|
if ti.base != nil: result = nimCopy(dest, src, ti.base)
|
||||||
elif ti.kind == tyObject:
|
elif ti.kind == tyObject:
|
||||||
asm "`result` = {m_type: `ti`};"
|
asm "`result` = (`dest` === null) ? {m_type: `ti`} : `dest`;"
|
||||||
else:
|
else:
|
||||||
asm "`result` = {};"
|
asm "`result` = (`dest` === null) ? {} : `dest`;"
|
||||||
nimCopyAux(result, x, ti.node)
|
nimCopyAux(result, src, ti.node)
|
||||||
of tySequence, tyArrayConstr, tyOpenArray, tyArray:
|
of tySequence, tyArrayConstr, tyOpenArray, tyArray:
|
||||||
asm """
|
asm """
|
||||||
`result` = new Array(`x`.length);
|
if (`dest` === null) {
|
||||||
for (var i = 0; i < `x`.length; ++i) {
|
`dest` = new Array(`src`.length);
|
||||||
`result`[i] = nimCopy(`x`[i], `ti`.base);
|
}
|
||||||
|
else {
|
||||||
|
`dest`.length = `src`.length;
|
||||||
|
}
|
||||||
|
`result` = `dest`;
|
||||||
|
for (var i = 0; i < `src`.length; ++i) {
|
||||||
|
`result`[i] = nimCopy(`result`[i], `src`[i], `ti`.base);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
of tyString:
|
of tyString:
|
||||||
asm """
|
asm """
|
||||||
if (`x` !== null) {
|
if (`src` !== null) {
|
||||||
`result` = `x`.slice(0);
|
`result` = `src`.slice(0);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
result = x
|
result = src
|
||||||
|
|
||||||
proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} =
|
proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} =
|
||||||
case ti.kind
|
case ti.kind
|
||||||
|
|
@ -611,7 +619,7 @@ proc arrayConstr(len: int, value: pointer, typ: PNimType): pointer {.
|
||||||
# types are fake
|
# types are fake
|
||||||
asm """
|
asm """
|
||||||
var result = new Array(`len`);
|
var result = new Array(`len`);
|
||||||
for (var i = 0; i < `len`; ++i) result[i] = nimCopy(`value`, `typ`);
|
for (var i = 0; i < `len`; ++i) result[i] = nimCopy(null, `value`, `typ`);
|
||||||
return result;
|
return result;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
13
tests/js/tcopying.nim
Normal file
13
tests/js/tcopying.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
output: '''123
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
type MyArray = array[1, int]
|
||||||
|
|
||||||
|
proc changeArray(a: var MyArray) =
|
||||||
|
a = [123]
|
||||||
|
|
||||||
|
var a : MyArray
|
||||||
|
changeArray(a)
|
||||||
|
echo a[0]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue