This commit is contained in:
Araq 2019-12-19 11:35:15 +01:00 • committed by Andreas Rumpf
commit d1d017ae85
4 changed files with 102 additions and 39 deletions

View file

@ -326,8 +326,22 @@ proc rdCharLoc(a: TLoc): Rope =
if skipTypes(a.t, abstractRange).kind == tyChar:
result = "((NU8)($1))" % [result]
proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
takeAddr: bool) =
type
TAssignmentFlag = enum
needToCopy
TAssignmentFlags = set[TAssignmentFlag]
proc genObjConstr(p: BProc, e: PNode, d: var TLoc)
proc rawConstExpr(p: BProc, n: PNode; d: var TLoc)
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
type
ObjConstrMode = enum
constructObj,
constructRefObj
proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: var TLoc,
mode: ObjConstrMode) =
if p.module.compileToCpp and t.isException and not isDefined(p.config, "noCppExceptions"):
# init vtable in Exception object for polymorphic exceptions
includeHeader(p.module, "<new>")
@ -339,7 +353,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
discard
of frHeader:
var r = rdLoc(a)
if not takeAddr: r = "(*$1)" % [r]
if mode == constructRefObj: r = "(*$1)" % [r]
var s = skipTypes(t, abstractInst)
if not p.module.compileToCpp:
while s.kind == tyObject and s[0] != nil:
@ -348,15 +362,22 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
linefmt(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t, a.lode.info)])
of frEmbedded:
if optTinyRtti in p.config.globalOptions:
localError(p.config, p.prc.info,
"complex object initialization is not supported with --newruntime")
# worst case for performance:
var r = if takeAddr: addrLoc(p.config, a) else: rdLoc(a)
linefmt(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t, a.lode.info)])
var n = newNodeIT(nkObjConstr, a.lode.info, t)
n.add newNodeIT(nkType, a.lode.info, t)
if mode == constructRefObj:
genObjConstr(p, n, a)
else:
var tmp: TLoc
rawConstExpr(p, n, tmp)
genAssignment(p, a, tmp, {})
else:
# worst case for performance:
var r = if mode == constructObj: addrLoc(p.config, a) else: rdLoc(a)
linefmt(p, section, "#objectInit($1, $2);$n", [r, genTypeInfo(p.module, t, a.lode.info)])
if isException(t):
var r = rdLoc(a)
if not takeAddr: r = "(*$1)" % [r]
if mode == constructRefObj: r = "(*$1)" % [r]
var s = skipTypes(t, abstractInst)
if not p.module.compileToCpp:
while s.kind == tyObject and s[0] != nil and s.sym.magic != mException:
@ -364,11 +385,6 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
s = skipTypes(s[0], skipPtrs)
linefmt(p, section, "$1.name = $2;$n", [r, makeCString(t.skipTypes(abstractInst).sym.name.s)])
type
TAssignmentFlag = enum
needToCopy
TAssignmentFlags = set[TAssignmentFlag]
proc genRefAssign(p: BProc, dest, src: TLoc)
proc isComplexValueType(t: PType): bool {.inline.} =
@ -399,7 +415,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
[addrLoc(p.config, loc), genTypeInfo(p.module, loc.t, loc.lode.info)])
# XXX: generated reset procs should not touch the m_type
# field, so disabling this should be safe:
genObjectInit(p, cpsStmts, loc.t, loc, true)
genObjectInit(p, cpsStmts, loc.t, loc, constructObj)
else:
# array passed as argument decayed into pointer, bug #7332
# so we use getTypeDesc here rather than rdLoc(loc)
@ -407,9 +423,9 @@ proc resetLoc(p: BProc, loc: var TLoc) =
[addrLoc(p.config, loc), getTypeDesc(p.module, loc.t)])
# XXX: We can be extra clever here and call memset only
# on the bytes following the m_type field?
genObjectInit(p, cpsStmts, loc.t, loc, true)
genObjectInit(p, cpsStmts, loc.t, loc, constructObj)
proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) =
let typ = loc.t
if optSeqDestructors in p.config.globalOptions and skipTypes(typ, abstractInst).kind in {tyString, tySequence}:
linefmt(p, cpsStmts, "$1.len = 0; $1.p = NIM_NIL;$n", [rdLoc(loc)])
@ -423,7 +439,7 @@ proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
if not isImportedCppType(typ):
linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
[addrLoc(p.config, loc), getTypeDesc(p.module, typ)])
genObjectInit(p, cpsStmts, loc.t, loc, true)
genObjectInit(p, cpsStmts, loc.t, loc, constructObj)
proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
if sfNoInit notin v.flags:
@ -580,7 +596,6 @@ proc genStmts(p: BProc, t: PNode)
proc expr(p: BProc, n: PNode, d: var TLoc)
proc genProcPrototype(m: BModule, sym: PSym)
proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc)
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
proc intLiteral(i: BiggestInt): Rope
proc genLiteral(p: BProc, n: PNode): Rope
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope