parent
1f1ef85eb0
commit
ed126794b6
3 changed files with 50 additions and 29 deletions
|
|
@ -256,32 +256,8 @@ proc addAbiCheck(m: BModule, t: PType, name: Rope) =
|
||||||
m.s[cfsTypeInfo].addf("NIM_STATIC_ASSERT(sizeof($1) == $2, $3);$n", [name, rope(size), msg2.rope])
|
m.s[cfsTypeInfo].addf("NIM_STATIC_ASSERT(sizeof($1) == $2, $3);$n", [name, rope(size), msg2.rope])
|
||||||
# see `testCodegenABICheck` for example error message it generates
|
# see `testCodegenABICheck` for example error message it generates
|
||||||
|
|
||||||
proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool =
|
from ccgutils import ccgIntroducedPtr
|
||||||
var pt = skipTypes(s.typ, typedescInst)
|
export ccgIntroducedPtr
|
||||||
assert skResult != s.kind
|
|
||||||
|
|
||||||
if tfByRef in pt.flags: return true
|
|
||||||
elif tfByCopy in pt.flags: return false
|
|
||||||
case pt.kind
|
|
||||||
of tyObject:
|
|
||||||
if s.typ.sym != nil and sfForward in s.typ.sym.flags:
|
|
||||||
# forwarded objects are *always* passed by pointers for consistency!
|
|
||||||
result = true
|
|
||||||
elif (optByRef in s.options) or (getSize(conf, pt) > conf.target.floatSize * 3):
|
|
||||||
result = true # requested anyway
|
|
||||||
elif (tfFinal in pt.flags) and (pt[0] == nil):
|
|
||||||
result = false # no need, because no subtyping possible
|
|
||||||
else:
|
|
||||||
result = true # ordinary objects are always passed by reference,
|
|
||||||
# otherwise casting doesn't work
|
|
||||||
of tyTuple:
|
|
||||||
result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options)
|
|
||||||
else:
|
|
||||||
result = false
|
|
||||||
# first parameter and return type is 'lent T'? --> use pass by pointer
|
|
||||||
if s.position == 0 and retType != nil and retType.kind == tyLent:
|
|
||||||
result = not (pt.kind in {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} or
|
|
||||||
pt.kind == tySet and mapSetType(conf, pt) == ctArray)
|
|
||||||
|
|
||||||
proc fillResult(conf: ConfigRef; param: PNode) =
|
proc fillResult(conf: ConfigRef; param: PNode) =
|
||||||
fillLoc(param.sym.loc, locParam, param, ~"Result",
|
fillLoc(param.sym.loc, locParam, param, ~"Result",
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
# This module declares some helpers for the C code generator.
|
# This module declares some helpers for the C code generator.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, hashes, strutils, msgs, wordrecg,
|
ast, types, hashes, strutils, msgs, wordrecg,
|
||||||
platform, trees, options
|
platform, trees, options, cgendata
|
||||||
|
|
||||||
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -106,3 +106,39 @@ proc mangle*(name: string): string =
|
||||||
requiresUnderscore = true
|
requiresUnderscore = true
|
||||||
if requiresUnderscore:
|
if requiresUnderscore:
|
||||||
result.add "_"
|
result.add "_"
|
||||||
|
|
||||||
|
proc mapSetType(conf: ConfigRef; typ: PType): TCTypeKind =
|
||||||
|
case int(getSize(conf, typ))
|
||||||
|
of 1: result = ctInt8
|
||||||
|
of 2: result = ctInt16
|
||||||
|
of 4: result = ctInt32
|
||||||
|
of 8: result = ctInt64
|
||||||
|
else: result = ctArray
|
||||||
|
|
||||||
|
proc ccgIntroducedPtr*(conf: ConfigRef; s: PSym, retType: PType): bool =
|
||||||
|
var pt = skipTypes(s.typ, typedescInst)
|
||||||
|
assert skResult != s.kind
|
||||||
|
|
||||||
|
if tfByRef in pt.flags: return true
|
||||||
|
elif tfByCopy in pt.flags: return false
|
||||||
|
case pt.kind
|
||||||
|
of tyObject:
|
||||||
|
if s.typ.sym != nil and sfForward in s.typ.sym.flags:
|
||||||
|
# forwarded objects are *always* passed by pointers for consistency!
|
||||||
|
result = true
|
||||||
|
elif (optByRef in s.options) or (getSize(conf, pt) > conf.target.floatSize * 3):
|
||||||
|
result = true # requested anyway
|
||||||
|
elif (tfFinal in pt.flags) and (pt[0] == nil):
|
||||||
|
result = false # no need, because no subtyping possible
|
||||||
|
else:
|
||||||
|
result = true # ordinary objects are always passed by reference,
|
||||||
|
# otherwise casting doesn't work
|
||||||
|
of tyTuple:
|
||||||
|
result = (getSize(conf, pt) > conf.target.floatSize*3) or (optByRef in s.options)
|
||||||
|
else:
|
||||||
|
result = false
|
||||||
|
# first parameter and return type is 'lent T'? --> use pass by pointer
|
||||||
|
if s.position == 0 and retType != nil and retType.kind == tyLent:
|
||||||
|
result = not (pt.kind in {tyVar, tyArray, tyOpenArray, tyVarargs, tyRef, tyPtr, tyPointer} or
|
||||||
|
pt.kind == tySet and mapSetType(conf, pt) == ctArray)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``).
|
## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``).
|
||||||
|
|
||||||
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
||||||
sighashes, lowerings, options, types, msgs, magicsys, tables
|
sighashes, lowerings, options, types, msgs, magicsys, tables, ccgutils
|
||||||
|
|
||||||
from trees import isCaseObj
|
from trees import isCaseObj
|
||||||
|
|
||||||
|
|
@ -230,6 +230,15 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||||
# for every field (dependent on dest.kind):
|
# for every field (dependent on dest.kind):
|
||||||
# `=` dest.field, src.field
|
# `=` dest.field, src.field
|
||||||
# =destroy(blob)
|
# =destroy(blob)
|
||||||
|
var dummy = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextSymId c.idgen, c.fn, c.info)
|
||||||
|
dummy.typ = y.typ
|
||||||
|
if ccgIntroducedPtr(c.g.config, dummy, y.typ):
|
||||||
|
# Because of potential aliasing when the src param is passed by ref, we need to check for equality here,
|
||||||
|
# because the wasMoved(dest) call would zero out src, if dest aliases src.
|
||||||
|
var cond = newTree(nkCall, newSymNode(c.g.getSysMagic(c.info, "==", mEqRef)),
|
||||||
|
newTreeIT(nkAddr, c.info, makePtrType(c.fn, x.typ, c.idgen), x), newTreeIT(nkAddr, c.info, makePtrType(c.fn, y.typ, c.idgen), y))
|
||||||
|
cond.typ = getSysType(c.g, x.info, tyBool)
|
||||||
|
body.add genIf(c, cond, newTreeI(nkReturnStmt, c.info, newNodeI(nkEmpty, c.info)))
|
||||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextSymId c.idgen, c.fn, c.info)
|
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextSymId c.idgen, c.fn, c.info)
|
||||||
temp.typ = x.typ
|
temp.typ = x.typ
|
||||||
incl(temp.flags, sfFromGeneric)
|
incl(temp.flags, sfFromGeneric)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue