This commit is contained in:
Araq 2015-04-19 02:43:19 +02:00
commit 5cea6807e1
5 changed files with 161 additions and 152 deletions

View file

@ -124,7 +124,7 @@ proc newProc(globals: PGlobals, module: BModule, procDef: PNode,
const const
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray,
tySet, tyVar, tyRef, tyPtr, tyBigNum, tyVarargs} tySet, tyBigNum, tyVarargs}
proc mapType(typ: PType): TJSTypeKind = proc mapType(typ: PType): TJSTypeKind =
let t = skipTypes(typ, abstractInst) let t = skipTypes(typ, abstractInst)
@ -163,7 +163,8 @@ proc mangleName(s: PSym): Rope =
add(result, rope(s.id)) add(result, rope(s.id))
s.loc.r = result s.loc.r = result
proc makeJSString(s: string): Rope = strutils.escape(s).rope proc makeJSString(s: string): Rope =
(if s.isNil: "null".rope else: strutils.escape(s).rope)
include jstypes include jstypes
@ -937,6 +938,12 @@ proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
r.address = nil r.address = nil
r.kind = resExpr r.kind = resExpr
proc isIndirect(v: PSym): bool =
result = {sfAddrTaken, sfGlobal} * v.flags != {} and
#(mapType(v.typ) != etyObject) and
sfVolatile notin v.flags and
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
proc genAddr(p: PProc, n: PNode, r: var TCompRes) = proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
case n.sons[0].kind case n.sons[0].kind
of nkSym: of nkSym:
@ -945,12 +952,16 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
case s.kind case s.kind
of skVar, skLet, skResult: of skVar, skLet, skResult:
r.kind = resExpr r.kind = resExpr
if mapType(n.sons[0].typ) == etyObject: let jsType = mapType(n.typ)
if jsType == etyObject:
# make addr() a no-op: # make addr() a no-op:
r.typ = etyNone r.typ = etyNone
r.res = s.loc.r if isIndirect(s):
r.res = s.loc.r & "[0]"
else:
r.res = s.loc.r
r.address = nil r.address = nil
elif {sfGlobal, sfAddrTaken} * s.flags != {}: elif {sfGlobal, sfAddrTaken} * s.flags != {} or jsType == etyBaseIndex:
# for ease of code generation, we do not distinguish between # for ease of code generation, we do not distinguish between
# sfAddrTaken and sfGlobal. # sfAddrTaken and sfGlobal.
r.typ = etyBaseIndex r.typ = etyBaseIndex
@ -992,7 +1003,7 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
else: else:
r.address = s.loc.r r.address = s.loc.r
r.res = s.loc.r & "_Idx" r.res = s.loc.r & "_Idx"
elif k != etyObject and {sfAddrTaken, sfGlobal} * s.flags != {}: elif isIndirect(s):
r.res = "$1[0]" % [s.loc.r] r.res = "$1[0]" % [s.loc.r]
else: else:
r.res = s.loc.r r.res = s.loc.r
@ -1124,7 +1135,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
of tyRange, tyGenericInst: of tyRange, tyGenericInst:
result = createVar(p, lastSon(typ), indirect) result = createVar(p, lastSon(typ), indirect)
of tySet: of tySet:
result = rope("{}") result = putToSeq("{}", indirect)
of tyBool: of tyBool:
result = putToSeq("false", indirect) result = putToSeq("false", indirect)
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
@ -1144,6 +1155,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
add(result, createVar(p, e, false)) add(result, createVar(p, e, false))
inc(i) inc(i)
add(result, "]") add(result, "]")
if indirect: result = "[$1]" % [result]
of tyTuple: of tyTuple:
result = rope("{") result = rope("{")
for i in 0.. <t.sonsLen: for i in 0.. <t.sonsLen:
@ -1151,6 +1163,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
addf(result, "Field$1: $2" | "Field$# = $#", [i.rope, addf(result, "Field$1: $2" | "Field$# = $#", [i.rope,
createVar(p, t.sons[i], false)]) createVar(p, t.sons[i], false)])
add(result, "}") add(result, "}")
if indirect: result = "[$1]" % [result]
of tyObject: of tyObject:
result = rope("{") result = rope("{")
var c = 0 var c = 0
@ -1161,6 +1174,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
add(result, createRecordVarAux(p, t.n, c)) add(result, createRecordVarAux(p, t.n, c))
t = t.sons[0] t = t.sons[0]
add(result, "}") add(result, "}")
if indirect: result = "[$1]" % [result]
of tyVar, tyPtr, tyRef: of tyVar, tyPtr, tyRef:
if mapType(t) == etyBaseIndex: if mapType(t) == etyBaseIndex:
result = putToSeq("[null, 0]" | "{nil, 0}", indirect) result = putToSeq("[null, 0]" | "{nil, 0}", indirect)
@ -1172,11 +1186,6 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
internalError("createVar: " & $t.kind) internalError("createVar: " & $t.kind)
result = nil result = nil
proc isIndirect(v: PSym): bool =
result = {sfAddrTaken, sfGlobal} * v.flags != {} and
(mapType(v.typ) != etyObject) and
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
proc genVarInit(p: PProc, v: PSym, n: PNode) = proc genVarInit(p: PProc, v: PSym, n: PNode) =
var var
a: TCompRes a: TCompRes
@ -1239,7 +1248,7 @@ proc genNew(p: PProc, n: PNode) =
var a: TCompRes var a: TCompRes
gen(p, n.sons[1], a) gen(p, n.sons[1], a)
var t = skipTypes(n.sons[1].typ, abstractVar).sons[0] var t = skipTypes(n.sons[1].typ, abstractVar).sons[0]
addf(p.body, "$1 = $2;$n", [a.res, createVar(p, t, true)]) addf(p.body, "$1 = $2;$n", [a.res, createVar(p, t, false)])
proc genNewSeq(p: PProc, n: PNode) = proc genNewSeq(p: PProc, n: PNode) =
var x, y: TCompRes var x, y: TCompRes

View file

@ -127,8 +127,8 @@ The signature has to be:
.. code-block:: nim .. code-block:: nim
proc `=deepCopy`(x: T): T proc `=deepCopy`(x: T): T
This mechanism is used by most data structures that support shared memory like This mechanism will be used by most data structures that support shared memory
channels to implement thread safe automatic memory management. like channels to implement thread safe automatic memory management.
The builtin ``deepCopy`` can even clone closures and their environments. See The builtin ``deepCopy`` can even clone closures and their environments. See
the documentation of `spawn`_ for details. the documentation of `spawn`_ for details.

View file

@ -35,9 +35,9 @@ echo ""
proc reraise_in_except = proc reraise_in_except =
try: try:
echo "BEFORE" echo "BEFORE"
raise newException(EIO, "") raise newException(IOError, "")
except EIO: except IOError:
echo "EXCEPT" echo "EXCEPT"
raise raise
@ -52,7 +52,7 @@ echo ""
proc return_in_except = proc return_in_except =
try: try:
echo "BEFORE" echo "BEFORE"
raise newException(EIO, "") raise newException(IOError, "")
except: except:
echo "EXCEPT" echo "EXCEPT"

View file

@ -4,8 +4,8 @@ discard """
exitcode: "1" exitcode: "1"
""" """
type type
ESomething = object of E_Base ESomething = object of Exception
ESomeOtherErr = object of E_Base ESomeOtherErr = object of Exception
proc genErrors(s: string) = proc genErrors(s: string) =
if s == "error!": if s == "error!":