Fixed ret by var in js

This commit is contained in:
Yuriy Glukhov 2015-10-15 15:00:30 +03:00
commit 2166b7bc46
8 changed files with 78 additions and 22 deletions

View file

@ -231,7 +231,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
curr.typ.sons[col], false)) curr.typ.sons[col], false))
var ret: PNode var ret: PNode
if base.typ.sons[0] != nil: 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, newSymNode(base.ast.sons[resultPos].sym))
addSon(a, call) addSon(a, call)
ret = newNodeI(nkReturnStmt, base.info) ret = newNodeI(nkReturnStmt, base.info)
@ -256,4 +256,3 @@ proc generateMethodDispatchers*(): PNode =
sortBucket(gMethods[bucket].methods, relevantCols) sortBucket(gMethods[bucket].methods, relevantCols)
addSon(result, addSon(result,
newSymNode(genDispatcher(gMethods[bucket].methods, relevantCols))) newSymNode(genDispatcher(gMethods[bucket].methods, relevantCols)))

View file

@ -790,19 +790,34 @@ proc needsNoCopy(y: PNode): bool =
proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) = proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
var a, b: TCompRes var a, b: TCompRes
gen(p, x, a) 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)
addf(p.body, "nimVarUnpack = $1;$n", [a.rdLoc])
a.res = rope "nimVarUnpack[0][nimVarUnpack[1]]"
else:
gen(p, x, a)
gen(p, y, b) gen(p, y, b)
case mapType(x.typ)
case xtyp
of etyObject: 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]) addf(p.body, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
else: else:
useMagic(p, "nimCopy") 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)]) [a.res, b.res, genTypeInfo(p, y.typ)])
of etyBaseIndex: of etyBaseIndex:
if a.typ != etyBaseIndex or b.typ != etyBaseIndex: if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
internalError(x.info, "genAsgn") if y.kind == nkCall:
addf(p.body, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res]) addf(p.body, "nimVarUnpack = $3; $1 = nimVarUnpack[0]; $2 = nimVarUnpack[1];$n", [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: else:
addf(p.body, "$1 = $2;$n", [a.res, b.res]) addf(p.body, "$1 = $2;$n", [a.res, b.res])
@ -1029,8 +1044,12 @@ proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
else: else:
var a: TCompRes var a: TCompRes
gen(p, n.sons[0], a) gen(p, n.sons[0], a)
if a.typ != etyBaseIndex: internalError(n.info, "genDeref") if a.typ == etyBaseIndex:
r.res = "$1[$2]" % [a.address, a.res] r.res = "$1[$2]" % [a.address, a.res]
elif n.sons[0].kind == nkCall:
r.res = "(nimVarUnpack = $#, nimVarUnpack[0][nimVarUnpack[1]])" % [a.res]
else:
internalError(n.info, "genDeref")
proc genArgNoParam(p: PProc, n: PNode, r: var TCompRes) = proc genArgNoParam(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes var a: TCompRes
@ -1584,7 +1603,10 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
mangleName(resultSym), mangleName(resultSym),
createVar(p, resultSym.typ, isIndirect(resultSym))] createVar(p, resultSym.typ, isIndirect(resultSym))]
gen(p, prc.ast.sons[resultPos], a) 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) genStmt(p, prc.getBody)
result = ("function $#($#) {$n$#$#$#$#}$n" | result = ("function $#($#) {$n$#$#$#$#}$n" |
"function $#($#) $n$#$#$#$#$nend$n") % "function $#($#) $n$#$#$#$#$nend$n") %

View file

@ -121,7 +121,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
if containsOrIncl(p.g.typeInfoGenerated, t.id): return if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind case t.kind
of tyDistinct: of tyDistinct:
result = genTypeInfo(p, typ.sons[0]) result = genTypeInfo(p, t.sons[0])
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64: of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64:
var s = var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" % "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))] [result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s) prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n", addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, typ.lastSon)]) [result, genTypeInfo(p, t.lastSon)])
of tyArrayConstr, tyArray: of tyArrayConstr, tyArray:
var s = var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" % "var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %

View file

@ -1411,7 +1411,8 @@ proc insert*[T](x: var seq[T], item: T, i = 0.Natural) {.noSideEffect.} =
defaultImpl() defaultImpl()
else: else:
when defined(js): when defined(js):
{.emit: "`x`[`x`_Idx].splice(`i`, 0, null);".} var it = item
{.emit: "`x`[`x`_Idx].splice(`i`, 0, `it`);".}
else: else:
defaultImpl() defaultImpl()
x[i] = item x[i] = item

View file

@ -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 type NimString = string # hack for hti.nim
include "system/hti" include "system/hti"
type JSRef = int # Fake type. type JSRef = ref RootObj # Fake type.
proc isFatPointer(ti: PNimType): bool = proc isFatPointer(ti: PNimType): bool =
# This has to be consistent with the code generator! # 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]];" asm "`result` = [`src`[0], `src`[1]];"
of tySet: of tySet:
asm """ asm """
`result` = {}; if (`dest` === null || `dest` === undefined) {
for (var key in `src`) { `result`[key] = `src`[key]; } `dest` = {};
}
else {
for (var key in `dest`) { delete `dest`[key]; }
}
for (var key in `src`) { `dest`[key] = `src`[key]; }
`result` = `dest`;
""" """
of tyTuple, tyObject: of tyTuple, tyObject:
if ti.base != nil: result = nimCopy(dest, src, ti.base) if ti.base != nil: result = nimCopy(dest, src, ti.base)

View file

@ -216,7 +216,9 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
"exception/texcsub", "exception/tfinally", "exception/texcsub", "exception/tfinally",
"exception/tfinally2", "exception/tfinally3", "exception/tfinally2", "exception/tfinally3",
"actiontable/tactiontable", "method/tmultim1", "actiontable/tactiontable", "method/tmultim1",
"method/tmultim3", "method/tmultim4"]: "method/tmultim3", "method/tmultim4",
"varres/tvarres0", "varres/tvarres3", "varres/tvarres4",
"varres/tvartup"]:
test "tests/" & testfile & ".nim" test "tests/" & testfile & ".nim"
# ------------------------- manyloc ------------------------------------------- # ------------------------- manyloc -------------------------------------------

30
tests/varres/tvarres0.nim Normal file
View 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

View file

@ -8,10 +8,6 @@ proc divmod(a, b: int): tuple[di, mo: int] =
return (a div b, a mod b) return (a div b, a mod b)
var (x, y) = divmod(15, 6) var (x, y) = divmod(15, 6)
stdout.write(x) echo x, " ", y
stdout.write(" ")
stdout.write(y)
#OUT 2 3 #OUT 2 3