From 24aa92c14f2301d1ef63f59bc4ae2ec31a64f9c5 Mon Sep 17 00:00:00 2001 From: metagn Date: Sat, 26 Oct 2024 21:55:50 +0300 Subject: [PATCH] cbuilder: add calls, sizeof/alignof/offsetof, use in ccgtypes (#24362) follows #24360, #24351 --- compiler/cbuilderexprs.nim | 50 +++++++++++++ compiler/cbuilderstmts.nim | 5 ++ compiler/ccgtypes.nim | 149 ++++++++++++++++++++++++++----------- 3 files changed, 162 insertions(+), 42 deletions(-) diff --git a/compiler/cbuilderexprs.nim b/compiler/cbuilderexprs.nim index fec7ec6d9b..4f2426965e 100644 --- a/compiler/cbuilderexprs.nim +++ b/compiler/cbuilderexprs.nim @@ -48,3 +48,53 @@ proc derefField(a, b: Snippet): Snippet = proc bitOr(a, b: Snippet): Snippet = "(" & a & " | " & b & ")" + +type CallBuilder = object + needsComma: bool + +proc initCallBuilder(builder: var Builder, callee: Snippet): CallBuilder = + result = CallBuilder(needsComma: false) + builder.add(callee) + builder.add("(") + +template addArgument(builder: var Builder, call: var CallBuilder, valueBody: typed) = + if call.needsComma: + builder.add(", ") + else: + call.needsComma = true + valueBody + +proc finishCallBuilder(builder: var Builder, call: CallBuilder) = + builder.add(")") + +template addCall(builder: var Builder, call: out CallBuilder, callee: Snippet, body: typed) = + call = initCallBuilder(builder, callee) + body + finishCallBuilder(builder, call) + +proc addNullaryCall(builder: var Builder, callee: Snippet) = + builder.add(callee) + builder.add("()") + +proc addUnaryCall(builder: var Builder, callee: Snippet, arg: Snippet) = + builder.add(callee) + builder.add("(") + builder.add(arg) + builder.add(")") + +proc addSizeof(builder: var Builder, val: Snippet) = + builder.add("sizeof(") + builder.add(val) + builder.add(")") + +proc addAlignof(builder: var Builder, val: Snippet) = + builder.add("NIM_ALIGNOF(") + builder.add(val) + builder.add(")") + +proc addOffsetof(builder: var Builder, val, member: Snippet) = + builder.add("offsetof(") + builder.add(val) + builder.add(", ") + builder.add(member) + builder.add(")") diff --git a/compiler/cbuilderstmts.nim b/compiler/cbuilderstmts.nim index f78ca1d8ed..9f0cb5d942 100644 --- a/compiler/cbuilderstmts.nim +++ b/compiler/cbuilderstmts.nim @@ -21,3 +21,8 @@ template addSubscriptAssignment(builder: var Builder, lhs: Snippet, index: Snipp builder.add("[" & index & "] = ") valueBody builder.add(";\n") + +template addStmt(builder: var Builder, stmtBody: typed) = + ## makes an expression built by `stmtBody` into a statement + stmtBody + builder.add(";\n") diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index a2fa8178c0..5aea0d0f1e 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1287,33 +1287,53 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; size = rope"void*" else: size = getTypeDesc(m, origType, dkVar) - m.s[cfsTypeInit3].addf( - "$1.size = sizeof($2);$n$1.align = NIM_ALIGNOF($2);$n$1.kind = $3;$n$1.base = $4;$n", - [nameHcr, size, rope(nimtypeKind), base] - ) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "size"): + m.s[cfsTypeInit3].addSizeof(size) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "align"): + m.s[cfsTypeInit3].addAlignof(size) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "kind"): + m.s[cfsTypeInit3].addIntValue(nimtypeKind) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "base"): + m.s[cfsTypeInit3].add(base) # compute type flags for GC optimization var flags = 0 if not containsGarbageCollectedRef(typ): flags = flags or 1 if not canFormAcycle(m.g.graph, typ): flags = flags or 2 #else echo("can contain a cycle: " & typeToString(typ)) if flags != 0: - m.s[cfsTypeInit3].addf("$1.flags = $2;$n", [nameHcr, rope(flags)]) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "flags"): + m.s[cfsTypeInit3].addIntValue(flags) cgsym(m, "TNimType") if isDefined(m.config, "nimTypeNames"): var typename = typeToString(if origType.typeInst != nil: origType.typeInst else: origType, preferName) if typename == "ref object" and origType.skipTypes(skipPtrs).sym != nil: typename = "anon ref object from " & m.config$origType.skipTypes(skipPtrs).sym.info - m.s[cfsTypeInit3].addf("$1.name = $2;$n", - [nameHcr, makeCString typename]) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "name"): + m.s[cfsTypeInit3].add(makeCString typename) cgsym(m, "nimTypeRoot") - m.s[cfsTypeInit3].addf("$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n", - [nameHcr]) + m.s[cfsTypeInit3].addFieldAssignment(nameHcr, "nextType"): + m.s[cfsTypeInit3].add("nimTypeRoot") + m.s[cfsTypeInit3].addAssignment("nimTypeRoot"): + m.s[cfsTypeInit3].add(cAddr(nameHcr)) if m.hcrOn: - m.s[cfsStrData].addf("static TNimType* $1;$n", [name]) - m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($2, \"$1\", sizeof(TNimType), NULL, (void**)&$1);$n", - [name, getModuleDllPath(m, m.module)]) + m.s[cfsStrData].addVar(kind = Global, name = name, typ = ptrType("TNimType")) + m.hcrCreateTypeInfosProc.add('\t') + var registerHcr: CallBuilder + m.hcrCreateTypeInfosProc.addStmt(): + m.hcrCreateTypeInfosProc.addCall(registerHcr, callee = "hcrRegisterGlobal"): + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add(getModuleDllPath(m, m.module)) + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add(makeCString(name)) + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.addSizeof("TNimType") + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add("NULL") + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.addCast(typ = "void**"): + m.hcrCreateTypeInfosProc.add(cAddr(name)) else: m.s[cfsStrData].addf("N_LIB_PRIVATE TNimType $1;$n", [name]) @@ -1347,13 +1367,27 @@ proc discriminatorTableDecl(m: BModule; objtype: PType, d: PSym): Rope = var tmp = discriminatorTableName(m, objtype, d) result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(m.config, d.typ)+1)] -proc genTNimNodeArray(m: BModule; name: Rope, size: Rope) = +proc genTNimNodeArray(m: BModule; name: Rope, size: int) = if m.hcrOn: - m.s[cfsData].addf("static TNimNode** $1;$n", [name]) - m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($3, \"$1\", sizeof(TNimNode*) * $2, NULL, (void**)&$1);$n", - [name, size, getModuleDllPath(m, m.module)]) + m.s[cfsData].addVar(kind = Global, name = name, typ = ptrType(ptrType("TNimNode"))) + var registerHcr: CallBuilder + m.hcrCreateTypeInfosProc.addStmt(): + m.hcrCreateTypeInfosProc.addCall(registerHcr, callee = "hcrRegisterGlobal"): + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add(getModuleDllPath(m, m.module)) + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add(makeCString(name)) + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + # XXX use cbuilder here + m.hcrCreateTypeInfosProc.add("sizeof(TNimNode*) * " & $size) + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.add("NULL") + m.hcrCreateTypeInfosProc.addArgument(registerHcr): + m.hcrCreateTypeInfosProc.addCast(typ = "void**"): + m.hcrCreateTypeInfosProc.add(cAddr(name)) else: - m.s[cfsTypeInit1].addf("static TNimNode* $1[$2];$n", [name, size]) + m.s[cfsTypeInit1].addArrayVar(kind = Global, name = name, + elementType = ptrType("TNimNode"), len = size) proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope; info: TLineInfo) = @@ -1363,7 +1397,7 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope; genObjectFields(m, typ, origType, n[0], expr, info) elif n.len > 0: var tmp = getTempName(m) & "_" & $n.len - genTNimNodeArray(m, tmp, rope(n.len)) + genTNimNodeArray(m, tmp, n.len) for i in 0..= 0: let objDisplay = genDisplay(m, t, objDepth)