array literals uses typed arrays; fix a jsgen bug (#16850)

* array litterals uses typed arrays
* Update compiler/jsgen.nim

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
flywind 2021-02-15 04:28:11 -06:00 • committed by GitHub
commit 240879bf3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 31 deletions

View file

@ -1991,6 +1991,23 @@ proc genMove(p: PProc; n: PNode; r: var TCompRes) =
genReset(p, n)
#lineF(p, "$1 = $2;$n", [dest.rdLoc, src.rdLoc])
proc genJSArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes
r.res = rope("[")
r.kind = resExpr
for i in 0 ..< n.len:
if i > 0: r.res.add(", ")
gen(p, n[i], a)
if a.typ == etyBaseIndex:
r.res.addf("[$1, $2]", [a.address, a.res])
else:
if not needsNoCopy(p, n[i]):
let typ = n[i].typ.skipTypes(abstractInst)
useMagic(p, "nimCopy")
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
r.res.add(a.res)
r.res.add("]")
proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
var
a: TCompRes
@ -2054,8 +2071,9 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mNew, mNewFinalize: genNew(p, n)
of mChr: gen(p, n[1], r)
of mArrToSeq:
if needsNoCopy(p, n[1]):
gen(p, n[1], r)
# only array literals doesn't need copy
if n[1].kind == nkBracket:
genJSArrayConstr(p, n[1], r)
else:
var x: TCompRes
gen(p, n[1], x)
@ -2172,21 +2190,26 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
r.res = tmp
proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes
r.res = rope("[")
r.kind = resExpr
for i in 0..<n.len:
if i > 0: r.res.add(", ")
gen(p, n[i], a)
if a.typ == etyBaseIndex:
r.res.addf("[$1, $2]", [a.address, a.res])
else:
if not needsNoCopy(p, n[i]):
let typ = n[i].typ.skipTypes(abstractInst)
useMagic(p, "nimCopy")
a.res = "nimCopy(null, $1, $2)" % [a.rdLoc, genTypeInfo(p, typ)]
## Constructs array or sequence.
## Nim array of uint8..uint32, int8..int32 maps to JS typed arrays.
## Nim sequence maps to JS array.
var t = skipTypes(n.typ, abstractInst)
let e = elemType(t)
let jsTyp = arrayTypeForElemType(e)
if skipTypes(n.typ, abstractVarRange).kind != tySequence and jsTyp.len > 0:
# generate typed array
# for example Nim generates `new Uint8Array([1, 2, 3])` for `[byte(1), 2, 3]`
# TODO use `set` or loop to initialize typed array which improves performances in some situations
var a: TCompRes
r.res = "new $1([" % [rope(jsTyp)]
r.kind = resExpr
for i in 0 ..< n.len:
if i > 0: r.res.add(", ")
gen(p, n[i], a)
r.res.add(a.res)
r.res.add("]")
r.res.add("])")
else:
genJSArrayConstr(p, n, r)
proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes