fixes #2476
This commit is contained in:
parent
751232dc7c
commit
5cea6807e1
5 changed files with 161 additions and 152 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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!":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue