summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYuriy Glukhov <yuriy.glukhov@gmail.com>2015-10-15 15:00:30 +0300
committerYuriy Glukhov <yuriy.glukhov@gmail.com>2015-10-15 16:04:53 +0300
commit2166b7bc46419a78b9e22062959e7272dfb89692 (patch)
treed7e549a43d8b1f8a30fb5df429f213858c4fb07e
parentc97cbe7abd85d134e95ad1a7044fc314c60e5bed (diff)
downloadNim-2166b7bc46419a78b9e22062959e7272dfb89692.tar.gz
Fixed ret by var in js
-rw-r--r--compiler/cgmeth.nim3
-rw-r--r--compiler/jsgen.nim38
-rw-r--r--compiler/jstypes.nim4
-rw-r--r--lib/system.nim3
-rw-r--r--lib/system/jssys.nim12
-rw-r--r--tests/testament/categories.nim4
-rw-r--r--tests/varres/tvarres0.nim30
-rw-r--r--tests/varres/tvartup.nim6
8 files changed, 78 insertions, 22 deletions
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim
index d2358b84a..9642e9122 100644
--- a/compiler/cgmeth.nim
+++ b/compiler/cgmeth.nim
@@ -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)))
-
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 36caf5e3e..06b06e35f 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -790,19 +790,34 @@ 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)
+    addf(p.body, "nimVarUnpack = $1;$n", [a.rdLoc])
+    a.res = rope "nimVarUnpack[0][nimVarUnpack[1]]"
+  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:
+        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:
     addf(p.body, "$1 = $2;$n", [a.res, b.res])
 
@@ -1029,8 +1044,12 @@ 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:
+      r.res = "(nimVarUnpack = $#, nimVarUnpack[0][nimVarUnpack[1]])" % [a.res]
+    else:
+      internalError(n.info, "genDeref")
 
 proc genArgNoParam(p: PProc, n: PNode, r: var TCompRes) =
   var a: TCompRes
@@ -1584,7 +1603,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") %
diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim
index 832d9996c..367c173ea 100644
--- a/compiler/jstypes.nim
+++ b/compiler/jstypes.nim
@@ -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" %
diff --git a/lib/system.nim b/lib/system.nim
index 89de08c6f..02544be27 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -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 = item
+      {.emit: "`x`[`x`_Idx].splice(`i`, 0, `it`);".}
     else:
       defaultImpl()
   x[i] = item
diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim
index eb6080d38..5bcddc5e6 100644
--- a/lib/system/jssys.nim
+++ b/lib/system/jssys.nim
@@ -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)
diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim
index 3bb18d8a2..e700ff185 100644
--- a/tests/testament/categories.nim
+++ b/tests/testament/categories.nim
@@ -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 -------------------------------------------
diff --git a/tests/varres/tvarres0.nim b/tests/varres/tvarres0.nim
new file mode 100644
index 000000000..fd10a73bd
--- /dev/null
+++ b/tests/varres/tvarres0.nim
@@ -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
diff --git a/tests/varres/tvartup.nim b/tests/varres/tvartup.nim
index 20a4156e6..1957a3e35 100644
--- a/tests/varres/tvartup.nim
+++ b/tests/varres/tvartup.nim
@@ -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
-
-