cbuilder: abstract over int and float generation (#24360)

Different from `intLiteral`, we add procs that just try to generate
integer values, assuming they're not an edge case like `<= low(int32)`
or `> high(int32)`.
This commit is contained in:
metagn
2024-10-26 18:49:30 +03:00
committed by GitHub
parent 40fc2d0e76
commit 506c8a5ce8
5 changed files with 75 additions and 49 deletions

View File

@@ -4,3 +4,29 @@ type
template newBuilder(s: string): Builder =
s
proc addIntValue(builder: var Builder, val: int) =
builder.addInt(val)
proc addIntValue(builder: var Builder, val: int64) =
builder.addInt(val)
proc addIntValue(builder: var Builder, val: uint64) =
builder.addInt(val)
proc addIntValue(builder: var Builder, val: Int128) =
builder.addInt128(val)
template cIntValue(val: int): Snippet = $val
template cIntValue(val: int64): Snippet = $val
template cIntValue(val: uint64): Snippet = $val
template cIntValue(val: Int128): Snippet = $val
import std/formatfloat
proc addFloatValue(builder: var Builder, val: float) =
builder.addFloat(val)
proc cFloatValue(val: float): Snippet =
result = ""
result.addFloat(val)

View File

@@ -61,7 +61,7 @@ proc addArrayVar(builder: var Builder, kind: VarKind = Local, name: string, elem
builder.add(" ")
builder.add(name)
builder.add("[")
builder.addInt(len)
builder.addIntValue(len)
builder.add("]")
if initializer.len != 0:
builder.add(" = ")
@@ -75,7 +75,7 @@ template addArrayVarWithInitializer(builder: var Builder, kind: VarKind = Local,
builder.add(" ")
builder.add(name)
builder.add("[")
builder.addInt(len)
builder.addIntValue(len)
builder.add("] = ")
body
builder.add(";\n")
@@ -97,7 +97,7 @@ template addArrayTypedef(builder: var Builder, name: string, len: BiggestInt, ty
builder.add(" ")
builder.add(name)
builder.add("[")
builder.addInt(len)
builder.addIntValue(len)
builder.add("];\n")
type
@@ -173,7 +173,7 @@ proc addArrayField(obj: var Builder; name, elementType: Snippet; len: int; initi
obj.add(" ")
obj.add(name)
obj.add("[")
obj.addInt(len)
obj.addIntValue(len)
obj.add("]")
if initializer.len != 0:
obj.add(initializer)
@@ -184,7 +184,7 @@ proc addField(obj: var Builder; field: PSym; name, typ: Snippet; isFlexArray: bo
obj.add('\t')
if field.alignment > 0:
obj.add("NIM_ALIGN(")
obj.addInt(field.alignment)
obj.addIntValue(field.alignment)
obj.add(") ")
obj.add(typ)
if sfNoalias in field.flags:
@@ -195,7 +195,7 @@ proc addField(obj: var Builder; field: PSym; name, typ: Snippet; isFlexArray: bo
obj.add("[SEQ_DECL_SIZE]")
if field.bitsize != 0:
obj.add(":")
obj.addInt(field.bitsize)
obj.addIntValue(field.bitsize)
if initializer.len != 0:
obj.add(initializer)
obj.add(";\n")

View File

@@ -2042,7 +2042,7 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) =
b.snippet.add(")")
else:
# handle the case of an empty set
b.snippet = rope("0")
b.snippet = cIntValue(0)
putIntoDest(p, d, e, b.snippet)
else:
assert(e[1].typ != nil)
@@ -2696,7 +2696,7 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
# small set
var ts = "NU" & $(getSize(p.config, e.typ) * 8)
p.s(cpsStmts).addAssignment(rdLoc(d)):
p.s(cpsStmts).add("0")
p.s(cpsStmts).addIntValue(0)
for it in e.sons:
if it.kind == nkRange:
idx = getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt)) # our counter
@@ -3260,8 +3260,8 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Builder)
var t = skipTypes(typ, abstractRange+{tyOwned}-{tyTypeDesc})
case t.kind
of tyBool: result.add rope"NIM_FALSE"
of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result.add rope"0"
of tyFloat..tyFloat128: result.add rope"0.0"
of tyEnum, tyChar, tyInt..tyInt64, tyUInt..tyUInt64: result.addIntValue(0)
of tyFloat..tyFloat128: result.addFloatValue(0.0)
of tyCstring, tyVar, tyLent, tyPointer, tyPtr, tyUntyped,
tyTyped, tyTypeDesc, tyStatic, tyRef, tyNil:
result.add rope"NIM_NIL"
@@ -3270,7 +3270,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Builder)
var seqInit: StructInitializer
result.addStructInitializer(seqInit, kind = siOrderedStruct):
result.addField(seqInit, name = "len"):
result.add("0")
result.addIntValue(0)
result.addField(seqInit, name = "p"):
result.add("NIM_NIL")
else:
@@ -3294,7 +3294,7 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Builder)
result.addStructInitializer(tupleInit, kind = siOrderedStruct):
if p.vccAndC and t.isEmptyTupleType:
result.addField(tupleInit, name = "dummy"):
result.add "0"
result.addIntValue(0)
for i, a in t.ikids:
result.addField(tupleInit, name = "Field" & $i):
getDefaultValue(p, a, info, result)
@@ -3311,13 +3311,13 @@ proc getDefaultValue(p: BProc; typ: PType; info: TLineInfo; result: var Builder)
result.addField(openArrInit, name = "Field0"):
result.add("NIM_NIL")
result.addField(openArrInit, name = "Field1"):
result.add("0")
result.addIntValue(0)
of tySet:
if mapSetType(p.config, t) == ctArray:
var setInit: StructInitializer
result.addStructInitializer(setInit, kind = siArray):
discard
else: result.add "0"
else: result.addIntValue(0)
else:
globalError(p.config, info, "cannot create null element for: " & $t.kind)
@@ -3459,7 +3459,7 @@ proc genConstTuple(p: BProc, n: PNode; isConst: bool; tup: PType; result: var Bu
result.addStructInitializer(tupleInit, kind = siOrderedStruct):
if p.vccAndC and n.len == 0:
result.addField(tupleInit, name = "dummy"):
result.add("0")
result.addIntValue(0)
for i in 0..<n.len:
var it = n[i]
if it.kind == nkExprColonExpr:
@@ -3527,7 +3527,7 @@ proc genConstSeqV2(p: BProc, n: PNode, t: PType; isConst: bool; result: var Buil
var resultInit: StructInitializer
result.addStructInitializer(resultInit, kind = siOrderedStruct):
result.addField(resultInit, name = "len"):
result.add(rope(n.len))
result.addIntValue(n.len)
result.addField(resultInit, name = "p"):
result.add cCast(typ = ptrType(getSeqPayloadType(p.module, t)), value = cAddr(payload))
@@ -3601,7 +3601,7 @@ proc genBracedInit(p: BProc, n: PNode; isConst: bool; optionalType: PType; resul
result.addField(openArrInit, name = "Field0"):
result.add(cCast(typ = ptrType(ctype), value = cAddr(payload)))
result.addField(openArrInit, name = "Field1"):
result.add(rope arrLen)
result.addIntValue(arrLen)
of tyObject:
genConstObjConstr(p, n, isConst, result)

View File

@@ -48,7 +48,7 @@ proc genStringLiteralDataOnlyV1(m: BModule, s: string; result: var Rope) =
var seqInit: StructInitializer
res.addStructInitializer(seqInit, kind = siOrderedStruct):
res.addField(seqInit, name = "len"):
res.add(rope(s.len))
res.addIntValue(s.len)
res.addField(seqInit, name = "reserved"):
res.add(cCast("NI", bitOr(cCast("NU", rope(s.len)), "NIM_STRLIT_FLAG")))
res.addField(strInit, name = "data"):
@@ -109,7 +109,7 @@ proc genStringLiteralV2(m: BModule; n: PNode; isConst: bool; result: var Rope) =
var strInit: StructInitializer
res.addStructInitializer(strInit, kind = siOrderedStruct):
res.addField(strInit, name = "len"):
res.add(rope(n.strVal.len))
res.addIntValue(n.strVal.len)
res.addField(strInit, name = "p"):
res.add(cCast(ptrType("NimStrPayload"), cAddr(litName)))
m.s[cfsStrData].add(res)
@@ -128,7 +128,7 @@ proc genStringLiteralV2Const(m: BModule; n: PNode; isConst: bool; result: var Ro
var strInit: StructInitializer
result.addStructInitializer(strInit, kind = siOrderedStruct):
result.addField(strInit, name = "len"):
result.add(rope(n.strVal.len))
result.addIntValue(n.strVal.len)
result.addField(strInit, name = "p"):
result.add(cCast(ptrType("NimStrPayload"), cAddr(pureLit)))

View File

@@ -1265,7 +1265,7 @@ proc genProcHeader(m: BModule; prc: PSym; result: var Rope; asPtr: bool = false)
proc genTypeInfoV1(m: BModule; t: PType; info: TLineInfo): Rope
proc getNimNode(m: BModule): Rope =
result = subscript(m.typeNodesName, rope(m.typeNodes))
result = subscript(m.typeNodesName, cIntValue(m.typeNodes))
inc(m.typeNodes)
proc tiNameForHcr(m: BModule; name: Rope): Rope =
@@ -1324,11 +1324,11 @@ proc genTypeInfoAux(m: BModule; typ, origType: PType, name: Rope;
var x = typ.last
if typ.kind == tyObject: x = x.skipTypes(skipPtrs)
if typ.kind == tyPtr and x.kind == tyObject and incompleteType(x):
base = rope("0")
base = cIntValue(0)
else:
base = genTypeInfoV1(m, x, info)
else:
base = rope("0")
base = cIntValue(0)
genTypeInfoAuxBase(m, typ, origType, name, base, info)
proc discriminatorTableName(m: BModule; objtype: PType, d: PSym): Rope =
@@ -1366,20 +1366,20 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
genTNimNodeArray(m, tmp, rope(n.len))
for i in 0..<n.len:
var tmp2 = getNimNode(m)
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, rope(i)):
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(i)):
m.s[cfsTypeInit3].add(cAddr(tmp2))
genObjectFields(m, typ, origType, n[i], tmp2, info)
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
m.s[cfsTypeInit3].add(rope(n.len))
m.s[cfsTypeInit3].addIntValue(n.len)
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
m.s[cfsTypeInit3].add("2")
m.s[cfsTypeInit3].addIntValue(2)
m.s[cfsTypeInit3].addFieldAssignment(expr, "sons"):
m.s[cfsTypeInit3].add(cAddr(subscript(tmp, "0")))
m.s[cfsTypeInit3].add(cAddr(subscript(tmp, cIntValue(0))))
else:
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
m.s[cfsTypeInit3].add(rope(n.len))
m.s[cfsTypeInit3].addIntValue(n.len)
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
m.s[cfsTypeInit3].add("2")
m.s[cfsTypeInit3].addIntValue(2)
of nkRecCase:
assert(n[0].kind == nkSym)
var field = n[0].sym
@@ -1410,14 +1410,14 @@ proc genObjectFields(m: BModule; typ, origType: PType, n: PNode, expr: Rope;
var x = toInt(getOrdValue(b[j][0]))
var y = toInt(getOrdValue(b[j][1]))
while x <= y:
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, rope(x)):
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(x)):
m.s[cfsTypeInit3].add(cAddr(tmp2))
inc(x)
else:
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, rope(getOrdValue(b[j]))):
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(getOrdValue(b[j]))):
m.s[cfsTypeInit3].add(cAddr(tmp2))
of nkElse:
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, rope(L)):
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(L)):
m.s[cfsTypeInit3].add(cAddr(tmp2))
else: internalError(m.config, n.info, "genObjectFields(nkRecCase)")
of nkSym:
@@ -1452,14 +1452,14 @@ proc genObjectInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo
t = t.baseClass
proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo) =
genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info)
genTypeInfoAuxBase(m, typ, typ, name, cIntValue(0), info)
var expr = getNimNode(m)
if not typ.isEmptyTupleType:
var tmp = getTempName(m) & "_" & $typ.kidsLen
genTNimNodeArray(m, tmp, rope(typ.kidsLen))
for i, a in typ.ikids:
var tmp2 = getNimNode(m)
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, rope(i)):
m.s[cfsTypeInit3].addSubscriptAssignment(tmp, cIntValue(i)):
m.s[cfsTypeInit3].add(cAddr(tmp2))
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
"$1.offset = offsetof($2, Field$3);$n" &
@@ -1467,16 +1467,16 @@ proc genTupleInfo(m: BModule; typ, origType: PType, name: Rope; info: TLineInfo)
"$1.name = \"Field$3\";$n",
[tmp2, getTypeDesc(m, origType, dkVar), rope(i), genTypeInfoV1(m, a, info)])
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
m.s[cfsTypeInit3].add(rope(typ.kidsLen))
m.s[cfsTypeInit3].addIntValue(typ.kidsLen)
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
m.s[cfsTypeInit3].add("2")
m.s[cfsTypeInit3].addIntValue(2)
m.s[cfsTypeInit3].addFieldAssignment(expr, "sons"):
m.s[cfsTypeInit3].add(cAddr(subscript(tmp, "0")))
m.s[cfsTypeInit3].add(cAddr(subscript(tmp, cIntValue(0))))
else:
m.s[cfsTypeInit3].addFieldAssignment(expr, "len"):
m.s[cfsTypeInit3].add(rope(typ.kidsLen))
m.s[cfsTypeInit3].addIntValue(typ.kidsLen)
m.s[cfsTypeInit3].addFieldAssignment(expr, "kind"):
m.s[cfsTypeInit3].add("2")
m.s[cfsTypeInit3].addIntValue(2)
m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "node"):
m.s[cfsTypeInit3].add(cAddr(expr))
@@ -1506,7 +1506,7 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
enumNames.add(makeCString(field.ast.strVal))
if field.position != i or tfEnumHasHoles in typ.flags:
specialCases.addFieldAssignment(elemNode, "offset"):
specialCases.add(rope(field.position))
specialCases.addIntValue(field.position)
hasHoles = true
var enumArray = getTempName(m)
var counter = getTempName(m)
@@ -1524,11 +1524,11 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
m.s[cfsTypeInit3].add(specialCases)
let n = getNimNode(m)
m.s[cfsTypeInit3].addFieldAssignment(n, "len"):
m.s[cfsTypeInit3].add(rope(typ.n.len))
m.s[cfsTypeInit3].addIntValue(typ.n.len)
m.s[cfsTypeInit3].addFieldAssignment(n, "kind"):
m.s[cfsTypeInit3].add("2")
m.s[cfsTypeInit3].addIntValue(0)
m.s[cfsTypeInit3].addFieldAssignment(n, "sons"):
m.s[cfsTypeInit3].add(cAddr(subscript(nodePtrs, "0")))
m.s[cfsTypeInit3].add(cAddr(subscript(nodePtrs, cIntValue(0))))
m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "node"):
m.s[cfsTypeInit3].add(cAddr(n))
if hasHoles:
@@ -1540,9 +1540,9 @@ proc genSetInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
genTypeInfoAux(m, typ, typ, name, info)
var tmp = getNimNode(m)
m.s[cfsTypeInit3].addFieldAssignment(tmp, "len"):
m.s[cfsTypeInit3].add(rope(firstOrd(m.config, typ)))
m.s[cfsTypeInit3].addIntValue(firstOrd(m.config, typ))
m.s[cfsTypeInit3].addFieldAssignment(tmp, "kind"):
m.s[cfsTypeInit3].add("0")
m.s[cfsTypeInit3].addIntValue(0)
m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "node"):
m.s[cfsTypeInit3].add(cAddr(tmp))
@@ -1746,7 +1746,7 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin
len = objDepth + 1,
initializer = objDisplay)
typeEntry.addFieldAssignment(name, "display"):
typeEntry.add(rope(objDisplayStore))
typeEntry.add(objDisplayStore)
let dispatchMethods = toSeq(getMethodsPerType(m.g.graph, t))
if dispatchMethods.len > 0:
@@ -1940,9 +1940,9 @@ proc genTypeInfoV1(m: BModule; t: PType; info: TLineInfo): Rope =
rememberEmittedTypeInfo(m.g.graph, FileIndex(owner), $result)
case t.kind
of tyEmpty, tyVoid: result = rope"0"
of tyEmpty, tyVoid: result = cIntValue(0)
of tyPointer, tyBool, tyChar, tyCstring, tyString, tyInt..tyUInt64, tyVar, tyLent:
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
genTypeInfoAuxBase(m, t, t, result, cIntValue(0), info)
of tyStatic:
if t.n != nil: result = genTypeInfoV1(m, skipModifier t, info)
else: internalError(m.config, "genTypeInfoV1(" & $t.kind & ')')
@@ -1951,7 +1951,7 @@ proc genTypeInfoV1(m: BModule; t: PType; info: TLineInfo): Rope =
return genTypeInfoV1(m, t.skipModifier, info)
of tyProc:
if t.callConv != ccClosure:
genTypeInfoAuxBase(m, t, t, result, rope"0", info)
genTypeInfoAuxBase(m, t, t, result, cIntValue(0), info)
else:
let x = fakeClosureType(m, t.owner)
genTupleInfo(m, x, x, result, info)