Skip to content

Commit

Permalink
use cbuilder for ccgliterals (nim-lang#24302)
Browse files Browse the repository at this point in the history
follows up nim-lang#24259 

This was the only use of the `STRING_LITERAL` macro in `nimbase.h`, so
this macro is now removed. We don't have to remove it though, maybe
people use it.
  • Loading branch information
metagn authored Oct 14, 2024
1 parent d4b9c14 commit 34c87de
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 28 deletions.
2 changes: 1 addition & 1 deletion compiler/cbuilderexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ proc cAddr(value: Snippet): Snippet =
"&" & value

proc bitOr(a, b: Snippet): Snippet =
a & " | " & b
"(" & a & " | " & b & ")"
70 changes: 49 additions & 21 deletions compiler/ccgliterals.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,37 @@ proc genStringLiteralDataOnlyV1(m: BModule, s: string; result: var Rope) =
cgsym(m, "TGenericSeq")
let tmp = getTempName(m)
result.add tmp
m.s[cfsStrData].addf("STRING_LITERAL($1, $2, $3);$n",
[tmp, makeCString(s), rope(s.len)])
var res = newBuilder("")
res.addVarWithTypeAndInitializer(AlwaysConst, name = tmp):
res.addSimpleStruct(m, name = "", baseType = ""):
res.addField(name = "Sup", typ = "TGenericSeq")
res.addArrayField(name = "data", elementType = "NIM_CHAR", len = s.len + 1)
do:
var strInit: StructInitializer
res.addStructInitializer(strInit, kind = siOrderedStruct):
res.addField(strInit, name = "Sup"):
var seqInit: StructInitializer
res.addStructInitializer(seqInit, kind = siOrderedStruct):
res.addField(seqInit, name = "len"):
res.add(rope(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"):
res.add(makeCString(s))
m.s[cfsStrData].add(res)

proc genStringLiteralV1(m: BModule; n: PNode; result: var Rope) =
if s.isNil:
appcg(m, result, "((#NimStringDesc*) NIM_NIL)", [])
result.add(cCast(ptrType(cgsymValue(m, "NimStringDesc")), "NIM_NIL"))
else:
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
var name: string = ""
if id == m.labels:
# string literal not found in the cache:
appcg(m, result, "((#NimStringDesc*) &", [])
genStringLiteralDataOnlyV1(m, n.strVal, result)
result.add ")"
genStringLiteralDataOnlyV1(m, n.strVal, name)
else:
appcg(m, result, "((#NimStringDesc*) &$1$2)",
[m.tmpBase, id])
name = m.tmpBase & $id
result.add(cCast(ptrType(cgsymValue(m, "NimStringDesc")), cAddr(name)))

# ------ Version 2: destructor based strings and seqs -----------------------

Expand All @@ -74,22 +89,30 @@ proc genStringLiteralDataOnlyV2(m: BModule, s: string; result: Rope; isConst: bo

proc genStringLiteralV2(m: BModule; n: PNode; isConst: bool; result: var Rope) =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
var litName: string
if id == m.labels:
let pureLit = getTempName(m)
genStringLiteralDataOnlyV2(m, n.strVal, pureLit, isConst)
let tmp = getTempName(m)
result.add tmp
cgsym(m, "NimStrPayload")
cgsym(m, "NimStringV2")
# string literal not found in the cache:
m.s[cfsStrData].addf("static $4 NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[tmp, rope(n.strVal.len), pureLit, rope(if isConst: "const" else: "")])
litName = getTempName(m)
genStringLiteralDataOnlyV2(m, n.strVal, litName, isConst)
else:
let tmp = getTempName(m)
result.add tmp
m.s[cfsStrData].addf("static $4 NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[tmp, rope(n.strVal.len), m.tmpBase & rope(id),
rope(if isConst: "const" else: "")])
litName = m.tmpBase & $id
let tmp = getTempName(m)
result.add tmp
var res = newBuilder("")
res.addVarWithTypeAndInitializer(
if isConst: AlwaysConst else: Global,
name = tmp):
res.add("NimStringV2")
do:
var strInit: StructInitializer
res.addStructInitializer(strInit, kind = siOrderedStruct):
res.addField(strInit, name = "len"):
res.add(rope(n.strVal.len))
res.addField(strInit, name = "p"):
res.add(cCast(ptrType("NimStrPayload"), cAddr(litName)))
m.s[cfsStrData].add(res)

proc genStringLiteralV2Const(m: BModule; n: PNode; isConst: bool; result: var Rope) =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
Expand All @@ -102,7 +125,12 @@ proc genStringLiteralV2Const(m: BModule; n: PNode; isConst: bool; result: var Ro
genStringLiteralDataOnlyV2(m, n.strVal, pureLit, isConst)
else:
pureLit = m.tmpBase & rope(id)
result.addf "{$1, (NimStrPayload*)&$2}", [rope(n.strVal.len), pureLit]
var strInit: StructInitializer
result.addStructInitializer(strInit, kind = siOrderedStruct):
result.addField(strInit, name = "len"):
result.add(rope(n.strVal.len))
result.addField(strInit, name = "p"):
result.add(cCast(ptrType("NimStrPayload"), cAddr(pureLit)))

# ------ Version selector ---------------------------------------------------

Expand All @@ -118,7 +146,7 @@ proc genStringLiteralDataOnly(m: BModule; s: string; info: TLineInfo;
localError(m.config, info, "cannot determine how to produce code for string literal")

proc genNilStringLiteral(m: BModule; info: TLineInfo; result: var Rope) =
appcg(m, result, "((#NimStringDesc*) NIM_NIL)", [])
result.add(cCast(ptrType(cgsymValue(m, "NimStringDesc")), "NIM_NIL"))

proc genStringLiteral(m: BModule; n: PNode; result: var Rope) =
case detectStrVersion(m)
Expand Down
6 changes: 0 additions & 6 deletions lib/nimbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,6 @@ typedef char* NCSTRING;

#define NIM_STRLIT_FLAG ((NU)(1) << ((NIM_INTBITS) - 2)) /* This has to be the same as system.strlitFlag! */

#define STRING_LITERAL(name, str, length) \
static const struct { \
TGenericSeq Sup; \
NIM_CHAR data[(length) + 1]; \
} name = {{length, (NI) ((NU)length | NIM_STRLIT_FLAG)}, str}

/* declared size of a sequence/variable length array: */
#if defined(__cplusplus) && defined(__clang__)
# define SEQ_DECL_SIZE 1
Expand Down

0 comments on commit 34c87de

Please sign in to comment.