WIP: adds NIF code generator for interop with Nimony (#24966)

This commit is contained in:
Andreas Rumpf
2025-05-26 15:42:19 +02:00
committed by GitHub
parent 8752392838
commit 241edaf0c0
12 changed files with 1722 additions and 7 deletions

View File

@@ -675,6 +675,9 @@ type
TInstantiation* = object
sym*: PSym
concreteTypes*: seq[PType]
genericParamsCount*: int # for terrible reasons `concreteTypes` contains all the types,
# so we need to know how many generic params there were
# this is not serialized for IC and that is fine.
compilesId*: CompilesId
PInstantiation* = ref TInstantiation

View File

@@ -473,6 +473,7 @@ proc parseCommand*(command: string): Command =
of "cpp", "compiletocpp": cmdCompileToCpp
of "objc", "compiletooc": cmdCompileToOC
of "js", "compiletojs": cmdCompileToJS
of "nif": cmdCompileToNif
of "r": cmdCrun
of "m": cmdM
of "run": cmdTcc
@@ -507,6 +508,7 @@ proc setCmd*(conf: ConfigRef, cmd: Command) =
of cmdCompileToCpp: conf.backend = backendCpp
of cmdCompileToOC: conf.backend = backendObjc
of cmdCompileToJS: conf.backend = backendJs
of cmdCompileToNif: conf.backend = backendNif
else: discard
proc setCommandEarly*(conf: ConfigRef, command: string) =

View File

@@ -341,7 +341,7 @@ proc getConfigVar(conf: ConfigRef; c: TSystemCC, suffix: string): string =
var fullSuffix = suffix
case conf.backend
of backendCpp, backendJs, backendObjc: fullSuffix = "." & $conf.backend & suffix
of backendC: discard
of backendC, backendNif: discard
of backendInvalid:
# during parsing of cfg files; we don't know the backend yet, no point in
# guessing wrong thing

View File

@@ -117,6 +117,22 @@ when not defined(leanCompiler):
else: raiseAssert $ext
compilePipelineProject(graph)
proc commandCompileToNif(graph: ModuleGraph) =
let conf = graph.config
extccomp.initVars(conf)
if conf.symbolFiles == disabledSf:
if {optRun, optForceFullMake} * conf.globalOptions == {optRun} or isDefined(conf, "nimBetterRun"):
if not changeDetectedViaJsonBuildInstructions(conf, conf.jsonBuildInstructionsFile):
# nothing changed
graph.config.notes = graph.config.mainPackageNotes
return
if not extccomp.ccHasSaneOverflow(conf):
conf.symbols.defineSymbol("nimEmulateOverflowChecks")
setPipeLinePass(graph, NifgenPass)
compilePipelineProject(graph)
proc commandCompileToC(graph: ModuleGraph) =
let conf = graph.config
extccomp.initVars(conf)
@@ -257,7 +273,7 @@ proc mainCommand*(graph: ModuleGraph) =
if conf.exc == excNone: conf.exc = excSetjmp
of backendCpp:
if conf.exc == excNone: conf.exc = excCpp
of backendObjc: discard
of backendObjc, backendNif: discard
of backendJs:
if conf.hcrOn:
# XXX: At the moment, system.nim cannot be compiled in JS mode
@@ -275,6 +291,7 @@ proc mainCommand*(graph: ModuleGraph) =
of backendCpp: commandCompileToC(graph)
of backendObjc: commandCompileToC(graph)
of backendJs: commandCompileToJS(graph)
of backendNif: commandCompileToNif(graph)
of backendInvalid: raiseAssert "unreachable"
template docLikeCmd(body) =

View File

@@ -60,6 +60,7 @@ type
SemPass
JSgenPass
CgenPass
NifgenPass
EvalPass
InterpreterPass
GenDependPass

1668
compiler/nifgen.nim Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -139,6 +139,7 @@ type
backendCpp = "cpp"
backendJs = "js"
backendObjc = "objc"
backendNif = "nif"
# backendNimscript = "nimscript" # this could actually work
# backendLlvm = "llvm" # probably not well supported; was cmdCompileToLLVM
@@ -171,10 +172,11 @@ type
cmdNop
cmdJsonscript # compile a .json build file
# old unused: cmdInterpret, cmdDef: def feature (find definition for IDEs)
cmdCompileToNif
const
cmdBackends* = {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
cmdCompileToJS, cmdCrun}
cmdCompileToJS, cmdCrun, cmdCompileToNif}
cmdDocLike* = {cmdDoc0, cmdDoc, cmdDoc2tex, cmdJsondoc0, cmdJsondoc,
cmdCtags, cmdBuildindex}

View File

@@ -1,7 +1,7 @@
import sem, cgen, modulegraphs, ast, llstream, parser, msgs,
lineinfos, reorder, options, semdata, cgendata, modules, pathutils,
packages, syntaxes, depends, vm, pragmas, idents, lookups, wordrecg,
liftdestructors
liftdestructors, nifgen
import pipelineutils
@@ -23,6 +23,10 @@ proc processPipeline(graph: ModuleGraph; semNode: PNode; bModule: PPassContext):
result = semNode
if bModule != nil:
genTopLevelStmt(BModule(bModule), result)
of NifgenPass:
result = semNode
if bModule != nil:
genTopLevelNif(bModule, result)
of JSgenPass:
when not defined(leanCompiler):
result = processJSCodeGen(bModule, semNode)
@@ -131,6 +135,8 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
nil
of SemPass:
nil
of NifgenPass:
setupNifgen(graph, module, idgen)
of NonePass:
raiseAssert "use setPipeLinePass to set a proper PipelinePass"
@@ -207,6 +213,8 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
of Docgen2JsonPass:
when not defined(leanCompiler):
discard closeJson(graph, bModule, finalNode)
of NifgenPass:
closeNif(graph, bModule, finalNode)
of NonePass:
raiseAssert "use setPipeLinePass to set a proper PipelinePass"

View File

@@ -429,6 +429,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: LayeredIdTable,
addDecl(c, s)
entry.concreteTypes[i] = s.typ
inc i
entry.genericParamsCount = i
c.matchedConcept = nil
pushProcCon(c, result)
instantiateProcType(c, pt, result, info)

View File

@@ -948,6 +948,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
else:
n[i].info
suggestSym(c.graph, info, f, c.graph.usageSym)
# this must only be enabled for cmd == cmdNif as its a minor breaking
# change otherwise :-(
if c.config.cmd == cmdCompileToNif:
n[i] = newSymNode(f)
f.typ = typ
f.position = pos
f.options = c.config.options
@@ -1067,7 +1071,7 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType
if needsForwardUpdate:
# if the inherited object is a forward type,
# the entire object needs to be checked again
c.forwardTypeUpdates.add (result, n) #we retry in the final pass
c.forwardTypeUpdates.add (result, n) # we retry in the final pass
rawAddSon(result, realBase)
if realBase == nil and tfInheritable in flags:
result.flags.incl tfInheritable

View File

@@ -3,6 +3,7 @@ Advanced commands:
//compileToCpp, cpp compile project to C++ code
//compileToOC, objc compile project to Objective C code
//js compile project to Javascript
//nif compile project to NIF
//e run a Nimscript file
//md2html convert a Markdown file to HTML
use `--docCmd:skip` to skip compiling snippets

View File

@@ -16,6 +16,11 @@ const
ChecksumsStableCommit = "f8f6bd34bfa3fe12c64b919059ad856a96efcba0" # 2.0.1
SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01"
NimonyStableCommit = "1dbabac403ae32e185ee4c29f006d04e04b50c6d" # unversioned \
# Note that Nimony uses Nim as a git submodule but we don't want to install
# Nimony's dependency to Nim as we are Nim. So a `git clone` without --recursive
# is **required** here.
# examples of possible values for fusion: #head, #ea82b54, 1.2.3
FusionStableHash = "#562467452b32cb7a97410ea177f083e6d8405734"
HeadHash = "#head"
@@ -177,8 +182,11 @@ proc bundleAtlasExe(latest: bool, args: string) =
options = "-d:release --noNimblePath -d:nimAtlasBootstrap " & args)
proc bundleChecksums(latest: bool) =
let commit = if latest: "HEAD" else: ChecksumsStableCommit
cloneDependency(distDir, "https://github.com/nim-lang/checksums.git", commit, allowBundled = true)
let checksumsCommit = if latest: "HEAD" else: ChecksumsStableCommit
cloneDependency(distDir, "https://github.com/nim-lang/checksums.git", checksumsCommit, allowBundled = true)
let nimonyCommit = if latest: "HEAD" else: NimonyStableCommit
cloneDependency(distDir, "https://github.com/nim-lang/nimony.git", nimonyCommit, allowBundled = true)
proc bundleNimsuggest(args: string) =
bundleChecksums(false)