mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-01 03:24:41 +00:00
Optimize lent in JS [backport:1.6] (#19393)
* Optimize lent in JS [backport:1.6] * addr on lent doesn't work anymore, don't use it * use unsafeAddr in test again for older versions
This commit is contained in:
@@ -178,7 +178,7 @@ const
|
||||
proc mapType(typ: PType): TJSTypeKind =
|
||||
let t = skipTypes(typ, abstractInst)
|
||||
case t.kind
|
||||
of tyVar, tyRef, tyPtr, tyLent:
|
||||
of tyVar, tyRef, tyPtr:
|
||||
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
||||
result = etyObject
|
||||
else:
|
||||
@@ -186,7 +186,8 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||
of tyPointer:
|
||||
# treat a tyPointer like a typed pointer to an array of bytes
|
||||
result = etyBaseIndex
|
||||
of tyRange, tyDistinct, tyOrdinal, tyProxy:
|
||||
of tyRange, tyDistinct, tyOrdinal, tyProxy, tyLent:
|
||||
# tyLent is no-op as JS has pass-by-reference semantics
|
||||
result = mapType(t[0])
|
||||
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
|
||||
of tyBool: result = etyBool
|
||||
@@ -1060,14 +1061,14 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||
xtyp = etySeq
|
||||
case xtyp
|
||||
of etySeq:
|
||||
if (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
|
||||
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
|
||||
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||
else:
|
||||
useMagic(p, "nimCopy")
|
||||
lineF(p, "$1 = nimCopy(null, $2, $3);$n",
|
||||
[a.rdLoc, b.res, genTypeInfo(p, y.typ)])
|
||||
of etyObject:
|
||||
if x.typ.kind in {tyVar} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
|
||||
if x.typ.kind in {tyVar, tyLent} or (needsNoCopy(p, y) and needsNoCopy(p, x)) or noCopyNeeded:
|
||||
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||
else:
|
||||
useMagic(p, "nimCopy")
|
||||
@@ -1092,10 +1093,18 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||
lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
|
||||
lineF(p, "$1 = $2;$n", [a.address, b.res])
|
||||
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||
elif a.typ == etyBaseIndex:
|
||||
# array indexing may not map to var type
|
||||
if b.address != nil:
|
||||
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||
else:
|
||||
lineF(p, "$1 = $2;$n", [a.address, b.res])
|
||||
else:
|
||||
internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
|
||||
else:
|
||||
elif b.address != nil:
|
||||
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||
else:
|
||||
lineF(p, "$1 = $2;$n", [a.address, b.res])
|
||||
else:
|
||||
lineF(p, "$1 = $2;$n", [a.rdLoc, b.rdLoc])
|
||||
|
||||
@@ -1288,7 +1297,7 @@ template isIndirect(x: PSym): bool =
|
||||
v.kind notin {skProc, skFunc, skConverter, skMethod, skIterator,
|
||||
skConst, skTemp, skLet})
|
||||
|
||||
proc genSymAddr(p: PProc, n: PNode, typ: PType, r: var TCompRes) =
|
||||
proc genSymAddr(p: PProc, n: PNode, typ: PType, r: var TCompRes) =
|
||||
let s = n.sym
|
||||
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
|
||||
case s.kind
|
||||
@@ -1456,13 +1465,17 @@ proc genSym(p: PProc, n: PNode, r: var TCompRes) =
|
||||
else:
|
||||
if s.loc.r == nil:
|
||||
internalError(p.config, n.info, "symbol has no generated name: " & s.name.s)
|
||||
r.res = s.loc.r
|
||||
if mapType(p, s.typ) == etyBaseIndex:
|
||||
r.address = s.loc.r
|
||||
r.res = s.loc.r & "_Idx"
|
||||
else:
|
||||
r.res = s.loc.r
|
||||
r.kind = resVal
|
||||
|
||||
proc genDeref(p: PProc, n: PNode, r: var TCompRes) =
|
||||
let it = n[0]
|
||||
let t = mapType(p, it.typ)
|
||||
if t == etyObject:
|
||||
if t == etyObject or it.typ.kind == tyLent:
|
||||
gen(p, it, r)
|
||||
else:
|
||||
var a: TCompRes
|
||||
@@ -1703,7 +1716,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||
result = putToSeq("0", indirect)
|
||||
of tyFloat..tyFloat128:
|
||||
result = putToSeq("0.0", indirect)
|
||||
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned:
|
||||
of tyRange, tyGenericInst, tyAlias, tySink, tyOwned, tyLent:
|
||||
result = createVar(p, lastSon(typ), indirect)
|
||||
of tySet:
|
||||
result = putToSeq("{}", indirect)
|
||||
@@ -1745,7 +1758,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||
createObjInitList(p, t, initIntSet(), initList)
|
||||
result = ("({$1})") % [initList]
|
||||
if indirect: result = "[$1]" % [result]
|
||||
of tyVar, tyPtr, tyLent, tyRef, tyPointer:
|
||||
of tyVar, tyPtr, tyRef, tyPointer:
|
||||
if mapType(p, t) == etyBaseIndex:
|
||||
result = putToSeq("[null, 0]", indirect)
|
||||
else:
|
||||
@@ -2394,16 +2407,17 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
||||
if prc.typ[0] != nil and sfPure notin prc.flags:
|
||||
resultSym = prc.ast[resultPos].sym
|
||||
let mname = mangleName(p.module, resultSym)
|
||||
if not isIndirect(resultSym) and
|
||||
let returnAddress = not isIndirect(resultSym) and
|
||||
resultSym.typ.kind in {tyVar, tyPtr, tyLent, tyRef, tyOwned} and
|
||||
mapType(p, resultSym.typ) == etyBaseIndex:
|
||||
mapType(p, resultSym.typ) == etyBaseIndex
|
||||
if returnAddress:
|
||||
resultAsgn = p.indentLine(("var $# = null;$n") % [mname])
|
||||
resultAsgn.add p.indentLine("var $#_Idx = 0;$n" % [mname])
|
||||
else:
|
||||
let resVar = createVar(p, resultSym.typ, isIndirect(resultSym))
|
||||
resultAsgn = p.indentLine(("var $# = $#;$n") % [mname, resVar])
|
||||
gen(p, prc.ast[resultPos], a)
|
||||
if mapType(p, resultSym.typ) == etyBaseIndex:
|
||||
if returnAddress:
|
||||
returnStmt = "return [$#, $#];$n" % [a.address, a.res]
|
||||
else:
|
||||
returnStmt = "return $#;$n" % [a.res]
|
||||
@@ -2579,8 +2593,15 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
|
||||
of nkObjConstr: genObjConstr(p, n, r)
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, n, r)
|
||||
of nkAddr, nkHiddenAddr:
|
||||
genAddr(p, n, r)
|
||||
of nkDerefExpr, nkHiddenDeref: genDeref(p, n, r)
|
||||
if n.typ.kind in {tyLent}:
|
||||
gen(p, n[0], r)
|
||||
else:
|
||||
genAddr(p, n, r)
|
||||
of nkDerefExpr, nkHiddenDeref:
|
||||
if n.typ.kind in {tyLent}:
|
||||
gen(p, n[0], r)
|
||||
else:
|
||||
genDeref(p, n, r)
|
||||
of nkBracketExpr: genArrayAccess(p, n, r)
|
||||
of nkDotExpr: genFieldAccess(p, n, r)
|
||||
of nkCheckedFieldExpr: genCheckedFieldOp(p, n, nil, r)
|
||||
|
||||
Reference in New Issue
Block a user