Skip to content

Commit

Permalink
enable vtable implementation for C++
Browse files Browse the repository at this point in the history
  • Loading branch information
ringabout authored Nov 29, 2023
1 parent 96513b2 commit 0aca90f
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 15 deletions.
22 changes: 15 additions & 7 deletions compiler/ccgtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,13 @@ proc genDisplay(m: BModule; t: PType, depth: int): Rope =
result.add seqs[0]
result.add "}"

proc genVTable(seqs: seq[PSym]): string =
result = "{"
for i in 0..<seqs.len:
if i > 0: result.add ", "
result.add "(void *) " & seqs[i].loc.r
result.add "}"

proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
cgsym(m, "TNimTypeV2")
m.s[cfsStrData].addf("N_LIB_PRIVATE TNimTypeV2 $1;$n", [name])
Expand Down Expand Up @@ -1714,18 +1721,19 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin
m.s[cfsVars].addf("static $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), dkVar), objDisplayStore, rope(objDepth+1), objDisplay])
addf(typeEntry, "$1.display = $2;$n", [name, rope(objDisplayStore)])

let dispatchMethods = toSeq(getMethodsPerType(m.g.graph, t))
if dispatchMethods.len > 0:
let vTablePointerName = getTempName(m)
m.s[cfsVars].addf("static void* $1[$2] = $3;$n", [vTablePointerName, rope(dispatchMethods.len), genVTable(dispatchMethods)])
for i in dispatchMethods:
genProcPrototype(m, i)
addf(typeEntry, "$1.vTable = $2;$n", [name, vTablePointerName])

m.s[cfsTypeInit3].add typeEntry

if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
discard genTypeInfoV1(m, t, info)

proc genVTable(seqs: seq[PSym]): string =
result = "{"
for i in 0..<seqs.len:
if i > 0: result.add ", "
result.add "(void *) " & seqs[i].loc.r
result.add "}"

proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineInfo) =
cgsym(m, "TNimTypeV2")
m.s[cfsStrData].addf("N_LIB_PRIVATE TNimTypeV2 $1;$n", [name])
Expand Down
3 changes: 1 addition & 2 deletions compiler/cgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2234,8 +2234,7 @@ proc finalCodegenActions*(graph: ModuleGraph; m: BModule; n: PNode) =
incl m.flags, objHasKidsValid
if optMultiMethods in m.g.config.globalOptions or
m.g.config.selectedGC notin {gcArc, gcOrc, gcAtomicArc} or
not m.g.config.isDefined("nimPreviewVtables") or
m.g.config.backend == backendCpp or sfCompileToCpp in m.module.flags:
not m.g.config.isDefined("nimPreviewVtables"):
generateIfMethodDispatchers(graph, m.idgen)


Expand Down
4 changes: 1 addition & 3 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,7 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
trackStmt(c, c.module, result, isTopLevel = true)
if optMultiMethods notin c.config.globalOptions and
c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and
c.config.isDefined("nimPreviewVtables") and
c.config.backend != backendCpp and
sfCompileToCpp notin c.module.flags:
c.config.isDefined("nimPreviewVtables"):
sortVTableDispatchers(c.graph)

if sfMainModule in c.module.flags:
Expand Down
7 changes: 5 additions & 2 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1606,8 +1606,11 @@ when not defined(js) and defined(nimV2):
traceImpl: pointer
typeInfoV1: pointer # for backwards compat, usually nil
flags: int
when defined(nimPreviewVtables) and not defined(cpp):
vTable: UncheckedArray[pointer] # vtable for types
when defined(nimPreviewVtables):
when defined(cpp):
vTable: ptr UncheckedArray[pointer] # vtable for types
else:
vTable: UncheckedArray[pointer] # vtable for types
PNimTypeV2 = ptr TNimTypeV2

proc supportsCopyMem(t: typedesc): bool {.magic: "TypeTrait".}
Expand Down
2 changes: 1 addition & 1 deletion lib/system/arc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ template tearDownForeignThreadGc* =
proc isObjDisplayCheck(source: PNimTypeV2, targetDepth: int16, token: uint32): bool {.compilerRtl, inl.} =
result = targetDepth <= source.depth and source.display[targetDepth] == token

when defined(nimPreviewVtables) and not defined(cpp):
when defined(nimPreviewVtables):
proc nimGetVTable(p: pointer, index: int): pointer
{.compilerRtl, inline, raises: [].} =
result = cast[ptr PNimTypeV2](p).vTable[index]
5 changes: 5 additions & 0 deletions tests/method/tvtable.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
discard """
targets: "c cpp"
"""

type FooBase = ref object of RootObj
dummy: int
type Foo = ref object of FooBase
Expand All @@ -15,5 +19,6 @@ method bar(x: Foo2, a: float32) =
proc test() =
var x = new Foo2
x.bar(2.3)
doAssert x.value <= 2.3

test()

0 comments on commit 0aca90f

Please sign in to comment.