mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 21:43:33 +00:00
Merge pull request #3451 from yglukhov/js-ret-by-var
JS: Fixed return by var. More fixes to copying.
This commit is contained in:
@@ -231,7 +231,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
|
||||
curr.typ.sons[col], false))
|
||||
var ret: PNode
|
||||
if base.typ.sons[0] != nil:
|
||||
var a = newNodeI(nkAsgn, base.info)
|
||||
var a = newNodeI(nkFastAsgn, base.info)
|
||||
addSon(a, newSymNode(base.ast.sons[resultPos].sym))
|
||||
addSon(a, call)
|
||||
ret = newNodeI(nkReturnStmt, base.info)
|
||||
@@ -256,4 +256,3 @@ proc generateMethodDispatchers*(): PNode =
|
||||
sortBucket(gMethods[bucket].methods, relevantCols)
|
||||
addSon(result,
|
||||
newSymNode(genDispatcher(gMethods[bucket].methods, relevantCols)))
|
||||
|
||||
|
||||
@@ -197,10 +197,10 @@ proc isSimpleExpr(n: PNode): bool =
|
||||
elif n.isAtom:
|
||||
result = true
|
||||
|
||||
proc getTemp(p: PProc): Rope =
|
||||
proc getTemp(p: PProc, defineInLocals: bool = true): Rope =
|
||||
inc(p.unique)
|
||||
result = "Tmp$1" % [rope(p.unique)]
|
||||
addf(p.locals, "var $1;$n" | "local $1;$n", [result])
|
||||
if defineInLocals: addf(p.locals, "var $1;$n" | "local $1;$n", [result])
|
||||
|
||||
proc genAnd(p: PProc, a, b: PNode, r: var TCompRes) =
|
||||
assert r.kind == resNone
|
||||
@@ -790,19 +790,36 @@ proc needsNoCopy(y: PNode): bool =
|
||||
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||
var a, b: TCompRes
|
||||
gen(p, x, a)
|
||||
|
||||
let xtyp = mapType(x.typ)
|
||||
|
||||
if x.kind == nkHiddenDeref and x.sons[0].kind == nkCall and xtyp != etyObject:
|
||||
gen(p, x.sons[0], a)
|
||||
let tmp = p.getTemp(false)
|
||||
addf(p.body, "var $1 = $2;$n", [tmp, a.rdLoc])
|
||||
a.res = "$1[0][$1[1]]" % [tmp]
|
||||
else:
|
||||
gen(p, x, a)
|
||||
|
||||
gen(p, y, b)
|
||||
case mapType(x.typ)
|
||||
|
||||
case xtyp
|
||||
of etyObject:
|
||||
if needsNoCopy(y) or noCopyNeeded:
|
||||
if (needsNoCopy(y) and needsNoCopy(x)) or noCopyNeeded:
|
||||
addf(p.body, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||
else:
|
||||
useMagic(p, "nimCopy")
|
||||
addf(p.body, "$1 = nimCopy($1, $2, $3);$n",
|
||||
addf(p.body, "nimCopy($1, $2, $3);$n",
|
||||
[a.res, b.res, genTypeInfo(p, y.typ)])
|
||||
of etyBaseIndex:
|
||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||
internalError(x.info, "genAsgn")
|
||||
addf(p.body, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||
if y.kind == nkCall:
|
||||
let tmp = p.getTemp(false)
|
||||
addf(p.body, "var $1 = $4; $2 = $1[0]; $3 = $1[1];$n", [tmp, a.address, a.res, b.rdLoc])
|
||||
else:
|
||||
internalError(x.info, "genAsgn")
|
||||
else:
|
||||
addf(p.body, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||
else:
|
||||
addf(p.body, "$1 = $2;$n", [a.res, b.res])
|
||||
|
||||
@@ -818,11 +835,9 @@ proc genSwap(p: PProc, n: PNode) =
|
||||
var a, b: TCompRes
|
||||
gen(p, n.sons[1], a)
|
||||
gen(p, n.sons[2], b)
|
||||
inc(p.unique)
|
||||
var tmp = "Tmp$1" % [rope(p.unique)]
|
||||
var tmp = p.getTemp(false)
|
||||
if mapType(skipTypes(n.sons[1].typ, abstractVar)) == etyBaseIndex:
|
||||
inc(p.unique)
|
||||
let tmp2 = "Tmp$1" % [rope(p.unique)]
|
||||
let tmp2 = p.getTemp(false)
|
||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||
internalError(n.info, "genSwap")
|
||||
addf(p.body, "var $1 = $2; $2 = $3; $3 = $1;$n" |
|
||||
@@ -1029,8 +1044,13 @@ proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
|
||||
else:
|
||||
var a: TCompRes
|
||||
gen(p, n.sons[0], a)
|
||||
if a.typ != etyBaseIndex: internalError(n.info, "genDeref")
|
||||
r.res = "$1[$2]" % [a.address, a.res]
|
||||
if a.typ == etyBaseIndex:
|
||||
r.res = "$1[$2]" % [a.address, a.res]
|
||||
elif n.sons[0].kind == nkCall:
|
||||
let tmp = p.getTemp
|
||||
r.res = "($1 = $2, $1[0][$1[1]])" % [tmp, a.res]
|
||||
else:
|
||||
internalError(n.info, "genDeref")
|
||||
|
||||
proc genArgNoParam(p: PProc, n: PNode, r: var TCompRes) =
|
||||
var a: TCompRes
|
||||
@@ -1584,7 +1604,10 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||
mangleName(resultSym),
|
||||
createVar(p, resultSym.typ, isIndirect(resultSym))]
|
||||
gen(p, prc.ast.sons[resultPos], a)
|
||||
returnStmt = "return $#;$n" % [a.res]
|
||||
if mapType(resultSym.typ) == etyBaseIndex:
|
||||
returnStmt = "return [$#, $#];$n" % [a.address, a.res]
|
||||
else:
|
||||
returnStmt = "return $#;$n" % [a.res]
|
||||
genStmt(p, prc.getBody)
|
||||
result = ("function $#($#) {$n$#$#$#$#}$n" |
|
||||
"function $#($#) $n$#$#$#$#$nend$n") %
|
||||
|
||||
@@ -121,7 +121,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
|
||||
case t.kind
|
||||
of tyDistinct:
|
||||
result = genTypeInfo(p, typ.sons[0])
|
||||
result = genTypeInfo(p, t.sons[0])
|
||||
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64:
|
||||
var s =
|
||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
|
||||
@@ -133,7 +133,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
|
||||
[result, rope(ord(t.kind))]
|
||||
prepend(p.g.typeInfo, s)
|
||||
addf(p.g.typeInfo, "$1.base = $2;$n",
|
||||
[result, genTypeInfo(p, typ.lastSon)])
|
||||
[result, genTypeInfo(p, t.lastSon)])
|
||||
of tyArrayConstr, tyArray:
|
||||
var s =
|
||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
|
||||
|
||||
@@ -1411,7 +1411,8 @@ proc insert*[T](x: var seq[T], item: T, i = 0.Natural) {.noSideEffect.} =
|
||||
defaultImpl()
|
||||
else:
|
||||
when defined(js):
|
||||
{.emit: "`x`[`x`_Idx].splice(`i`, 0, null);".}
|
||||
var it : T
|
||||
{.emit: "`x`[`x`_Idx].splice(`i`, 0, `it`);".}
|
||||
else:
|
||||
defaultImpl()
|
||||
x[i] = item
|
||||
|
||||
@@ -532,7 +532,7 @@ proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b
|
||||
type NimString = string # hack for hti.nim
|
||||
include "system/hti"
|
||||
|
||||
type JSRef = int # Fake type.
|
||||
type JSRef = ref RootObj # Fake type.
|
||||
|
||||
proc isFatPointer(ti: PNimType): bool =
|
||||
# This has to be consistent with the code generator!
|
||||
@@ -569,8 +569,14 @@ proc nimCopy(dest, src: JSRef, ti: PNimType): JSRef =
|
||||
asm "`result` = [`src`[0], `src`[1]];"
|
||||
of tySet:
|
||||
asm """
|
||||
`result` = {};
|
||||
for (var key in `src`) { `result`[key] = `src`[key]; }
|
||||
if (`dest` === null || `dest` === undefined) {
|
||||
`dest` = {};
|
||||
}
|
||||
else {
|
||||
for (var key in `dest`) { delete `dest`[key]; }
|
||||
}
|
||||
for (var key in `src`) { `dest`[key] = `src`[key]; }
|
||||
`result` = `dest`;
|
||||
"""
|
||||
of tyTuple, tyObject:
|
||||
if ti.base != nil: result = nimCopy(dest, src, ti.base)
|
||||
|
||||
@@ -216,7 +216,9 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
|
||||
"exception/texcsub", "exception/tfinally",
|
||||
"exception/tfinally2", "exception/tfinally3",
|
||||
"actiontable/tactiontable", "method/tmultim1",
|
||||
"method/tmultim3", "method/tmultim4"]:
|
||||
"method/tmultim3", "method/tmultim4",
|
||||
"varres/tvarres0", "varres/tvarres3", "varres/tvarres4",
|
||||
"varres/tvartup"]:
|
||||
test "tests/" & testfile & ".nim"
|
||||
|
||||
# ------------------------- manyloc -------------------------------------------
|
||||
|
||||
30
tests/varres/tvarres0.nim
Normal file
30
tests/varres/tvarres0.nim
Normal file
@@ -0,0 +1,30 @@
|
||||
discard """
|
||||
output: '''123
|
||||
1234
|
||||
123
|
||||
1234
|
||||
12345
|
||||
'''
|
||||
"""
|
||||
|
||||
# Test simple type
|
||||
var a = 123
|
||||
proc getA(): var int = a
|
||||
|
||||
echo getA()
|
||||
|
||||
getA() = 1234
|
||||
echo getA()
|
||||
|
||||
|
||||
# Test object type
|
||||
type Foo = object
|
||||
a: int
|
||||
var f: Foo
|
||||
f.a = 123
|
||||
proc getF(): var Foo = f
|
||||
echo getF().a
|
||||
getF().a = 1234
|
||||
echo getF().a
|
||||
getF() = Foo(a: 12345)
|
||||
echo getF().a
|
||||
@@ -8,10 +8,6 @@ proc divmod(a, b: int): tuple[di, mo: int] =
|
||||
return (a div b, a mod b)
|
||||
|
||||
var (x, y) = divmod(15, 6)
|
||||
stdout.write(x)
|
||||
stdout.write(" ")
|
||||
stdout.write(y)
|
||||
echo x, " ", y
|
||||
|
||||
#OUT 2 3
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user