diff --git a/changelog.md b/changelog.md index fb70a9a6b0..f21ab39da5 100644 --- a/changelog.md +++ b/changelog.md @@ -5,7 +5,7 @@ - `-d:nimStrictDelete` becomes the default. An index error is produced when the index passed to `system.delete` was out of bounds. Use `-d:nimAuditDelete` to mimic the old behavior for backwards compatibility. - The default user-agent in `std/httpclient` has been changed to `Nim-httpclient/` instead of `Nim httpclient/` which was incorrect according to the HTTP spec. -- Methods now support implementations based on vtable by using `-d:nimPreviewVtables`. methods are confined in the same module where the type has been defined. +- Methods now support implementations based on a VTable by using `--experimental:vtables`. Methods are then confined to be in the same module where their type has been defined. - With `-d:nimPreviewNonVarDestructor`, non-var destructors become the default. ## Standard library additions and changes diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 2f304852b1..462b08a438 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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.. 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]) @@ -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.. 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]) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 5a331ae7c8..d22a6bdc24 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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: + vtables notin m.g.config.features: generateIfMethodDispatchers(graph, m.idgen) diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 3bbe7b3f4a..833bb6fe50 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -157,7 +157,7 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) = proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym) = var witness: PSym = nil - if s.typ[1].owner.getModule != s.getModule and g.config.isDefined("nimPreviewVtables"): + if s.typ[1].owner.getModule != s.getModule and vtables in g.config.features and not g.config.isDefined("nimInternalNonVtablesTesting"): localError(g.config, s.info, errGenerated, "method `" & s.name.s & "` can be defined only in the same module with its type (" & s.typ[1].typeToString() & ")") for i in 0..