From 8f9ea358b693084ae09921d04084843779f8ee93 Mon Sep 17 00:00:00 2001 From: flywind <43030857+xflywind@users.noreply.github.com> Date: Wed, 10 Feb 2021 11:49:44 -0600 Subject: [PATCH] [JS] Ref #15952 make toOpenArray works better (#17001) * ref 15952 toOpenArray works in JS * fix (cherry picked from commit 9bd4f503f4afcdcb8a42475c2f9c97a20830fae1) --- compiler/jsgen.nim | 29 +++++++++++++++++++---------- tests/openarray/topenarray.nim | 13 +++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 tests/openarray/topenarray.nim diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index be59404efa54c..e6f27a3527d1f 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -14,27 +14,28 @@ The JS code generator contains only 2 tricks: Trick 1 ------- -Some locations (for example 'var int') require "fat pointers" (``etyBaseIndex``) +Some locations (for example 'var int') require "fat pointers" (`etyBaseIndex`) which are pairs (array, index). The derefence operation is then 'array[index]'. -Check ``mapType`` for the details. +Check `mapType` for the details. Trick 2 ------- It is preferable to generate '||' and '&&' if possible since that is more idiomatic and hence should be friendlier for the JS JIT implementation. However -code like ``foo and (let bar = baz())`` cannot be translated this way. Instead -the expressions need to be transformed into statements. ``isSimpleExpr`` +code like `foo and (let bar = baz())` cannot be translated this way. Instead +the expressions need to be transformed into statements. `isSimpleExpr` implements the required case distinction. """ import - ast, strutils, trees, magicsys, options, - nversion, msgs, idents, types, tables, - ropes, math, passes, ccgutils, wordrecg, renderer, - intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, - transf, injectdestructors, sourcemap, json, sets + ast, trees, magicsys, options, + nversion, msgs, idents, types, + ropes, passes, ccgutils, wordrecg, renderer, + cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, + transf, injectdestructors, sourcemap +import std/[json, sets, math, tables, intsets, strutils] from modulegraphs import ModuleGraph, PPassContext @@ -1345,7 +1346,15 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) = of nkStmtListExpr: if n.len == 1: gen(p, n[0], r) else: internalError(p.config, n[0].info, "genAddr for complex nkStmtListExpr") - else: internalError(p.config, n[0].info, "genAddr: " & $n[0].kind) + of nkCallKinds: + if n[0].typ.kind == tyOpenArray: + # 'var openArray' for instance produces an 'addr' but this is harmless: + # namely toOpenArray(a, 1, 3) + gen(p, n[0], r) + else: + internalError(p.config, n[0].info, "genAddr: " & $n[0].kind) + else: + internalError(p.config, n[0].info, "genAddr: " & $n[0].kind) proc attachProc(p: PProc; content: Rope; s: PSym) = p.g.code.add(content) diff --git a/tests/openarray/topenarray.nim b/tests/openarray/topenarray.nim new file mode 100644 index 0000000000000..0f74e0ea5e1a6 --- /dev/null +++ b/tests/openarray/topenarray.nim @@ -0,0 +1,13 @@ +discard """ + targets: "c cpp js" +""" + +proc pro[T](a: var openArray[T]) = discard + +proc main = + var a = [1,2,3,4,5] + + pro(toOpenArray(a, 1, 3)) + pro(a.toOpenArray(1,3)) + +main()