Skip to content

Commit

Permalink
tsizeof now almost works for packed types
Browse files Browse the repository at this point in the history
  • Loading branch information
krux02 committed May 9, 2017
1 parent 329477b commit a735356
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 108 deletions.
3 changes: 0 additions & 3 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1730,9 +1730,6 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mNewFinalize: genNewFinalize(p, e)
of mNewSeq: genNewSeq(p, e)
of mNewSeqOfCap: genNewSeqOfCap(p, e, d)
of mSizeOf:
let t = e.sons[1].typ.skipTypes({tyTypeDesc})
putIntoDest(p, d, e.typ, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])
of mChr: genSomeCast(p, e, d)
of mOrd: genOrd(p, e, d)
of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
Expand Down
7 changes: 3 additions & 4 deletions compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1633,11 +1633,11 @@ proc genReprAux(p: PProc, n: PNode, r: var TCompRes, magic: string, typ: Rope =

gen(p, n.sons[1], a)
if magic == "reprAny":
# the pointer argument in reprAny is expandend to
# the pointer argument in reprAny is expandend to
# (pointedto, pointer), so we need to fill it
if a.address.isNil:
add(r.res, a.res)
add(r.res, ", null")
add(r.res, ", null")
else:
add(r.res, "$1, $2" % [a.address, a.res])
else:
Expand Down Expand Up @@ -1670,7 +1670,7 @@ proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
genReprAux(p, n, r, "reprSet", genTypeInfo(p, t))
of tyEmpty, tyVoid:
localError(n.info, "'repr' doesn't support 'void' type")
of tyPointer:
of tyPointer:
genReprAux(p, n, r, "reprPointer")
of tyOpenArray, tyVarargs:
genReprAux(p, n, r, "reprJSONStringify")
Expand Down Expand Up @@ -1758,7 +1758,6 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mIsNil: unaryExpr(p, n, r, "", "($1 === null)")
of mEnumToStr: genRepr(p, n, r)
of mNew, mNewFinalize: genNew(p, n)
of mSizeOf: r.res = rope(getSize(n.sons[1].typ))
of mChr, mArrToSeq: gen(p, n.sons[1], r) # nothing to do
of mOrd: genOrd(p, n, r)
of mLengthStr:
Expand Down
16 changes: 3 additions & 13 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,6 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
localError(n.info, errInvalidArgForX, opToStr[m])
result = n

proc semSizeof(c: PContext, n: PNode): PNode =
if sonsLen(n) != 2:
localError(n.info, errXExpectsTypeOrValue, "sizeof")
else:
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
#restoreOldStyleType(n.sons[1])
n.typ = getSysType(tyInt)
result = n

proc semOf(c: PContext, n: PNode): PNode =
if sonsLen(n) == 3:
n.sons[1] = semExprWithType(c, n.sons[1])
Expand Down Expand Up @@ -936,7 +927,7 @@ proc readTypeParameter(c: PContext, typ: PType,

else:
discard

if typ.kind != tyUserTypeClass:
let ty = if typ.kind == tyCompositeTypeClass: typ.sons[1].skipGenericAlias
else: typ.skipGenericAlias
Expand Down Expand Up @@ -1849,7 +1840,6 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
of mCompiles: result = semCompiles(c, setMs(n, s), flags)
of mLow: result = semLowHigh(c, setMs(n, s), mLow)
of mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
of mSizeOf: result = semSizeof(c, setMs(n, s))
of mIs: result = semIs(c, setMs(n, s), flags)
of mOf: result = semOf(c, setMs(n, s))
of mShallowCopy: result = semShallowCopy(c, n, flags)
Expand Down Expand Up @@ -2300,14 +2290,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
pragma = n[1]
pragmaName = considerQuotedIdent(pragma[0])
flags = flags

case whichKeyword(pragmaName)
of wExplain:
flags.incl efExplain
else:
# what other pragmas are allowed for expressions? `likely`, `unlikely`
invalidPragma(n)

result = semExpr(c, n[0], flags)
of nkPar:
case checkPar(n)
Expand Down
13 changes: 0 additions & 13 deletions compiler/semfold.nim
Original file line number Diff line number Diff line change
Expand Up @@ -653,19 +653,6 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
of mNone:
# If it has no sideEffect, it should be evaluated. But not here.
return
of mSizeOf:
var a = n.sons[1]
if computeSize(a.typ) < 0:
localError(a.info, errCannotEvalXBecauseIncompletelyDefined,
"sizeof")
result = nil
elif skipTypes(a.typ, typedescInst+{tyRange}).kind in
IntegralTypes+NilableTypes+{tySet}:
#{tyArray,tyObject,tyTuple}:
result = newIntNodeT(getSize(a.typ), n)
else:
result = nil
# XXX: size computation for complex types is still wrong
of mLow:
result = newIntNodeT(firstOrd(n.sons[1].typ), n)
of mHigh:
Expand Down
50 changes: 47 additions & 3 deletions compiler/sizealignoffsetimpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,46 @@ proc computeObjectOffsetsRecursive(n: PNode, initialOffset: BiggestInt): tuple[o
result.align = 1
result.offset = szNonConcreteType

proc computePackedObjectOffsetsRecursive(n: PNode, initialOffset: BiggestInt): BiggestInt =
## ``result`` is the offset within the object, after the node has been written, no padding bytes added
case n.kind
of nkRecCase:

assert(n.sons[0].kind == nkSym)
let kindOffset = computePackedObjectOffsetsRecursive(n.sons[0], initialOffset)
# the union neds to be aligned first, before the offsets can be assigned
let kindUnionOffset = kindOffset

var maxChildOffset: BiggestInt = 0
for i in 1 ..< sonsLen(n):
let offset = computePackedObjectOffsetsRecursive(n.sons[i].lastSon, kindUnionOffset)
maxChildOffset = max(maxChildOffset, offset)

result = maxChildOffset



of nkRecList:
result = initialOffset
for i, child in n.sons:
result = computePackedObjectOffsetsRecursive(child, result)
if result < 0:
break

of nkSym:
n.sym.typ.computeSizeAlign
n.sym.offset = initialOffset.int
result = n.sym.offset + n.sym.typ.size

else:
result = szNonConcreteType

# TODO this one needs an alignment map of the individual types

proc computeSizeAlign(typ: PType): void =
## computes and sets ``size`` and ``align`` members of ``typ``


if typ.size >= 0:
# nothing to do, size already computed
return
Expand Down Expand Up @@ -283,7 +318,11 @@ proc computeSizeAlign(typ: PType): void =
headerSize = 0
headerAlign = 1

let (offset, align) = computeObjectOffsetsRecursive(typ.n, headerSize)
let (offset, align) =
if tfPacked in typ.flags:
(computePackedObjectOffsetsRecursive(typ.n, headerSize), BiggestInt(1))
else:
computeObjectOffsetsRecursive(typ.n, headerSize)

if offset < 0:
typ.size = offset
Expand All @@ -292,8 +331,13 @@ proc computeSizeAlign(typ: PType): void =

# header size is already in size from computeObjectOffsetsRecursive
# maxAlign is probably not changed at all from headerAlign
typ.align = int16(max(align, headerAlign))
typ.size = align(offset, typ.align)

if tfPacked in typ.flags:
typ.size = offset
typ.align = 1
else:
typ.size = align(offset, typ.align)
typ.align = int16(max(align, headerAlign))

of tyInferred:
if typ.len > 1:
Expand Down
2 changes: 0 additions & 2 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -948,8 +948,6 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.gABC(n, if m == mOf: opcOf else: opcIs, dest, tmp, idx)
c.freeTemp(tmp)
c.freeTemp(idx)
of mSizeOf:
globalError(n.info, errCannotInterpretNodeX, renderTree(n))
of mHigh:
if dest < 0: dest = c.getTemp(n.typ)
let tmp = c.genx(n.sons[1])
Expand Down
2 changes: 1 addition & 1 deletion lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ proc unsafeNew*[T](a: var ref T, size: Natural) {.magic: "New", noSideEffect.}
## of the passed ``size``. This should only be used for optimization
## purposes when you know what you're doing!

proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect.}
proc sizeof*[T](x: T): int {.magic: "SizeOf", noSideEffect, compileTime.}
## returns the size of ``x`` in bytes. Since this is a low-level proc,
## its usage is discouraged - using ``new`` for the most cases suffices
## that one never needs to know ``x``'s size. As a special semantic rule,
Expand Down
Loading

0 comments on commit a735356

Please sign in to comment.