fixes #26152; JS regression: dockhack.js is invalid (#26156)

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:
ringabout
2026-09-01 16:26:00 +08:00
committed by GitHub
parent dcec8e1cd1
commit 859b0ba270
2 changed files with 17 additions and 6 deletions

View File

@@ -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':

View File

@@ -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]()