diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index b7a9ac1180d70..d6ccbc6c7fd22 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1144,7 +1144,7 @@ proc genRestoreFrameAfterException(p: BProc) = if hasCurFramePointer notin p.flags: p.flags.incl hasCurFramePointer p.procSec(cpsLocals).add('\t') - p.procSec(cpsLocals).addVar(kind = Local, name = cSymbol("_nimCurFrame"), typ = ptrType(cSymbol("TFrame"))) + p.procSec(cpsLocals).addVar(kind = Local, name = cSymbol("_nimCurFrame"), typ = ptrType(getTFrame(p.module))) p.procSec(cpsInit).add('\t') p.procSec(cpsInit).addAssignmentWithValue(cSymbol("_nimCurFrame")): p.procSec(cpsInit).addCall(cgsymValue(p.module, "getFrame")) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index cca52a6a26ac4..736abe24463fd 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -171,9 +171,10 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope = headerBuilder.addParam(paramBuilder, name = "op", typ = NimInt) let header = extract(headerBuilder) - m.s[cfsProcHeaders].addDeclWithVisibility(StaticProc): - m.s[cfsProcHeaders].add(header) - m.s[cfsProcHeaders].finishProcHeaderAsProto() + when not buildNifc: + m.s[cfsProcHeaders].addDeclWithVisibility(StaticProc): + m.s[cfsProcHeaders].add(header) + m.s[cfsProcHeaders].finishProcHeaderAsProto() m.s[cfsProcs].addDeclWithVisibility(StaticProc): m.s[cfsProcs].add(header) m.s[cfsProcs].finishProcHeaderWithBody(): @@ -221,9 +222,10 @@ proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope = discard let header = extract(headerBuilder) - m.s[cfsProcHeaders].addDeclWithVisibility(StaticProc): - m.s[cfsProcHeaders].add(header) - m.s[cfsProcHeaders].finishProcHeaderAsProto() + when not buildNifc: + m.s[cfsProcHeaders].addDeclWithVisibility(StaticProc): + m.s[cfsProcHeaders].add(header) + m.s[cfsProcHeaders].finishProcHeaderAsProto() m.s[cfsProcs].addDeclWithVisibility(StaticProc): m.s[cfsProcs].add(header) m.s[cfsProcs].finishProcHeaderWithBody(): diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 0a88c38284cfb..0994a1a3ea7fb 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -396,7 +396,7 @@ proc dataFieldAccessor(p: BProc, sym: Rope): Rope = proc dataField(p: BProc, val: Rope): Rope {.inline.} = result = derefField(dataFieldAccessor(p, val), "data") -proc genProcPrototype(m: BModule, sym: PSym) +proc genProcPrototype(m: BModule, sym: PSym, thisModule: bool = true) include ccgliterals include ccgtypes @@ -823,6 +823,21 @@ proc initLocExprSingleUse(p: BProc, e: PNode): TLoc = result.flags.incl lfSingleUse expr(p, e, result) +proc getProgramResult(m: BModule): Snippet = + if sfSystemModule in m.module.flags: + cSymbol("nim_program_result") + else: + cgsymValue(m, "programResult") + +proc getTFrame(m: BModule): Snippet = + when buildNifc: + if sfSystemModule in m.module.flags: + cSymbol("TFrame") + else: + cgsymValue(m, "TFrame") + else: + cSymbol("TFrame") + include ccgcalls, "ccgstmts.nim" proc initFrame(p: BProc, procname, filename: Rope): Rope = @@ -845,7 +860,7 @@ proc initFrame(p: BProc, procname, filename: Rope): Rope = cgsym(p.module, "nimFrame") when buildNifc: var res = newBuilder("") - res.addVar(name = cSymbol("FR_"), typ = cSymbol("TFrame")) + res.addVar(name = cSymbol("FR_"), typ = getTFrame(p.module)) res.addFieldAssignment(cSymbol("FR_"), "procname", procname) res.addFieldAssignment(cSymbol("FR_"), "filename", filename) res.addFieldAssignment(cSymbol("FR_"), "line", cIntValue(0)) @@ -857,7 +872,7 @@ proc initFrame(p: BProc, procname, filename: Rope): Rope = proc initFrameNoDebug(p: BProc; frame, procname, filename: Snippet; line: int): Snippet = cgsym(p.module, "nimFrame") - p.blocks[0].sections[cpsLocals].addVar(name = frame, typ = cSymbol("TFrame")) + p.blocks[0].sections[cpsLocals].addVar(name = frame, typ = getTFrame(p.module)) var res = newBuilder("") res.add('\t') res.addFieldAssignment(frame, "procname", procname) @@ -1422,7 +1437,7 @@ proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} = sym.magic == mNone and m.config.backend == backendCpp) -proc genProcPrototype(m: BModule, sym: PSym) = +proc genProcPrototype(m: BModule, sym: PSym, thisModule: bool = true) = useHeader(m, sym) if lfNoDecl in sym.loc.flags or sfCppMember * sym.flags != {}: return if lfDynamicLib in sym.loc.flags: @@ -1455,12 +1470,15 @@ proc genProcPrototype(m: BModule, sym: PSym) = let extraVis = if sym.typ.callConv != ccInline and requiresExternC(m, sym): ExternC + elif not thisModule and visibility notin {ImportLib, ExportLib}: + Extern else: None - m.s[cfsProcHeaders].addDeclWithVisibility(extraVis): - m.s[cfsProcHeaders].addDeclWithVisibility(visibility): - m.s[cfsProcHeaders].add(extract(header)) - m.s[cfsProcHeaders].finishProcHeaderAsProto() + if not buildNifc or {visibility, extraVis} * {Extern, ExternC, ImportLib} != {}: + m.s[cfsProcHeaders].addDeclWithVisibility(extraVis): + m.s[cfsProcHeaders].addDeclWithVisibility(visibility): + m.s[cfsProcHeaders].add(extract(header)) + m.s[cfsProcHeaders].finishProcHeaderAsProto() # TODO: figure out how to rename this - it DOES generate a forward declaration proc genProcNoForward(m: BModule, prc: PSym) = @@ -1476,7 +1494,7 @@ proc genProcNoForward(m: BModule, prc: PSym) = elif lfDynamicLib in prc.loc.flags: var q = findPendingModule(m, prc) fillProcLoc(q, prc.ast[namePos]) - genProcPrototype(m, prc) + genProcPrototype(m, prc, q.module.id == m.module.id) if q != nil and not containsOrIncl(q.declaredThings, prc.id): symInDynamicLib(q, prc) # register the procedure even though it is in a different dynamic library and will not be @@ -1524,7 +1542,7 @@ proc genProcNoForward(m: BModule, prc: PSym) = cCall("hcrGetProc", getModuleDllPath(m, prc), '"' & prc.loc.snippet & '"'))) - genProcPrototype(m, prc) + genProcPrototype(m, prc, q.module.id == m.module.id) if q != nil and not containsOrIncl(q.declaredThings, prc.id): # make sure there is a "prototype" in the external module # which will actually become a function pointer @@ -1700,7 +1718,7 @@ proc genMainProcs(m: BModule) = proc genMainProcsWithResult(m: BModule) = genMainProcs(m) - var res = cSymbol("nim_program_result") + var res = getProgramResult(m) if m.hcrOn: res = cDeref(res) m.s[cfsProcs].addReturn(res) @@ -1908,12 +1926,14 @@ proc registerInitProcs*(g: BModuleList; m: PSym; flags: set[ModuleBackendFlag]) ## Called from the IC backend. if HasDatInitProc in flags: let datInit = getSomeNameForModule(g.config, g.config.toFullPath(m.info.fileIndex).AbsoluteFile) & "DatInit000" - g.mainModProcs.addDeclWithVisibility(Private): + let vis = when buildNifc: Extern else: Private + g.mainModProcs.addDeclWithVisibility(vis): g.mainModProcs.addProcHeader(ccNimCall, datInit, CVoid, cProcParams()) g.mainModProcs.finishProcHeaderAsProto() g.mainDatInit.addCallStmt(datInit) if HasModuleInitProc in flags: let init = getSomeNameForModule(g.config, g.config.toFullPath(m.info.fileIndex).AbsoluteFile) & "Init000" + let vis = when buildNifc: Extern else: Private g.mainModProcs.addDeclWithVisibility(Private): g.mainModProcs.addProcHeader(ccNimCall, init, CVoid, cProcParams()) g.mainModProcs.finishProcHeaderAsProto() @@ -1979,24 +1999,25 @@ proc registerModuleToMain(g: BModuleList; m: BModule) = g.mainModProcs.add(extract(hcrModuleMeta)) g.mainModProcs.addDeclWithVisibility(StaticProc): g.mainModProcs.addVar(name = "hcr_handle", typ = CPointer) - g.mainModProcs.addDeclWithVisibility(ExportLib): - g.mainModProcs.addProcHeader(ccNimCall, init, CVoid, cProcParams()) - g.mainModProcs.finishProcHeaderAsProto() - g.mainModProcs.addDeclWithVisibility(ExportLib): - g.mainModProcs.addProcHeader(ccNimCall, datInit, CVoid, cProcParams()) - g.mainModProcs.finishProcHeaderAsProto() - g.mainModProcs.addDeclWithVisibility(ExportLib): - g.mainModProcs.addProcHeaderWithParams(ccNimCall, m.getHcrInitName, CVoid): - var hcrInitParams: ProcParamBuilder - g.mainModProcs.addProcParams(hcrInitParams): - g.mainModProcs.addUnnamedParam(hcrInitParams, CPointer) - g.mainModProcs.addProcTypedParam(hcrInitParams, ccNimCall, "getProcAddr", CPointer, cProcParams( - (name: "", typ: CPointer), - (name: "", typ: ptrType(CChar)))) - g.mainModProcs.finishProcHeaderAsProto() - g.mainModProcs.addDeclWithVisibility(ExportLib): - g.mainModProcs.addProcHeader(ccNimCall, "HcrCreateTypeInfos", CVoid, cProcParams()) - g.mainModProcs.finishProcHeaderAsProto() + when not buildNifc: + g.mainModProcs.addDeclWithVisibility(ExportLib): + g.mainModProcs.addProcHeader(ccNimCall, init, CVoid, cProcParams()) + g.mainModProcs.finishProcHeaderAsProto() + g.mainModProcs.addDeclWithVisibility(ExportLib): + g.mainModProcs.addProcHeader(ccNimCall, datInit, CVoid, cProcParams()) + g.mainModProcs.finishProcHeaderAsProto() + g.mainModProcs.addDeclWithVisibility(ExportLib): + g.mainModProcs.addProcHeaderWithParams(ccNimCall, m.getHcrInitName, CVoid): + var hcrInitParams: ProcParamBuilder + g.mainModProcs.addProcParams(hcrInitParams): + g.mainModProcs.addUnnamedParam(hcrInitParams, CPointer) + g.mainModProcs.addProcTypedParam(hcrInitParams, ccNimCall, "getProcAddr", CPointer, cProcParams( + (name: "", typ: CPointer), + (name: "", typ: ptrType(CChar)))) + g.mainModProcs.finishProcHeaderAsProto() + g.mainModProcs.addDeclWithVisibility(ExportLib): + g.mainModProcs.addProcHeader(ccNimCall, "HcrCreateTypeInfos", CVoid, cProcParams()) + g.mainModProcs.finishProcHeaderAsProto() g.mainModInit.addCallStmt(init) g.otherModsInit.addCallStmt("hcrInit", cCast(ptrType(CPointer), "hcr_module_list"), @@ -2039,7 +2060,8 @@ proc registerModuleToMain(g: BModuleList; m: BModule) = return if m.s[cfsDatInitProc].buf.len > 0: - g.mainModProcs.addDeclWithVisibility(Private): + let vis = when buildNifc: Extern else: Private + g.mainModProcs.addDeclWithVisibility(Extern): g.mainModProcs.addProcHeader(ccNimCall, datInit, CVoid, cProcParams()) g.mainModProcs.finishProcHeaderAsProto() g.mainDatInit.addCallStmt(datInit) @@ -2054,7 +2076,8 @@ proc registerModuleToMain(g: BModuleList; m: BModule) = cCast(CPointer, cAddr("inner"))) if m.s[cfsInitProc].buf.len > 0: - g.mainModProcs.addDeclWithVisibility(Private): + let vis = when buildNifc: Extern else: Private + g.mainModProcs.addDeclWithVisibility(vis): g.mainModProcs.addProcHeader(ccNimCall, init, CVoid, cProcParams()) g.mainModProcs.finishProcHeaderAsProto() if sfMainModule in m.module.flags: @@ -2162,7 +2185,7 @@ proc genInitCode(m: BModule) = # Give this small function its own scope prcBody.addScope(): # Keep a bogus frame in case the code needs one - prcBody.addVar(name = cSymbol("FR_"), typ = cSymbol("TFrame")) + prcBody.addVar(name = cSymbol("FR_"), typ = getTFrame(m)) prcBody.addFieldAssignment(cSymbol("FR_"), "len", cIntValue(0)) writeSection(preInitProc, cpsLocals) @@ -2188,7 +2211,7 @@ proc genInitCode(m: BModule) = var procname = makeCString(m.module.name.s) prcBody.add(initFrame(m.initProc, procname, quotedFilename(m.config, m.module.info))) else: - prcBody.addVar(name = cSymbol("FR_"), typ = cSymbol("TFrame")) + prcBody.addVar(name = cSymbol("FR_"), typ = getTFrame(m)) prcBody.addFieldAssignment(cSymbol("FR_"), "len", cIntValue(0)) writeSection(initProc, cpsInit, m.hcrOn) diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 700ee88ca8b9d..fbee137b71752 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -174,4 +174,4 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasLegacyNoStrictDefs") when defined(nimCompileToNifc): - defineSymbol("nifc") + defineSymbol("nimNifc") diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 3a0e3daa4d730..10294456b0a62 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -1024,7 +1024,36 @@ proc callCCompiler*(conf: ConfigRef) = generateScript(conf, script) proc callNifc*(conf: ConfigRef) = - discard + var exe = getConfigVar(conf, ccNifc, ".exe") + if exe.len == 0: exe = getCompilerExe(conf, ccNifc, false) + if needsExeExt(conf): exe = addFileExt(exe, "exe") + + var cmd = @[exe, "c"] + cmd.add("--nifcache:" & conf.getNimcacheDir().string) + cmd.add("--cc:" & CC[conf.cCompiler].name) + cmd.add("--out:" & conf.absOutFile.string) + let opts = conf.options * {optOptimizeSpeed, optOptimizeSize} + if opts == {optOptimizeSpeed}: + cmd.add("--opt:speed") + elif opts == {optOptimizeSize}: + cmd.add("--opt:size") + if optLineDir in conf.options: + cmd.add("--linedir:on") + for idx, it in conf.toCompile: + let cf = if noAbsolutePaths(conf): extractFilename(it.cname.string) + else: it.cname.string + cmd.add(cf) + execExternalProgram(conf, quoteShellCommand(cmd), hintExecuting) + + if optCompileOnly in conf.globalOptions: return + let appName = splitFile(conf.toCompile[^1].cname).name + when defined(windows): + let makefilePath = conf.getNimcacheDir().string / "Makefile." & appName & ".bat" + let makeCmd = expandFilename(makefilePath) + else: + let makefilePath = s.config.nifcacheDir / "Makefile." & appName + let makeCmd = "make -f " & makefilePath + execExternalProgram(conf, makeCmd, hintExecuting) template hashNimExe(): string = $secureHashFile(os.getAppFilename()) diff --git a/lib/system.nim b/lib/system.nim index a213a168396ff..15e59c826f85a 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -511,6 +511,63 @@ type ## Each effect should inherit from `RootEffect` unless you know what ## you're doing. +type + Endianness* = enum ## Type describing the endianness of a processor. + littleEndian, bigEndian + +const + cpuEndian* {.magic: "CpuEndian".}: Endianness = littleEndian + ## The endianness of the target CPU. This is a valuable piece of + ## information for low-level code only. This works thanks to compiler + ## magic. + + hostOS* {.magic: "HostOS".}: string = "" + ## A string that describes the host operating system. + ## + ## Possible values: + ## `"windows"`, `"macosx"`, `"linux"`, `"netbsd"`, `"freebsd"`, + ## `"openbsd"`, `"solaris"`, `"aix"`, `"haiku"`, `"standalone"`. + + hostCPU* {.magic: "HostCPU".}: string = "" + ## A string that describes the host CPU. + ## + ## Possible values: + ## `"i386"`, `"alpha"`, `"powerpc"`, `"powerpc64"`, `"powerpc64el"`, + ## `"sparc"`, `"amd64"`, `"mips"`, `"mipsel"`, `"arm"`, `"arm64"`, + ## `"mips64"`, `"mips64el"`, `"riscv32"`, `"riscv64"`, `"loongarch64"`. + +const + QuitSuccess* = 0 + ## is the value that should be passed to `quit <#quit,int>`_ to indicate + ## success. + + QuitFailure* = 1 + ## is the value that should be passed to `quit <#quit,int>`_ to indicate + ## failure. + +when not defined(js) and hostOS != "standalone": + var programResult* {.compilerproc, exportc: "nim_program_result".}: int + ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`. + +when defined(nimNifc): + {.pragma: tframe, compilerproc.} +else: + {.pragma: tframe, importc, nodecl.} + +type + PFrame* = ptr TFrame ## Represents a runtime frame of the call stack; + ## part of the debugger API. + # keep in sync with nimbase.h `struct TFrame_` + TFrame* {.tframe, final.} = object ## The frame itself. + prev*: PFrame ## Previous frame; used for chaining the call stack. + procname*: cstring ## Name of the proc that is currently executing. + line*: int ## Line number of the proc that is currently executing. + filename*: cstring ## Filename of the proc that is currently executing. + len*: int16 ## Length of the inspectable slots. + calldepth*: int16 ## Used for max call depth checking. + when NimStackTraceMsgs: + frameMsgLen*: int ## end position in frameMsgBuf for this frame. + type StackTraceEntry* = object ## In debug mode exceptions store the stack trace that led ## to them. A `StackTraceEntry` is a single entry of the @@ -1032,37 +1089,12 @@ proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} = tmp.add("cd") assert tmp == "abcd" -type - Endianness* = enum ## Type describing the endianness of a processor. - littleEndian, bigEndian - const - cpuEndian* {.magic: "CpuEndian".}: Endianness = littleEndian - ## The endianness of the target CPU. This is a valuable piece of - ## information for low-level code only. This works thanks to compiler - ## magic. - - hostOS* {.magic: "HostOS".}: string = "" - ## A string that describes the host operating system. - ## - ## Possible values: - ## `"windows"`, `"macosx"`, `"linux"`, `"netbsd"`, `"freebsd"`, - ## `"openbsd"`, `"solaris"`, `"aix"`, `"haiku"`, `"standalone"`. - - hostCPU* {.magic: "HostCPU".}: string = "" - ## A string that describes the host CPU. - ## - ## Possible values: - ## `"i386"`, `"alpha"`, `"powerpc"`, `"powerpc64"`, `"powerpc64el"`, - ## `"sparc"`, `"amd64"`, `"mips"`, `"mipsel"`, `"arm"`, `"arm64"`, - ## `"mips64"`, `"mips64el"`, `"riscv32"`, `"riscv64"`, `"loongarch64"`. - seqShallowFlag = low(int) strlitFlag = 1 shl (sizeof(int)*8 - 2) # later versions of the codegen \ # emit this flag # for string literals, it allows for some optimizations. -const hasThreadSupport = compileOption("threads") and not defined(nimscript) hasSharedHeap = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own @@ -1101,19 +1133,6 @@ when hasThreadSupport: else: {.pragma: rtlThreadVar.} -const - QuitSuccess* = 0 - ## is the value that should be passed to `quit <#quit,int>`_ to indicate - ## success. - - QuitFailure* = 1 - ## is the value that should be passed to `quit <#quit,int>`_ to indicate - ## failure. - -when not defined(js) and hostOS != "standalone": - var programResult* {.compilerproc, exportc: "nim_program_result".}: int - ## deprecated, prefer `quit` or `exitprocs.getProgramResult`, `exitprocs.setProgramResult`. - import std/private/since import system/ctypes export ctypes @@ -1720,25 +1739,6 @@ when not defined(nimscript): when not declared(sysFatal): include "system/fatal" -when defined(nifc): - {.pragma: tframe, compilerproc.} -else: - {.pragma: tframe, importc, nodecl.} - -type - PFrame* = ptr TFrame ## Represents a runtime frame of the call stack; - ## part of the debugger API. - # keep in sync with nimbase.h `struct TFrame_` - TFrame* {.tframe, final.} = object ## The frame itself. - prev*: PFrame ## Previous frame; used for chaining the call stack. - procname*: cstring ## Name of the proc that is currently executing. - line*: int ## Line number of the proc that is currently executing. - filename*: cstring ## Filename of the proc that is currently executing. - len*: int16 ## Length of the inspectable slots. - calldepth*: int16 ## Used for max call depth checking. - when NimStackTraceMsgs: - frameMsgLen*: int ## end position in frameMsgBuf for this frame. - when defined(nimV2): var framePtr {.threadvar.}: PFrame diff --git a/tests/a.nim b/tests/a.nim new file mode 100644 index 0000000000000..b1e4199f1cd69 --- /dev/null +++ b/tests/a.nim @@ -0,0 +1 @@ +echo "hello world"