mirror of
https://github.com/nim-lang/Nim.git
synced 2026-09-02 03:43:41 +00:00
fixes #26152 PR #26086 introduced {base, off, len} view wrappers for var openArray arguments to preserve write-through semantics. This caused imported JS pattern calls such as #.sort(#) to emit invalid object-literal syntax instead of invoking the underlying array method. Skip the view wrapper when generating arguments for imported pattern calls, while retaining it for regular Nim procedures.
This commit is contained in:
@@ -1787,9 +1787,11 @@ proc genVarOpenArrayArg(p: PProc, n: PNode, r: var TCompRes) =
|
||||
r.res = "{base: $1, off: 0, len: ($1).length}" % [v.rdLoc]
|
||||
r.kind = resExpr
|
||||
|
||||
proc genArg(p: PProc, n: PNode, param: PSym, r: var TCompRes; emitted: ptr int = nil) =
|
||||
proc genArg(p: PProc, n: PNode, param: PSym, r: var TCompRes;
|
||||
emitted: ptr int = nil; skipVarOpenArray = false) =
|
||||
var a: TCompRes = default(TCompRes)
|
||||
if param.typ != nil and param.typ.kind == tyVar and param.typ[0].kind == tyOpenArray:
|
||||
if (not skipVarOpenArray) and param.typ != nil and param.typ.kind == tyVar and
|
||||
param.typ[0].kind == tyOpenArray:
|
||||
# `var openArray` params are passed as a `{base, off, len}` slice view.
|
||||
genVarOpenArrayArg(p, n, a)
|
||||
r.res.add(a.rdLoc)
|
||||
@@ -1847,7 +1849,8 @@ proc genArgs(p: PProc, n: PNode, r: var TCompRes; start=1) =
|
||||
r.kind = resExpr
|
||||
|
||||
proc genOtherArg(p: PProc; n: PNode; i: int; typ: PType;
|
||||
generated: var int; r: var TCompRes) =
|
||||
generated: var int; r: var TCompRes;
|
||||
skipVarOpenArray = false) =
|
||||
if i >= n.len:
|
||||
globalError(p.config, n.info, "wrong importcpp pattern; expected parameter at position " & $i &
|
||||
" but got only: " & $(n.len-1))
|
||||
@@ -1860,11 +1863,12 @@ proc genOtherArg(p: PProc; n: PNode; i: int; typ: PType;
|
||||
if paramType.isNil:
|
||||
genArgNoParam(p, it, r)
|
||||
else:
|
||||
genArg(p, it, paramType.sym, r)
|
||||
genArg(p, it, paramType.sym, r, skipVarOpenArray = skipVarOpenArray)
|
||||
inc generated
|
||||
|
||||
proc genPatternCall(p: PProc; n: PNode; pat: string; typ: PType;
|
||||
r: var TCompRes) =
|
||||
let skipVarOpenArray = sfImportc in n[0].sym.flags
|
||||
var i = 0
|
||||
var j = 1
|
||||
r.kind = resExpr
|
||||
@@ -1874,11 +1878,11 @@ proc genPatternCall(p: PProc; n: PNode; pat: string; typ: PType;
|
||||
var generated = 0
|
||||
for k in j..<n.len:
|
||||
if generated > 0: r.res.add(", ")
|
||||
genOtherArg(p, n, k, typ, generated, r)
|
||||
genOtherArg(p, n, k, typ, generated, r, skipVarOpenArray)
|
||||
inc i
|
||||
of '#':
|
||||
var generated = 0
|
||||
genOtherArg(p, n, j, typ, generated, r)
|
||||
genOtherArg(p, n, j, typ, generated, r, skipVarOpenArray)
|
||||
inc j
|
||||
inc i
|
||||
of '\31':
|
||||
|
||||
@@ -49,6 +49,13 @@ proc bar(s: var seq[int], a: int) =
|
||||
s.bar(5)
|
||||
doAssert(s == @[123, 1])
|
||||
|
||||
# Imported JavaScript patterns must receive the underlying array, not the
|
||||
# `{base, off, len}` view used for regular `var openArray` parameters.
|
||||
proc jsSort[T](x: var openArray[T], cmp: proc(a, b: T): int) {.importcpp: "#.sort(#)", nodecl.}
|
||||
var sorted = @[2, 1]
|
||||
sorted.jsSort(proc(a, b: int): int = a - b)
|
||||
doAssert(sorted == @[1, 2])
|
||||
|
||||
import tables
|
||||
block: # Test get addr of byvar return value
|
||||
var t = initTable[string, int]()
|
||||
|
||||
Reference in New Issue
Block a user