sizeof alignof offsetof macros api (#10855)
This commit is contained in:
parent
16fcbee1bc
commit
188870648a
7 changed files with 93 additions and 1 deletions
|
|
@ -662,7 +662,7 @@ type
|
||||||
|
|
||||||
mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal,
|
mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal,
|
||||||
mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
|
mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
|
||||||
mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mNSigHash,
|
mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mNSigHash, mNSizeOf,
|
||||||
mNBindSym, mLocals, mNCallSite,
|
mNBindSym, mLocals, mNCallSite,
|
||||||
mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
|
mEqIdent, mEqNimrodNode, mSameNodeType, mGetImpl, mNGenSym,
|
||||||
mNHint, mNWarning, mNError,
|
mNHint, mNWarning, mNError,
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimHasNilSeqs")
|
defineSymbol("nimHasNilSeqs")
|
||||||
defineSymbol("nimHasSignatureHashInMacro")
|
defineSymbol("nimHasSignatureHashInMacro")
|
||||||
defineSymbol("nimHasDefault")
|
defineSymbol("nimHasDefault")
|
||||||
|
defineSymbol("nimMacrosSizealignof")
|
||||||
for f in low(Feature)..high(Feature):
|
for f in low(Feature)..high(Feature):
|
||||||
defineSymbol("nimHas" & $f)
|
defineSymbol("nimHas" & $f)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1477,6 +1477,27 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
|
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, "node has no type")
|
stackTrace(c, tos, pc, "node has no type")
|
||||||
|
of opcNGetSize:
|
||||||
|
decodeBImm(rkInt)
|
||||||
|
let n = regs[rb].node
|
||||||
|
case imm
|
||||||
|
of 0: # size
|
||||||
|
if n.typ == nil:
|
||||||
|
stackTrace(c, tos, pc, "node has no type")
|
||||||
|
else:
|
||||||
|
regs[ra].intVal = getSize(c.config, n.typ)
|
||||||
|
of 1: # align
|
||||||
|
if n.typ == nil:
|
||||||
|
stackTrace(c, tos, pc, "node has no type")
|
||||||
|
else:
|
||||||
|
regs[ra].intVal = getAlign(c.config, n.typ)
|
||||||
|
else: # offset
|
||||||
|
if n.kind != nkSym:
|
||||||
|
stackTrace(c, tos, pc, "node is not a symbol")
|
||||||
|
elif n.sym.kind != skField:
|
||||||
|
stackTrace(c, tos, pc, "symbol is not a field (nskField)")
|
||||||
|
else:
|
||||||
|
regs[ra].intVal = n.sym.offset
|
||||||
of opcNStrVal:
|
of opcNStrVal:
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
createStr regs[ra]
|
createStr regs[ra]
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ type
|
||||||
opcNGetType,
|
opcNGetType,
|
||||||
opcNStrVal,
|
opcNStrVal,
|
||||||
opcNSigHash,
|
opcNSigHash,
|
||||||
|
opcNGetSize,
|
||||||
|
|
||||||
opcNSetIntVal,
|
opcNSetIntVal,
|
||||||
opcNSetFloatVal, opcNSetSymbol, opcNSetIdent, opcNSetType, opcNSetStrVal,
|
opcNSetFloatVal, opcNSetSymbol, opcNSetIdent, opcNSetType, opcNSetStrVal,
|
||||||
|
|
|
||||||
|
|
@ -1236,6 +1236,12 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
||||||
c.gABC(n, opcNGetType, dest, tmp, rc)
|
c.gABC(n, opcNGetType, dest, tmp, rc)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
#genUnaryABC(c, n, dest, opcNGetType)
|
#genUnaryABC(c, n, dest, opcNGetType)
|
||||||
|
of mNSizeOf:
|
||||||
|
let imm = case n[0].sym.name.s:
|
||||||
|
of "getSize": 0
|
||||||
|
of "getAlign": 1
|
||||||
|
else: 2 # "getOffset"
|
||||||
|
c.genUnaryABI(n, dest, opcNGetSize, imm)
|
||||||
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
|
of mNStrVal: genUnaryABC(c, n, dest, opcNStrVal)
|
||||||
of mNSigHash: genUnaryABC(c, n , dest, opcNSigHash)
|
of mNSigHash: genUnaryABC(c, n , dest, opcNSigHash)
|
||||||
of mNSetIntVal:
|
of mNSetIntVal:
|
||||||
|
|
|
||||||
|
|
@ -1582,3 +1582,15 @@ proc getProjectPath*(): string = discard
|
||||||
## Returns the path to the currently compiling project, not to
|
## Returns the path to the currently compiling project, not to
|
||||||
## be confused with ``system.currentSourcePath`` which returns
|
## be confused with ``system.currentSourcePath`` which returns
|
||||||
## the path of the current module.
|
## the path of the current module.
|
||||||
|
|
||||||
|
when defined(nimMacrosSizealignof):
|
||||||
|
proc getSize*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
|
## Returns the same result as ``system.sizeof``, but it works on
|
||||||
|
## ``NimNode`` for use in macro context.
|
||||||
|
proc getAlign*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
|
## Returns the same result as ``system.alignof``, but it works on
|
||||||
|
## ``NimNode`` for use in macro context.
|
||||||
|
proc getOffset*(arg: NimNode): int {.magic: "NSizeOf", noSideEffect.} =
|
||||||
|
## Returns the same result as ``system.offsetof``, but it expects
|
||||||
|
## a resolved symbol node from a field of a type. Therefore it
|
||||||
|
## only requires one argument instead of two.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ discard """
|
||||||
body executed
|
body executed
|
||||||
body executed
|
body executed
|
||||||
OK
|
OK
|
||||||
|
macros api OK
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -485,3 +486,53 @@ if failed:
|
||||||
quit("FAIL")
|
quit("FAIL")
|
||||||
else:
|
else:
|
||||||
echo "OK"
|
echo "OK"
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# sizeof macros API
|
||||||
|
##########################################
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
type
|
||||||
|
Vec2f = object
|
||||||
|
x,y: float32
|
||||||
|
|
||||||
|
Vec4f = object
|
||||||
|
x,y,z,w: float32
|
||||||
|
|
||||||
|
# this type is constructed to have no platform depended alignment.
|
||||||
|
ParticleDataA = object
|
||||||
|
pos, vel: Vec2f
|
||||||
|
birthday: float32
|
||||||
|
padding: float32
|
||||||
|
moreStuff: Vec4f
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
# name size align offset
|
||||||
|
("pos", 8, 4, 0),
|
||||||
|
("vel", 8, 4, 8),
|
||||||
|
("birthday", 4, 4, 16),
|
||||||
|
("padding", 4, 4, 20),
|
||||||
|
("moreStuff", 16, 4, 24)
|
||||||
|
]
|
||||||
|
|
||||||
|
macro typeProcessing(arg: typed): untyped =
|
||||||
|
let recList = arg.getTypeImpl[2]
|
||||||
|
recList.expectKind nnkRecList
|
||||||
|
for i, identDefs in recList:
|
||||||
|
identDefs.expectKind nnkIdentDefs
|
||||||
|
identDefs.expectLen 3
|
||||||
|
let sym = identDefs[0]
|
||||||
|
sym.expectKind nnkSym
|
||||||
|
doAssert expected[i][0] == sym.strVal
|
||||||
|
doAssert expected[i][1] == getSize(sym)
|
||||||
|
doAssert expected[i][2] == getAlign(sym)
|
||||||
|
doAssert expected[i][3] == getOffset(sym)
|
||||||
|
|
||||||
|
result = newCall(bindSym"echo", newLit("macros api OK"))
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
var mylocal: ParticleDataA
|
||||||
|
typeProcessing(mylocal)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue