Skip to content

Commit 24aa92c

Browse files
authored
cbuilder: add calls, sizeof/alignof/offsetof, use in ccgtypes (#24362)
follows #24360, #24351
1 parent 031ad95 commit 24aa92c

File tree

3 files changed

+162
-42
lines changed

3 files changed

+162
-42
lines changed

compiler/cbuilderexprs.nim

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,53 @@ proc derefField(a, b: Snippet): Snippet =
4848

4949
proc bitOr(a, b: Snippet): Snippet =
5050
"(" & a & " | " & b & ")"
51+
52+
type CallBuilder = object
53+
needsComma: bool
54+
55+
proc initCallBuilder(builder: var Builder, callee: Snippet): CallBuilder =
56+
result = CallBuilder(needsComma: false)
57+
builder.add(callee)
58+
builder.add("(")
59+
60+
template addArgument(builder: var Builder, call: var CallBuilder, valueBody: typed) =
61+
if call.needsComma:
62+
builder.add(", ")
63+
else:
64+
call.needsComma = true
65+
valueBody
66+
67+
proc finishCallBuilder(builder: var Builder, call: CallBuilder) =
68+
builder.add(")")
69+
70+
template addCall(builder: var Builder, call: out CallBuilder, callee: Snippet, body: typed) =
71+
call = initCallBuilder(builder, callee)
72+
body
73+
finishCallBuilder(builder, call)
74+
75+
proc addNullaryCall(builder: var Builder, callee: Snippet) =
76+
builder.add(callee)
77+
builder.add("()")
78+
79+
proc addUnaryCall(builder: var Builder, callee: Snippet, arg: Snippet) =
80+
builder.add(callee)
81+
builder.add("(")
82+
builder.add(arg)
83+
builder.add(")")
84+
85+
proc addSizeof(builder: var Builder, val: Snippet) =
86+
builder.add("sizeof(")
87+
builder.add(val)
88+
builder.add(")")
89+
90+
proc addAlignof(builder: var Builder, val: Snippet) =
91+
builder.add("NIM_ALIGNOF(")
92+
builder.add(val)
93+
builder.add(")")
94+
95+
proc addOffsetof(builder: var Builder, val, member: Snippet) =
96+
builder.add("offsetof(")
97+
builder.add(val)
98+
builder.add(", ")
99+
builder.add(member)
100+
builder.add(")")

compiler/cbuilderstmts.nim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snipp
2121
builder.add("[" & index & "] = ")
2222
valueBody
2323
builder.add(";\n")
24+
25+
template addStmt(builder: var Builder, stmtBody: typed) =
26+
## makes an expression built by `stmtBody` into a statement
27+
stmtBody
28+
builder.add(";\n")

compiler/ccgtypes.nim

Lines changed: 107 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,33 +1287,53 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
12871287
size = rope"void*"
12881288
else:
12891289
size = getTypeDesc(m, origType, dkVar)
1290-
m.s[cfsTypeInit3].addf(
1291-
"$1.size = sizeof($2);$n$1.align = NIM_ALIGNOF($2);$n$1.kind = $3;$n$1.base = $4;$n",
1292-
[nameHcr, size, rope(nimtypeKind), base]
1293-
)
1290+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "size"):
1291+
m.s[cfsTypeInit3].addSizeof(size)
1292+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "align"):
1293+
m.s[cfsTypeInit3].addAlignof(size)
1294+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "kind"):
1295+
m.s[cfsTypeInit3].addIntValue(nimtypeKind)
1296+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "base"):
1297+
m.s[cfsTypeInit3].add(base)
12941298
# compute type flags for GC optimization
12951299
var flags = 0
12961300
if not containsGarbageCollectedRef(typ): flags = flags or 1
12971301
if not canFormAcycle(m.g.graph, typ): flags = flags or 2
12981302
#else echo("can contain a cycle: " & typeToString(typ))
12991303
if flags != 0:
1300-
m.s[cfsTypeInit3].addf("$1.flags = $2;$n", [nameHcr, rope(flags)])
1304+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "flags"):
1305+
m.s[cfsTypeInit3].addIntValue(flags)
13011306
cgsym(m, "TNimType")
13021307
if isDefined(m.config, "nimTypeNames"):
13031308
var typename = typeToString(if origType.typeInst != nil: origType.typeInst
13041309
else: origType, preferName)
13051310
if typename == "ref object" and origType.skipTypes(skipPtrs).sym != nil:
13061311
typename = "anon ref object from " & m.config$origType.skipTypes(skipPtrs).sym.info
1307-
m.s[cfsTypeInit3].addf("$1.name = $2;$n",
1308-
[nameHcr, makeCString typename])
1312+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "name"):
1313+
m.s[cfsTypeInit3].add(makeCString typename)
13091314
cgsym(m, "nimTypeRoot")
1310-
m.s[cfsTypeInit3].addf("$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n",
1311-
[nameHcr])
1315+
m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "nextType"):
1316+
m.s[cfsTypeInit3].add("nimTypeRoot")
1317+
m.s[cfsTypeInit3].addAssignment("nimTypeRoot"):
1318+
m.s[cfsTypeInit3].add(cAddr(nameHcr))
13121319

13131320
if m.hcrOn:
1314-
m.s[cfsStrData].addf("static TNimType* $1;$n", [name])
1315-
m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($2, \"$1\", sizeof(TNimType), NULL, (void**)&$1);$n",
1316-
[name, getModuleDllPath(m, m.module)])
1321+
m.s[cfsStrData].addVar(kind = Global, name = name, typ = ptrType("TNimType"))
1322+
m.hcrCreateTypeInfosProc.add('\t')
1323+
var registerHcr: CallBuilder
1324+
m.hcrCreateTypeInfosProc.addStmt():
1325+
m.hcrCreateTypeInfosProc.addCall(registerHcr, callee = "hcrRegisterGlobal"):
1326+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1327+
m.hcrCreateTypeInfosProc.add(getModuleDllPath(m, m.module))
1328+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1329+
m.hcrCreateTypeInfosProc.add(makeCString(name))
1330+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1331+
m.hcrCreateTypeInfosProc.addSizeof("TNimType")
1332+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1333+
m.hcrCreateTypeInfosProc.add("NULL")
1334+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1335+
m.hcrCreateTypeInfosProc.addCast(typ = "void**"):
1336+
m.hcrCreateTypeInfosProc.add(cAddr(name))
13171337
else:
13181338
m.s[cfsStrData].addf("N_LIB_PRIVATE TNimType $1;$n", [name])
13191339

@@ -1347,13 +1367,27 @@ proc discriminatorTableDecl(m: BModule; objtype: PType, d: PSym): Rope =
13471367
var tmp = discriminatorTableName(m, objtype, d)
13481368
result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(m.config, d.typ)+1)]
13491369

1350-
proc genTNimNodeArray(m: BModule; name: Rope, size: Rope) =
1370+
proc genTNimNodeArray(m: BModule; name: Rope, size: int) =
13511371
if m.hcrOn:
1352-
m.s[cfsData].addf("static TNimNode** $1;$n", [name])
1353-
m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($3, \"$1\", sizeof(TNimNode*) * $2, NULL, (void**)&$1);$n",
1354-
[name, size, getModuleDllPath(m, m.module)])
1372+
m.s[cfsData].addVar(kind = Global, name = name, typ = ptrType(ptrType("TNimNode")))
1373+
var registerHcr: CallBuilder
1374+
m.hcrCreateTypeInfosProc.addStmt():
1375+
m.hcrCreateTypeInfosProc.addCall(registerHcr, callee = "hcrRegisterGlobal"):
1376+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1377+
m.hcrCreateTypeInfosProc.add(getModuleDllPath(m, m.module))
1378+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1379+
m.hcrCreateTypeInfosProc.add(makeCString(name))
1380+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1381+
# XXX use cbuilder here
1382+
m.hcrCreateTypeInfosProc.add("sizeof(TNimNode*) * " & $size)
1383+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1384+
m.hcrCreateTypeInfosProc.add("NULL")
1385+
m.hcrCreateTypeInfosProc.addArgument(registerHcr):
1386+
m.hcrCreateTypeInfosProc.addCast(typ = "void**"):
1387+
m.hcrCreateTypeInfosProc.add(cAddr(name))
13551388
else:
1356-
m.s[cfsTypeInit1].addf("static TNimNode* $1[$2];$n", [name, size])
1389+
m.s[cfsTypeInit1].addArrayVar(kind = Global, name = name,
1390+
elementType = ptrType("TNimNode"), len = size)
13571391

13581392
proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
13591393
info: TLineInfo) =
@@ -1363,7 +1397,7 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
13631397
genObjectFields(m, typ, origType, n[0], expr, info)
13641398
elif n.len > 0:
13651399
var tmp = getTempName(m) & "_" & $n.len
1366-
genTNimNodeArray(m, tmp, rope(n.len))
1400+
genTNimNodeArray(m, tmp, n.len)
13671401
for i in 0..<n.len:
13681402
var tmp2 = getNimNode(m)
13691403
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(i)):
@@ -1389,14 +1423,21 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
13891423
if field.loc.snippet == "": fillObjectFields(m, typ)
13901424
if field.loc.t == nil:
13911425
internalError(m.config, n.info, "genObjectFields")
1392-
m.s[cfsTypeInit3].addf("$1.kind = 3;$n" &
1393-
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
1394-
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
1395-
"$1.len = $7;$n", [expr, getTypeDesc(m, origType, dkVar), field.loc.snippet,
1396-
genTypeInfoV1(m, field.typ, info),
1397-
makeCString(field.name.s),
1398-
tmp, rope(L)])
1399-
m.s[cfsData].addf("TNimNode* $1[$2];$n", [tmp, rope(L+1)])
1426+
let fieldTypInfo = genTypeInfoV1(m, field.typ, info)
1427+
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
1428+
m.s[cfsTypeInit3].addIntValue(3)
1429+
m.s[cfsTypeInit3].addFieldAssignment(expr, "offset"):
1430+
m.s[cfsTypeInit3].addOffsetof(getTypeDesc(m, origType, dkVar), field.loc.snippet)
1431+
m.s[cfsTypeInit3].addFieldAssignment(expr, "typ"):
1432+
m.s[cfsTypeInit3].add(fieldTypInfo)
1433+
m.s[cfsTypeInit3].addFieldAssignment(expr, "name"):
1434+
m.s[cfsTypeInit3].add(makeCString(field.name.s))
1435+
m.s[cfsTypeInit3].addFieldAssignment(expr, "sons"):
1436+
m.s[cfsTypeInit3].add(cAddr(subscript(tmp, "0")))
1437+
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
1438+
m.s[cfsTypeInit3].addIntValue(L)
1439+
m.s[cfsData].addArrayVar(kind = Local, name = tmp,
1440+
elementType = ptrType("TNimNode"), len = toInt(L)+1)
14001441
for i in 1..<n.len:
14011442
var b = n[i] # branch
14021443
var tmp2 = getNimNode(m)
@@ -1428,10 +1469,15 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
14281469
if field.loc.snippet == "": fillObjectFields(m, typ)
14291470
if field.loc.t == nil:
14301471
internalError(m.config, n.info, "genObjectFields")
1431-
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
1432-
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
1433-
"$1.name = $5;$n", [expr, getTypeDesc(m, origType, dkVar),
1434-
field.loc.snippet, genTypeInfoV1(m, field.typ, info), makeCString(field.name.s)])
1472+
let fieldTypInfo = genTypeInfoV1(m, field.typ, info)
1473+
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
1474+
m.s[cfsTypeInit3].addIntValue(1)
1475+
m.s[cfsTypeInit3].addFieldAssignment(expr, "offset"):
1476+
m.s[cfsTypeInit3].addOffsetof(getTypeDesc(m, origType, dkVar), field.loc.snippet)
1477+
m.s[cfsTypeInit3].addFieldAssignment(expr, "typ"):
1478+
m.s[cfsTypeInit3].add(fieldTypInfo)
1479+
m.s[cfsTypeInit3].addFieldAssignment(expr, "name"):
1480+
m.s[cfsTypeInit3].add(makeCString(field.name.s))
14351481
else: internalError(m.config, n.info, "genObjectFields")
14361482

14371483
proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) =
@@ -1456,16 +1502,20 @@ proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo)
14561502
var expr = getNimNode(m)
14571503
if not typ.isEmptyTupleType:
14581504
var tmp = getTempName(m) & "_" & $typ.kidsLen
1459-
genTNimNodeArray(m, tmp, rope(typ.kidsLen))
1505+
genTNimNodeArray(m, tmp, typ.kidsLen)
14601506
for i, a in typ.ikids:
14611507
var tmp2 = getNimNode(m)
1508+
let fieldTypInfo = genTypeInfoV1(m, a, info)
14621509
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(i)):
14631510
m.s[cfsTypeInit3].add(cAddr(tmp2))
1464-
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
1465-
"$1.offset = offsetof($2, Field$3);$n" &
1466-
"$1.typ = $4;$n" &
1467-
"$1.name = \"Field$3\";$n",
1468-
[tmp2, getTypeDesc(m, origType, dkVar), rope(i), genTypeInfoV1(m, a, info)])
1511+
m.s[cfsTypeInit3].addFieldAssignment(tmp2, "kind"):
1512+
m.s[cfsTypeInit3].addIntValue(1)
1513+
m.s[cfsTypeInit3].addFieldAssignment(tmp2, "offset"):
1514+
m.s[cfsTypeInit3].addOffsetof(getTypeDesc(m, origType, dkVar), "Field" & $i)
1515+
m.s[cfsTypeInit3].addFieldAssignment(tmp2, "typ"):
1516+
m.s[cfsTypeInit3].add(fieldTypInfo)
1517+
m.s[cfsTypeInit3].addFieldAssignment(tmp2, "name"):
1518+
m.s[cfsTypeInit3].add("\"Field" & $i & "\"")
14691519
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
14701520
m.s[cfsTypeInit3].addIntValue(typ.kidsLen)
14711521
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
@@ -1487,7 +1537,7 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
14871537
# positions will be reset after the loop.
14881538
genTypeInfoAux(m, typ, typ, name, info)
14891539
var nodePtrs = getTempName(m) & "_" & $typ.n.len
1490-
genTNimNodeArray(m, nodePtrs, rope(typ.n.len))
1540+
genTNimNodeArray(m, nodePtrs, typ.n.len)
14911541
var enumNames = newBuilder("")
14921542
var enumNamesInit: StructInitializer
14931543
var specialCases = newBuilder("")
@@ -1568,9 +1618,16 @@ proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) =
15681618
proc declareNimType(m: BModule; name: string; str: Rope, module: int) =
15691619
let nr = rope(name)
15701620
if m.hcrOn:
1571-
m.s[cfsStrData].addf("static $2* $1;$n", [str, nr])
1572-
m.s[cfsTypeInit1].addf("\t$1 = ($3*)hcrGetGlobal($2, \"$1\");$n",
1573-
[str, getModuleDllPath(m, module), nr])
1621+
m.s[cfsStrData].addVar(kind = Global, name = str, typ = ptrType(nr))
1622+
m.s[cfsTypeInit1].add('\t')
1623+
m.s[cfsTypeInit1].addAssignment(str):
1624+
m.s[cfsTypeInit1].addCast(typ = ptrType(nr)):
1625+
var hcrGlobal: CallBuilder
1626+
m.s[cfsTypeInit1].addCall(hcrGlobal, "hcrGetGlobal"):
1627+
m.s[cfsTypeInit1].addArgument(hcrGlobal):
1628+
m.s[cfsTypeInit1].add(getModuleDllPath(m, module))
1629+
m.s[cfsTypeInit1].addArgument(hcrGlobal):
1630+
m.s[cfsTypeInit1].add("\"" & str & "\"")
15741631
else:
15751632
m.s[cfsStrData].addf("extern $2 $1;$n", [str, nr])
15761633

@@ -1734,8 +1791,16 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin
17341791
typeName = rope("NIM_NIL")
17351792
typeEntry.addFieldAssignment(name, "name"):
17361793
typeEntry.add(typeName)
1737-
addf(typeEntry, "$1.size = sizeof($2); $1.align = (NI16) NIM_ALIGNOF($2); $1.depth = $3; $1.flags = $4;",
1738-
[name, getTypeDesc(m, t), rope(objDepth), rope(flags)])
1794+
let sizeTyp = getTypeDesc(m, t)
1795+
typeEntry.addFieldAssignment(name, "size"):
1796+
typeEntry.addSizeof(sizeTyp)
1797+
typeEntry.addFieldAssignment(name, "align"):
1798+
typeEntry.addCast(typ = "NI16"):
1799+
typeEntry.addAlignof(sizeTyp)
1800+
typeEntry.addFieldAssignment(name, "depth"):
1801+
typeEntry.addIntValue(objDepth)
1802+
typeEntry.addFieldAssignment(name, "flags"):
1803+
typeEntry.addIntValue(flags)
17391804

17401805
if objDepth >= 0:
17411806
let objDisplay = genDisplay(m, t, objDepth)

0 commit comments

Comments
 (0)