|
|
|
|
@@ -820,6 +820,7 @@ proc initLocExprSingleUse(p: BProc, e: PNode): TLoc =
|
|
|
|
|
include ccgcalls, "ccgstmts.nim"
|
|
|
|
|
|
|
|
|
|
proc initFrame(p: BProc, procname, filename: Rope): Rope =
|
|
|
|
|
# XXX cbuilder
|
|
|
|
|
const frameDefines = """
|
|
|
|
|
$1define nimfr_(proc, file) \
|
|
|
|
|
TFrame FR_; \
|
|
|
|
|
@@ -1636,16 +1637,174 @@ proc getInitName(m: BModule): Rope =
|
|
|
|
|
proc getDatInitName(m: BModule): Rope = getSomeInitName(m, "DatInit000")
|
|
|
|
|
proc getHcrInitName(m: BModule): Rope = getSomeInitName(m, "HcrInit000")
|
|
|
|
|
|
|
|
|
|
proc hcrGetProcLoadCode(m: BModule, sym, prefix, handle, getProcFunc: string): Rope
|
|
|
|
|
proc hcrGetProcLoadCode(builder: var Builder, m: BModule, sym, prefix, handle, getProcFunc: string)
|
|
|
|
|
|
|
|
|
|
# The use of a volatile function pointer to call Pre/NimMainInner
|
|
|
|
|
# prevents inlining of the NimMainInner function and dependent
|
|
|
|
|
# functions, which might otherwise merge their stack frames.
|
|
|
|
|
proc isInnerMainVolatile(m: BModule): bool =
|
|
|
|
|
m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}
|
|
|
|
|
|
|
|
|
|
proc genPreMain(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addProcHeader(m.config.nimMainPrefix & "PreMainInner", "void", cProcParams())
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsProcs].add(extract(m.g.otherModsInit))
|
|
|
|
|
if optNoMain notin m.config.globalOptions:
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addVar(name = "cmdCount", typ = "int")
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addVar(name = "cmdLine", typ = ptrType(ptrType("char")))
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addVar(name = "gEnv", typ = ptrType(ptrType("char")))
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addProcHeader(m.config.nimMainPrefix & "PreMain", "void", cProcParams())
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
if isInnerMainVolatile(m):
|
|
|
|
|
m.s[cfsProcs].addProcVar(name = "inner", rettype = "void", params = cProcParams(), isVolatile = true)
|
|
|
|
|
m.s[cfsProcs].addAssignment("inner", m.config.nimMainPrefix & "PreMainInner")
|
|
|
|
|
m.s[cfsProcs].add(extract(m.g.mainDatInit))
|
|
|
|
|
m.s[cfsProcs].addCallStmt(cDeref("inner"))
|
|
|
|
|
else:
|
|
|
|
|
# not volatile
|
|
|
|
|
m.s[cfsProcs].add(extract(m.g.mainDatInit))
|
|
|
|
|
m.s[cfsProcs].addCallStmt(m.config.nimMainPrefix & "PreMainInner")
|
|
|
|
|
|
|
|
|
|
proc genMainProcs(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addCallStmt(m.config.nimMainPrefix & "NimMain")
|
|
|
|
|
|
|
|
|
|
proc genMainProcsWithResult(m: BModule) =
|
|
|
|
|
genMainProcs(m)
|
|
|
|
|
var res = "nim_program_result"
|
|
|
|
|
if m.hcrOn: res = cDeref(res)
|
|
|
|
|
m.s[cfsProcs].addReturn(res)
|
|
|
|
|
|
|
|
|
|
proc genNimMainInner(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Private):
|
|
|
|
|
m.s[cfsProcs].addProcHeader(ccCDecl, m.config.nimMainPrefix & "NimMainInner", "void", cProcParams())
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsProcs].add(extract(m.g.mainModInit))
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc initStackBottom(m: BModule): bool =
|
|
|
|
|
not (m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcAtomicArc, gcOrc})
|
|
|
|
|
|
|
|
|
|
proc genNimMainProc(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
m.s[cfsProcs].addProcHeader(ccCDecl, m.config.nimMainPrefix & "NimMain", "void", cProcParams())
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
if isInnerMainVolatile(m):
|
|
|
|
|
m.s[cfsProcs].addProcVar(name = "inner", rettype = "void", params = cProcParams(), isVolatile = true)
|
|
|
|
|
m.s[cfsProcs].add(preMainCode)
|
|
|
|
|
m.s[cfsProcs].addAssignment("inner", m.config.nimMainPrefix & "NimMainInner")
|
|
|
|
|
if initStackBottom(m):
|
|
|
|
|
m.s[cfsProcs].addCallStmt("initStackBottomWith", cCast("void*", cAddr("inner")))
|
|
|
|
|
m.s[cfsProcs].addCallStmt(cDeref("inner"))
|
|
|
|
|
else:
|
|
|
|
|
# not volatile
|
|
|
|
|
m.s[cfsProcs].add(preMainCode)
|
|
|
|
|
if initStackBottom(m):
|
|
|
|
|
m.s[cfsProcs].addCallStmt("initStackBottomWith", cCast("void*", cAddr("inner")))
|
|
|
|
|
m.s[cfsProcs].addCallStmt(m.config.nimMainPrefix & "NimMainInner")
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genNimMainBody(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
genNimMainInner(m)
|
|
|
|
|
genNimMainProc(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
proc genPosixCMain(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addProcHeader("main", "int", cProcParams(
|
|
|
|
|
(name: "argc", typ: "int"),
|
|
|
|
|
(name: "args", typ: ptrType(ptrType("char"))),
|
|
|
|
|
(name: "env", typ: ptrType(ptrType("char")))))
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsProcs].addAssignment("cmdLine", "args")
|
|
|
|
|
m.s[cfsProcs].addAssignment("cmdCount", "argc")
|
|
|
|
|
m.s[cfsProcs].addAssignment("gEnv", "env")
|
|
|
|
|
genMainProcsWithResult(m)
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genStandaloneCMain(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addProcHeader("main", "int", cProcParams())
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
genMainProcs(m)
|
|
|
|
|
m.s[cfsProcs].addReturn(cIntValue(0))
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genWinNimMain(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
genNimMainBody(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
proc genWinCMain(m: BModule) =
|
|
|
|
|
m.s[cfsProcs].addProcHeader(ccStdCall, "WinMain", "int", cProcParams(
|
|
|
|
|
(name: "hCurInstance", typ: "HINSTANCE"),
|
|
|
|
|
(name: "hPrevInstance", typ: "HINSTANCE"),
|
|
|
|
|
(name: "lpCmdLine", typ: "LPSTR"),
|
|
|
|
|
(name: "nCmdShow", typ: "int")))
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
genMainProcsWithResult(m)
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genWinNimDllMain(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
genNimMainInner(m)
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(ExportLib):
|
|
|
|
|
genNimMainProc(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
proc genWinCDllMain(m: BModule) =
|
|
|
|
|
# used to use WINAPI macro, now ccStdCall:
|
|
|
|
|
m.s[cfsProcs].addProcHeader(ccStdCall, "DllMain", "BOOL", cProcParams(
|
|
|
|
|
(name: "hinstDLL", typ: "HINSTANCE"),
|
|
|
|
|
(name: "fwdreason", typ: "DWORD"),
|
|
|
|
|
(name: "lpvReserved", typ: "LPVOID")))
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsProcs].addSingleIfStmt(removeSinglePar(cOp(Equal, "fwdreason", "DLL_PROCESS_ATTACH"))):
|
|
|
|
|
genMainProcs(m)
|
|
|
|
|
m.s[cfsProcs].addReturn(cIntValue(1))
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genPosixNimDllMain(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
genWinNimDllMain(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
proc genPosixCDllMain(m: BModule) =
|
|
|
|
|
# used to use NIM_POSIX_INIT, now uses direct constructor attribute
|
|
|
|
|
m.s[cfsProcs].addProcHeader("NimMainInit", "void", cProcParams(), isConstructor = true)
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
genMainProcs(m)
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genGenodeNimMain(m: BModule, preMainCode: Snippet) =
|
|
|
|
|
let typName = "Genode::Env"
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(Extern):
|
|
|
|
|
m.s[cfsProcs].addVar(name = "nim_runtime_env", typ = ptrType(typName))
|
|
|
|
|
m.s[cfsProcs].addDeclWithVisibility(ExternC):
|
|
|
|
|
m.s[cfsProcs].addProcHeader("nim_component_construct", "void", cProcParams((name: "", typ: ptrType(typName))))
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderAsProto()
|
|
|
|
|
genNimMainBody(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
proc genComponentConstruct(m: BModule) =
|
|
|
|
|
let fnName = "Libc::Component::construct"
|
|
|
|
|
let typName = "Libc::Env"
|
|
|
|
|
m.s[cfsProcs].addProcHeader(fnName, "void", cProcParams((name: "env", typ: cppRefType(typName))))
|
|
|
|
|
m.s[cfsProcs].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsProcs].addLineComment("Set Env used during runtime initialization")
|
|
|
|
|
m.s[cfsProcs].addAssignment("nim_runtime_env", cAddr("env"))
|
|
|
|
|
let callFn = "Libc::with_libc"
|
|
|
|
|
var call: CallBuilder
|
|
|
|
|
m.s[cfsProcs].addStmt():
|
|
|
|
|
m.s[cfsProcs].addCall(call, callFn):
|
|
|
|
|
m.s[cfsProcs].addArgument(call):
|
|
|
|
|
m.s[cfsProcs].addCppLambda(ByReference, cProcParams()):
|
|
|
|
|
m.s[cfsProcs].addLineComment("Initialize runtime and globals")
|
|
|
|
|
genMainProcs(m)
|
|
|
|
|
m.s[cfsProcs].addLineComment("Call application construct")
|
|
|
|
|
m.s[cfsProcs].addCallStmt("nim_component_construct", cAddr("env"))
|
|
|
|
|
m.s[cfsProcs].addNewline()
|
|
|
|
|
|
|
|
|
|
proc genMainProc(m: BModule) =
|
|
|
|
|
## this function is called in cgenWriteModules after all modules are closed,
|
|
|
|
|
## it means raising dependency on the symbols is too late as it will not propagate
|
|
|
|
|
## into other modules, only simple rope manipulations are allowed
|
|
|
|
|
var preMainCode: Rope = ""
|
|
|
|
|
var preMainBuilder = newBuilder("")
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
proc loadLib(handle: string, name: string): Rope =
|
|
|
|
|
result = ""
|
|
|
|
|
proc loadLib(builder: var Builder, handle: string, name: string) =
|
|
|
|
|
let prc = magicsys.getCompilerProc(m.g.graph, name)
|
|
|
|
|
assert prc != nil
|
|
|
|
|
let n = newStrNode(nkStrLit, prc.annex.path.strVal)
|
|
|
|
|
@@ -1653,130 +1812,23 @@ proc genMainProc(m: BModule) =
|
|
|
|
|
var strLitBuilder = newBuilder("")
|
|
|
|
|
genStringLiteral(m, n, strLitBuilder)
|
|
|
|
|
let strLit = extract(strLitBuilder)
|
|
|
|
|
appcg(m, result, "\tif (!($1 = #nimLoadLibrary($2)))$N" &
|
|
|
|
|
"\t\t#nimLoadLibraryError($2);$N",
|
|
|
|
|
[handle, strLit])
|
|
|
|
|
builder.addAssignment(handle, cCall(cgsymValue(m, "nimLoadLibrary"), strLit))
|
|
|
|
|
builder.addSingleIfStmt(cOp(Not, handle)):
|
|
|
|
|
builder.addCallStmt(cgsymValue(m, "nimLoadLibraryError"), strLit)
|
|
|
|
|
|
|
|
|
|
preMainCode.add(loadLib("hcr_handle", "hcrGetProc"))
|
|
|
|
|
loadLib(preMainBuilder, "hcr_handle", "hcrGetProc")
|
|
|
|
|
if m.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}:
|
|
|
|
|
preMainCode.add("\t$1PreMain();\L" % [rope m.config.nimMainPrefix])
|
|
|
|
|
preMainBuilder.addCallStmt(m.config.nimMainPrefix & "PreMain")
|
|
|
|
|
else:
|
|
|
|
|
preMainCode.add("\tvoid* rtl_handle;\L")
|
|
|
|
|
preMainCode.add(loadLib("rtl_handle", "nimGC_setStackBottom"))
|
|
|
|
|
preMainCode.add(hcrGetProcLoadCode(m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr"))
|
|
|
|
|
preMainCode.add("\tinner = $1PreMain;\L" % [rope m.config.nimMainPrefix])
|
|
|
|
|
preMainCode.add("\tinitStackBottomWith_actual((void *)&inner);\L")
|
|
|
|
|
preMainCode.add("\t(*inner)();\L")
|
|
|
|
|
preMainBuilder.addVar(name = "rtl_handle", typ = "void*")
|
|
|
|
|
loadLib(preMainBuilder, "rtl_handle", "nimGC_setStackBottom")
|
|
|
|
|
hcrGetProcLoadCode(preMainBuilder, m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr")
|
|
|
|
|
preMainBuilder.addAssignment("inner", m.config.nimMainPrefix & "PreMain")
|
|
|
|
|
preMainBuilder.addCallStmt("initStackBottomWith_actual", cCast("void*", cAddr("inner")))
|
|
|
|
|
preMainBuilder.addCallStmt(cDeref("inner"))
|
|
|
|
|
else:
|
|
|
|
|
preMainCode.add("\t$1PreMain();\L" % [rope m.config.nimMainPrefix])
|
|
|
|
|
|
|
|
|
|
var posixCmdLine: Rope = ""
|
|
|
|
|
if optNoMain notin m.config.globalOptions:
|
|
|
|
|
posixCmdLine.add "N_LIB_PRIVATE int cmdCount;\L"
|
|
|
|
|
posixCmdLine.add "N_LIB_PRIVATE char** cmdLine;\L"
|
|
|
|
|
posixCmdLine.add "N_LIB_PRIVATE char** gEnv;\L"
|
|
|
|
|
|
|
|
|
|
const
|
|
|
|
|
# The use of a volatile function pointer to call Pre/NimMainInner
|
|
|
|
|
# prevents inlining of the NimMainInner function and dependent
|
|
|
|
|
# functions, which might otherwise merge their stack frames.
|
|
|
|
|
|
|
|
|
|
PreMainBody = "$N" &
|
|
|
|
|
"N_LIB_PRIVATE void $3PreMainInner(void) {$N" &
|
|
|
|
|
"$2" &
|
|
|
|
|
"}$N$N" &
|
|
|
|
|
"$4" &
|
|
|
|
|
"N_LIB_PRIVATE void $3PreMain(void) {$N" &
|
|
|
|
|
"##if $5$N" & # 1 for volatile call, 0 for non-volatile
|
|
|
|
|
"\tvoid (*volatile inner)(void);$N" &
|
|
|
|
|
"\tinner = $3PreMainInner;$N" &
|
|
|
|
|
"$1" &
|
|
|
|
|
"\t(*inner)();$N" &
|
|
|
|
|
"##else$N" &
|
|
|
|
|
"$1" &
|
|
|
|
|
"\t$3PreMainInner();$N" &
|
|
|
|
|
"##endif$N" &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
MainProcs =
|
|
|
|
|
"\t$^NimMain();$N"
|
|
|
|
|
|
|
|
|
|
MainProcsWithResult =
|
|
|
|
|
MainProcs & ("\treturn $1nim_program_result;$N")
|
|
|
|
|
|
|
|
|
|
NimMainInner = "N_LIB_PRIVATE N_CDECL(void, $5NimMainInner)(void) {$N" &
|
|
|
|
|
"$1" &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
NimMainProc =
|
|
|
|
|
"N_CDECL(void, $5NimMain)(void) {$N" &
|
|
|
|
|
"##if $6$N" & # 1 for volatile call, 0 for non-volatile
|
|
|
|
|
"\tvoid (*volatile inner)(void);$N" &
|
|
|
|
|
"$4" &
|
|
|
|
|
"\tinner = $5NimMainInner;$N" &
|
|
|
|
|
"$2" &
|
|
|
|
|
"\t(*inner)();$N" &
|
|
|
|
|
"##else$N" &
|
|
|
|
|
"$4" &
|
|
|
|
|
"$2" &
|
|
|
|
|
"\t$5NimMainInner();$N" &
|
|
|
|
|
"##endif$N" &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
NimMainBody = NimMainInner & NimMainProc
|
|
|
|
|
|
|
|
|
|
PosixCMain =
|
|
|
|
|
"int main(int argc, char** args, char** env) {$N" &
|
|
|
|
|
"\tcmdLine = args;$N" &
|
|
|
|
|
"\tcmdCount = argc;$N" &
|
|
|
|
|
"\tgEnv = env;$N" &
|
|
|
|
|
MainProcsWithResult &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
StandaloneCMain =
|
|
|
|
|
"int main(void) {$N" &
|
|
|
|
|
MainProcs &
|
|
|
|
|
"\treturn 0;$N" &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
WinNimMain = NimMainBody
|
|
|
|
|
|
|
|
|
|
WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $N" &
|
|
|
|
|
" HINSTANCE hPrevInstance, $N" &
|
|
|
|
|
" LPSTR lpCmdLine, int nCmdShow) {$N" &
|
|
|
|
|
MainProcsWithResult & "}$N$N"
|
|
|
|
|
|
|
|
|
|
WinNimDllMain = NimMainInner & "N_LIB_EXPORT " & NimMainProc
|
|
|
|
|
|
|
|
|
|
WinCDllMain =
|
|
|
|
|
"BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, $N" &
|
|
|
|
|
" LPVOID lpvReserved) {$N" &
|
|
|
|
|
"\tif (fwdreason == DLL_PROCESS_ATTACH) {$N" & MainProcs & "\t}$N" &
|
|
|
|
|
"\treturn 1;$N}$N$N"
|
|
|
|
|
|
|
|
|
|
PosixNimDllMain = WinNimDllMain
|
|
|
|
|
|
|
|
|
|
PosixCDllMain =
|
|
|
|
|
"N_LIB_PRIVATE void NIM_POSIX_INIT NimMainInit(void) {$N" &
|
|
|
|
|
MainProcs &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
|
|
|
|
|
GenodeNimMain =
|
|
|
|
|
"extern Genode::Env *nim_runtime_env;$N" &
|
|
|
|
|
"extern \"C\" void nim_component_construct(Genode::Env*);$N$N" &
|
|
|
|
|
NimMainBody
|
|
|
|
|
|
|
|
|
|
ComponentConstruct =
|
|
|
|
|
"void Libc::Component::construct(Libc::Env &env) {$N" &
|
|
|
|
|
"\t// Set Env used during runtime initialization$N" &
|
|
|
|
|
"\tnim_runtime_env = &env;$N" &
|
|
|
|
|
"\tLibc::with_libc([&] () {$N\t" &
|
|
|
|
|
"\t// Initialize runtime and globals$N" &
|
|
|
|
|
MainProcs &
|
|
|
|
|
"\t// Call application construct$N" &
|
|
|
|
|
"\t\tnim_component_construct(&env);$N" &
|
|
|
|
|
"\t});$N" &
|
|
|
|
|
"}$N$N"
|
|
|
|
|
preMainBuilder.addCallStmt(m.config.nimMainPrefix & "PreMain")
|
|
|
|
|
let preMainCode = extract(preMainBuilder)
|
|
|
|
|
|
|
|
|
|
if m.config.target.targetOS == osWindows and
|
|
|
|
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
|
|
|
|
@@ -1784,36 +1836,24 @@ proc genMainProc(m: BModule) =
|
|
|
|
|
elif m.config.target.targetOS == osGenode:
|
|
|
|
|
m.includeHeader("<libc/component.h>")
|
|
|
|
|
|
|
|
|
|
let initStackBottomCall =
|
|
|
|
|
if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcAtomicArc, gcOrc}: "".rope
|
|
|
|
|
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", [])
|
|
|
|
|
if initStackBottom(m):
|
|
|
|
|
cgsym(m, "initStackBottomWith")
|
|
|
|
|
inc(m.labels)
|
|
|
|
|
|
|
|
|
|
let isVolatile = if m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}: "1" else: "0"
|
|
|
|
|
appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit, m.config.nimMainPrefix, posixCmdLine, isVolatile])
|
|
|
|
|
genPreMain(m)
|
|
|
|
|
|
|
|
|
|
if m.config.target.targetOS == osWindows and
|
|
|
|
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
|
|
|
|
if optGenGuiApp in m.config.globalOptions:
|
|
|
|
|
const nimMain = WinNimMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], nimMain,
|
|
|
|
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix, isVolatile])
|
|
|
|
|
genWinNimMain(m, preMainCode)
|
|
|
|
|
else:
|
|
|
|
|
const nimMain = WinNimDllMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], nimMain,
|
|
|
|
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix, isVolatile])
|
|
|
|
|
genWinNimDllMain(m, preMainCode)
|
|
|
|
|
elif m.config.target.targetOS == osGenode:
|
|
|
|
|
const nimMain = GenodeNimMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], nimMain,
|
|
|
|
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix, isVolatile])
|
|
|
|
|
genGenodeNimMain(m, preMainCode)
|
|
|
|
|
elif optGenDynLib in m.config.globalOptions:
|
|
|
|
|
const nimMain = PosixNimDllMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], nimMain,
|
|
|
|
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix, isVolatile])
|
|
|
|
|
genPosixNimDllMain(m, preMainCode)
|
|
|
|
|
else:
|
|
|
|
|
const nimMain = NimMainBody
|
|
|
|
|
appcg(m, m.s[cfsProcs], nimMain,
|
|
|
|
|
[m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix, isVolatile])
|
|
|
|
|
genNimMainBody(m, preMainCode)
|
|
|
|
|
|
|
|
|
|
if optNoMain notin m.config.globalOptions:
|
|
|
|
|
if m.config.cppCustomNamespace.len > 0:
|
|
|
|
|
@@ -1823,23 +1863,17 @@ proc genMainProc(m: BModule) =
|
|
|
|
|
if m.config.target.targetOS == osWindows and
|
|
|
|
|
m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}:
|
|
|
|
|
if optGenGuiApp in m.config.globalOptions:
|
|
|
|
|
const otherMain = WinCMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: "", m.config.nimMainPrefix])
|
|
|
|
|
genWinCMain(m)
|
|
|
|
|
else:
|
|
|
|
|
const otherMain = WinCDllMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
|
|
|
|
|
genWinCDllMain(m)
|
|
|
|
|
elif m.config.target.targetOS == osGenode:
|
|
|
|
|
const otherMain = ComponentConstruct
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
|
|
|
|
|
genComponentConstruct(m)
|
|
|
|
|
elif optGenDynLib in m.config.globalOptions:
|
|
|
|
|
const otherMain = PosixCDllMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
|
|
|
|
|
genPosixCDllMain(m)
|
|
|
|
|
elif m.config.target.targetOS == osStandalone:
|
|
|
|
|
const otherMain = StandaloneCMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [m.config.nimMainPrefix])
|
|
|
|
|
genStandaloneCMain(m)
|
|
|
|
|
else:
|
|
|
|
|
const otherMain = PosixCMain
|
|
|
|
|
appcg(m, m.s[cfsProcs], otherMain, [if m.hcrOn: "*" else: "", m.config.nimMainPrefix])
|
|
|
|
|
genPosixCMain(m)
|
|
|
|
|
|
|
|
|
|
if m.config.cppCustomNamespace.len > 0:
|
|
|
|
|
openNamespaceNim(m.config.cppCustomNamespace, m.s[cfsProcs])
|
|
|
|
|
@@ -1848,18 +1882,21 @@ 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.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [datInit])
|
|
|
|
|
g.mainDatInit.addf("\t$1();$N", [datInit])
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(Private):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, datInit, "void", 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"
|
|
|
|
|
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
|
|
|
|
|
let initCall = "\t$1();$N" % [init]
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(Private):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, init, "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
if sfMainModule in m.flags:
|
|
|
|
|
g.mainModInit.add(initCall)
|
|
|
|
|
g.mainModInit.addCallStmt(init)
|
|
|
|
|
elif sfSystemModule in m.flags:
|
|
|
|
|
g.mainDatInit.add(initCall) # systemInit must called right after systemDatInit if any
|
|
|
|
|
g.mainDatInit.addCallStmt(init) # systemInit must called right after systemDatInit if any
|
|
|
|
|
else:
|
|
|
|
|
g.otherModsInit.add(initCall)
|
|
|
|
|
g.otherModsInit.addCallStmt(init)
|
|
|
|
|
|
|
|
|
|
proc whichInitProcs*(m: BModule): set[ModuleBackendFlag] =
|
|
|
|
|
# called from IC.
|
|
|
|
|
@@ -1877,31 +1914,68 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
|
|
|
|
datInit = m.getDatInitName
|
|
|
|
|
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
var hcrModuleMeta = "$nN_LIB_PRIVATE const char* hcr_module_list[] = {$n" % []
|
|
|
|
|
var hcrModuleMeta = newBuilder("")
|
|
|
|
|
let systemModulePath = getModuleDllPath(m, g.modules[g.graph.config.m.systemFileIdx.int].module)
|
|
|
|
|
let mainModulePath = getModuleDllPath(m, m.module)
|
|
|
|
|
hcrModuleMeta.addDeclWithVisibility(Private):
|
|
|
|
|
hcrModuleMeta.addArrayVarWithInitializer(kind = Local,
|
|
|
|
|
name = "hcr_module_list",
|
|
|
|
|
elementType = ptrConstType("char"),
|
|
|
|
|
len = g.graph.importDeps.getOrDefault(FileIndex(m.module.position)).len +
|
|
|
|
|
ord(sfMainModule in m.module.flags) +
|
|
|
|
|
1):
|
|
|
|
|
var modules: StructInitializer
|
|
|
|
|
hcrModuleMeta.addStructInitializer(modules, siArray):
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
hcrModuleMeta.addField(modules, ""):
|
|
|
|
|
hcrModuleMeta.add(systemModulePath)
|
|
|
|
|
g.graph.importDeps.withValue(FileIndex(m.module.position), deps):
|
|
|
|
|
for curr in deps[]:
|
|
|
|
|
hcrModuleMeta.addField(modules, ""):
|
|
|
|
|
hcrModuleMeta.add(getModuleDllPath(m, g.modules[curr.int].module))
|
|
|
|
|
hcrModuleMeta.addField(modules, ""):
|
|
|
|
|
hcrModuleMeta.add("\"\"")
|
|
|
|
|
hcrModuleMeta.addDeclWithVisibility(ExportLib):
|
|
|
|
|
hcrModuleMeta.addProcHeader(ccNimCall, "HcrGetImportedModules", "void**", cProcParams())
|
|
|
|
|
hcrModuleMeta.finishProcHeaderWithBody():
|
|
|
|
|
hcrModuleMeta.addReturn(cCast("void**", "hcr_module_list"))
|
|
|
|
|
hcrModuleMeta.addDeclWithVisibility(ExportLib):
|
|
|
|
|
hcrModuleMeta.addProcHeader(ccNimCall, "HcrGetSigHash", ptrType("char"), cProcParams())
|
|
|
|
|
hcrModuleMeta.finishProcHeaderWithBody():
|
|
|
|
|
hcrModuleMeta.addReturn('"' & $sigHash(m.module, m.config) & '"')
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
hcrModuleMeta.addf("\t$1,$n", [systemModulePath])
|
|
|
|
|
g.graph.importDeps.withValue(FileIndex(m.module.position), deps):
|
|
|
|
|
for curr in deps[]:
|
|
|
|
|
hcrModuleMeta.addf("\t$1,$n", [getModuleDllPath(m, g.modules[curr.int].module)])
|
|
|
|
|
hcrModuleMeta.addf("\t\"\"};$n", [])
|
|
|
|
|
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
|
|
|
|
|
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
|
|
|
|
|
[($sigHash(m.module, m.config)).rope])
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
g.mainModProcs.add(hcrModuleMeta)
|
|
|
|
|
g.mainModProcs.addf("static void* hcr_handle;$N", [])
|
|
|
|
|
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [init])
|
|
|
|
|
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [datInit])
|
|
|
|
|
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void*, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*));$N", [m.getHcrInitName])
|
|
|
|
|
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void);$N", [])
|
|
|
|
|
g.mainModInit.addf("\t$1();$N", [init])
|
|
|
|
|
g.otherModsInit.addf("\thcrInit((void**)hcr_module_list, $1, $2, $3, hcr_handle, nimGetProcAddr);$n",
|
|
|
|
|
[mainModulePath, systemModulePath, datInit])
|
|
|
|
|
g.mainDatInit.addf("\t$1(hcr_handle, nimGetProcAddr);$N", [m.getHcrInitName])
|
|
|
|
|
g.mainDatInit.addf("\thcrAddModule($1);\n", [mainModulePath])
|
|
|
|
|
g.mainDatInit.addf("\tHcrCreateTypeInfos();$N", [])
|
|
|
|
|
g.mainModProcs.add(extract(hcrModuleMeta))
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(StaticProc):
|
|
|
|
|
g.mainModProcs.addVar(name = "hcr_handle", typ = "void*")
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(ExportLib):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, init, "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(ExportLib):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, datInit, "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(ExportLib):
|
|
|
|
|
g.mainModProcs.addProcHeaderWithParams(ccNimCall, m.getHcrInitName, "void"):
|
|
|
|
|
var hcrInitParams: ProcParamBuilder
|
|
|
|
|
g.mainModProcs.addProcParams(hcrInitParams):
|
|
|
|
|
g.mainModProcs.addUnnamedParam(hcrInitParams, "void*")
|
|
|
|
|
g.mainModProcs.addProcTypedParam(hcrInitParams, ccNimCall, "getProcAddr", "void*", cProcParams(
|
|
|
|
|
(name: "", typ: "void*"),
|
|
|
|
|
(name: "", typ: ptrType("char"))))
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(ExportLib):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, "HcrCreateTypeInfos", "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
g.mainModInit.addCallStmt(init)
|
|
|
|
|
g.otherModsInit.addCallStmt("hcrInit",
|
|
|
|
|
cCast("void**", "hcr_module_list"),
|
|
|
|
|
mainModulePath,
|
|
|
|
|
systemModulePath,
|
|
|
|
|
datInit,
|
|
|
|
|
"hcr_handle",
|
|
|
|
|
"nimGetProcAddr")
|
|
|
|
|
g.mainDatInit.addCallStmt(m.getHcrInitName, "hcr_handle", "nimGetProcAddr")
|
|
|
|
|
g.mainDatInit.addCallStmt("hcrAddModule", mainModulePath)
|
|
|
|
|
g.mainDatInit.addCallStmt("HcrCreateTypeInfos")
|
|
|
|
|
# nasty nasty hack to get the command line functionality working with HCR
|
|
|
|
|
# register the 2 variables on behalf of the os module which might not even
|
|
|
|
|
# be loaded (in which case it will get collected but that is not a problem)
|
|
|
|
|
@@ -1909,38 +1983,52 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
|
|
|
|
# (`makeCString` was doing line wrap of string litterals) was root cause for
|
|
|
|
|
# bug #16265.
|
|
|
|
|
let osModulePath = ($systemModulePath).replace("stdlib_system", "stdlib_os").rope
|
|
|
|
|
g.mainDatInit.addf("\thcrAddModule($1);\n", [osModulePath])
|
|
|
|
|
g.mainDatInit.add("\tint* cmd_count;\n")
|
|
|
|
|
g.mainDatInit.add("\tchar*** cmd_line;\n")
|
|
|
|
|
g.mainDatInit.addf("\thcrRegisterGlobal($1, \"cmdCount\", sizeof(cmd_count), NULL, (void**)&cmd_count);$N", [osModulePath])
|
|
|
|
|
g.mainDatInit.addf("\thcrRegisterGlobal($1, \"cmdLine\", sizeof(cmd_line), NULL, (void**)&cmd_line);$N", [osModulePath])
|
|
|
|
|
g.mainDatInit.add("\t*cmd_count = cmdCount;\n")
|
|
|
|
|
g.mainDatInit.add("\t*cmd_line = cmdLine;\n")
|
|
|
|
|
g.mainDatInit.addCallStmt("hcrAddModule", osModulePath)
|
|
|
|
|
g.mainDatInit.addVar(name = "cmd_count", typ = ptrType("int"))
|
|
|
|
|
g.mainDatInit.addVar(name = "cmd_line", typ = ptrType(ptrType(ptrType("char"))))
|
|
|
|
|
g.mainDatInit.addCallStmt("hcrRegisterGlobal",
|
|
|
|
|
osModulePath,
|
|
|
|
|
"\"cmdCount\"",
|
|
|
|
|
cSizeof("cmd_count"),
|
|
|
|
|
"NULL",
|
|
|
|
|
cCast("void**", cAddr("cmd_count")))
|
|
|
|
|
g.mainDatInit.addCallStmt("hcrRegisterGlobal",
|
|
|
|
|
osModulePath,
|
|
|
|
|
"\"cmdLine\"",
|
|
|
|
|
cSizeof("cmd_line"),
|
|
|
|
|
"NULL",
|
|
|
|
|
cCast("void**", cAddr("cmd_line")))
|
|
|
|
|
g.mainDatInit.addAssignment(cDeref("cmd_count"), "cmdCount")
|
|
|
|
|
g.mainDatInit.addAssignment(cDeref("cmd_line"), "cmdLine")
|
|
|
|
|
else:
|
|
|
|
|
m.s[cfsInitProc].add(hcrModuleMeta)
|
|
|
|
|
m.s[cfsInitProc].add(extract(hcrModuleMeta))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if m.s[cfsDatInitProc].buf.len > 0:
|
|
|
|
|
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [datInit])
|
|
|
|
|
g.mainDatInit.addf("\t$1();$N", [datInit])
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(Private):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, datInit, "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
g.mainDatInit.addCallStmt(datInit)
|
|
|
|
|
|
|
|
|
|
# Initialization of TLS and GC should be done in between
|
|
|
|
|
# systemDatInit and systemInit calls if any
|
|
|
|
|
if sfSystemModule in m.module.flags:
|
|
|
|
|
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
|
|
|
|
|
g.mainDatInit.add(ropecg(m, "\t#initThreadVarsEmulation();$N", []))
|
|
|
|
|
g.mainDatInit.addCallStmt(cgsymValue(m, "initThreadVarsEmulation"))
|
|
|
|
|
if m.config.target.targetOS != osStandalone and m.config.selectedGC notin {gcNone, gcArc, gcAtomicArc, gcOrc}:
|
|
|
|
|
g.mainDatInit.add(ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []))
|
|
|
|
|
g.mainDatInit.addCallStmt(cgsymValue(m, "initStackBottomWith"),
|
|
|
|
|
cCast("void*", cAddr("inner")))
|
|
|
|
|
|
|
|
|
|
if m.s[cfsInitProc].buf.len > 0:
|
|
|
|
|
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
|
|
|
|
|
let initCall = "\t$1();$N" % [init]
|
|
|
|
|
g.mainModProcs.addDeclWithVisibility(Private):
|
|
|
|
|
g.mainModProcs.addProcHeader(ccNimCall, init, "void", cProcParams())
|
|
|
|
|
g.mainModProcs.finishProcHeaderAsProto()
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
g.mainModInit.add(initCall)
|
|
|
|
|
g.mainModInit.addCallStmt(init)
|
|
|
|
|
elif sfSystemModule in m.module.flags:
|
|
|
|
|
g.mainDatInit.add(initCall) # systemInit must called right after systemDatInit if any
|
|
|
|
|
g.mainDatInit.addCallStmt(init) # systemInit must called right after systemDatInit if any
|
|
|
|
|
else:
|
|
|
|
|
g.otherModsInit.add(initCall)
|
|
|
|
|
g.otherModsInit.addCallStmt(init)
|
|
|
|
|
|
|
|
|
|
proc genDatInitCode(m: BModule) =
|
|
|
|
|
## this function is called in cgenWriteModules after all modules are closed,
|
|
|
|
|
@@ -1949,19 +2037,21 @@ proc genDatInitCode(m: BModule) =
|
|
|
|
|
|
|
|
|
|
var moduleDatInitRequired = m.hcrOn
|
|
|
|
|
|
|
|
|
|
var prc = newBuilder("$1 N_NIMCALL(void, $2)(void) {$N" %
|
|
|
|
|
[rope(if m.hcrOn: "N_LIB_EXPORT" else: "N_LIB_PRIVATE"), getDatInitName(m)])
|
|
|
|
|
var prc = newBuilder("")
|
|
|
|
|
let vis = if m.hcrOn: ExportLib else: Private
|
|
|
|
|
prc.addDeclWithVisibility(vis):
|
|
|
|
|
prc.addProcHeader(ccNimCall, getDatInitName(m), "void", cProcParams())
|
|
|
|
|
prc.finishProcHeaderWithBody():
|
|
|
|
|
# we don't want to break into such init code - could happen if a line
|
|
|
|
|
# directive from a function written by the user spills after itself
|
|
|
|
|
genCLineDir(prc, InvalidFileIdx, 999999, m.config)
|
|
|
|
|
|
|
|
|
|
# we don't want to break into such init code - could happen if a line
|
|
|
|
|
# directive from a function written by the user spills after itself
|
|
|
|
|
genCLineDir(prc, InvalidFileIdx, 999999, m.config)
|
|
|
|
|
for i in cfsTypeInit1..cfsDynLibInit:
|
|
|
|
|
if m.s[i].buf.len != 0:
|
|
|
|
|
moduleDatInitRequired = true
|
|
|
|
|
prc.add(extract(m.s[i]))
|
|
|
|
|
|
|
|
|
|
for i in cfsTypeInit1..cfsDynLibInit:
|
|
|
|
|
if m.s[i].buf.len != 0:
|
|
|
|
|
moduleDatInitRequired = true
|
|
|
|
|
prc.add(extract(m.s[i]))
|
|
|
|
|
|
|
|
|
|
prc.addf("}$N$N", [])
|
|
|
|
|
prc.addNewline()
|
|
|
|
|
|
|
|
|
|
if moduleDatInitRequired:
|
|
|
|
|
m.s[cfsDatInitProc].add(extract(prc))
|
|
|
|
|
@@ -1969,7 +2059,7 @@ proc genDatInitCode(m: BModule) =
|
|
|
|
|
|
|
|
|
|
# Very similar to the contents of symInDynamicLib - basically only the
|
|
|
|
|
# things needed for the hot code reloading runtime procs to be loaded
|
|
|
|
|
proc hcrGetProcLoadCode(m: BModule, sym, prefix, handle, getProcFunc: string): Rope =
|
|
|
|
|
proc hcrGetProcLoadCode(builder: var Builder, m: BModule, sym, prefix, handle, getProcFunc: string) =
|
|
|
|
|
let prc = magicsys.getCompilerProc(m.g.graph, sym)
|
|
|
|
|
assert prc != nil
|
|
|
|
|
fillProcLoc(m, prc.ast[namePos])
|
|
|
|
|
@@ -1980,10 +2070,10 @@ proc hcrGetProcLoadCode(m: BModule, sym, prefix, handle, getProcFunc: string): R
|
|
|
|
|
prc.typ.sym = nil
|
|
|
|
|
|
|
|
|
|
if not containsOrIncl(m.declaredThings, prc.id):
|
|
|
|
|
m.s[cfsVars].addf("static $2 $1;$n", [prc.loc.snippet, getTypeDesc(m, prc.loc.t, dkVar)])
|
|
|
|
|
m.s[cfsVars].addVar(Global, name = prc.loc.snippet, typ = getTypeDesc(m, prc.loc.t, dkVar))
|
|
|
|
|
|
|
|
|
|
result = "\t$1 = ($2) $3($4, $5);$n" %
|
|
|
|
|
[tmp, getTypeDesc(m, prc.typ, dkVar), getProcFunc.rope, handle.rope, makeCString(prefix & sym)]
|
|
|
|
|
builder.addAssignment(tmp, cCast(getTypeDesc(m, prc.typ, dkVar),
|
|
|
|
|
cCall(getProcFunc, handle, makeCString(prefix & sym))))
|
|
|
|
|
|
|
|
|
|
proc genInitCode(m: BModule) =
|
|
|
|
|
## this function is called in cgenWriteModules after all modules are closed,
|
|
|
|
|
@@ -1991,46 +2081,57 @@ proc genInitCode(m: BModule) =
|
|
|
|
|
## into other modules, only simple rope manipulations are allowed
|
|
|
|
|
var moduleInitRequired = m.hcrOn
|
|
|
|
|
let initname = getInitName(m)
|
|
|
|
|
var prc = newBuilder("$1 N_NIMCALL(void, $2)(void) {$N" %
|
|
|
|
|
[rope(if m.hcrOn: "N_LIB_EXPORT" else: "N_LIB_PRIVATE"), initname])
|
|
|
|
|
var prcBody = newBuilder("")
|
|
|
|
|
# we don't want to break into such init code - could happen if a line
|
|
|
|
|
# directive from a function written by the user spills after itself
|
|
|
|
|
genCLineDir(prc, InvalidFileIdx, 999999, m.config)
|
|
|
|
|
genCLineDir(prcBody, InvalidFileIdx, 999999, m.config)
|
|
|
|
|
if m.typeNodes > 0:
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
appcg(m, m.s[cfsTypeInit1], "\t#TNimNode* $1;$N", [m.typeNodesName])
|
|
|
|
|
appcg(m, m.s[cfsTypeInit1], "\thcrRegisterGlobal($3, \"$1_$2\", sizeof(TNimNode) * $2, NULL, (void**)&$1);$N",
|
|
|
|
|
[m.typeNodesName, m.typeNodes, getModuleDllPath(m, m.module)])
|
|
|
|
|
m.s[cfsTypeInit1].addVar(name = m.typeNodesName, typ = ptrType(cgsymValue(m, "TNimNode")))
|
|
|
|
|
m.s[cfsTypeInit1].addCallStmt("hcrRegisterGlobal",
|
|
|
|
|
getModuleDllPath(m, m.module),
|
|
|
|
|
'"' & m.typeNodesName & '_' & $m.typeNodes & '"',
|
|
|
|
|
cOp(Mul, "NI", cSizeof("TNimNode"), cIntValue(m.typeNodes)),
|
|
|
|
|
"NULL",
|
|
|
|
|
cCast("void**", cAddr(m.typeNodesName)))
|
|
|
|
|
else:
|
|
|
|
|
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
|
|
|
|
[m.typeNodesName, m.typeNodes])
|
|
|
|
|
m.s[cfsTypeInit1].addArrayVar(Global, name = m.typeNodesName,
|
|
|
|
|
elementType = cgsymValue(m, "TNimNode"), len = m.typeNodes)
|
|
|
|
|
if m.nimTypes > 0:
|
|
|
|
|
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
|
|
|
|
|
[m.nimTypesName, m.nimTypes])
|
|
|
|
|
m.s[cfsTypeInit1].addArrayVar(Global, name = m.nimTypesName,
|
|
|
|
|
elementType = cgsymValue(m, "TNimType"), len = m.nimTypes)
|
|
|
|
|
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
prc.addf("\tint* nim_hcr_dummy_ = 0;$n" &
|
|
|
|
|
"\tNIM_BOOL nim_hcr_do_init_ = " &
|
|
|
|
|
"hcrRegisterGlobal($1, \"module_initialized_\", 1, NULL, (void**)&nim_hcr_dummy_);$n",
|
|
|
|
|
[getModuleDllPath(m, m.module)])
|
|
|
|
|
prcBody.addVar(name = "nim_hcr_dummy_", typ = ptrType("int"), initializer = cIntValue(0))
|
|
|
|
|
prcBody.addVar(name = "nim_hcr_do_init_", typ = "NIM_BOOL",
|
|
|
|
|
initializer = cCall("hcrRegisterGlobal",
|
|
|
|
|
getModuleDllPath(m, m.module),
|
|
|
|
|
"\"module_initialized_\"",
|
|
|
|
|
cIntValue(1),
|
|
|
|
|
"NULL",
|
|
|
|
|
cCast("void**", cAddr("nim_hcr_dummy_"))))
|
|
|
|
|
|
|
|
|
|
template writeSection(thing: untyped, section: TCProcSection, addHcrGuards = false) =
|
|
|
|
|
if m.thing.s(section).buf.len > 0:
|
|
|
|
|
moduleInitRequired = true
|
|
|
|
|
if addHcrGuards: prc.add("\tif (nim_hcr_do_init_) {\n\n")
|
|
|
|
|
prc.add(extract(m.thing.s(section)))
|
|
|
|
|
if addHcrGuards: prc.add("\n\t} // nim_hcr_do_init_\n")
|
|
|
|
|
if addHcrGuards:
|
|
|
|
|
prcBody.addSingleIfStmt("nim_hcr_do_init_"):
|
|
|
|
|
prcBody.addNewline()
|
|
|
|
|
prcBody.add(extract(m.thing.s(section)))
|
|
|
|
|
prcBody.addNewline()
|
|
|
|
|
else:
|
|
|
|
|
prcBody.add(extract(m.thing.s(section)))
|
|
|
|
|
|
|
|
|
|
if m.preInitProc.s(cpsInit).buf.len > 0 or m.preInitProc.s(cpsStmts).buf.len > 0:
|
|
|
|
|
# Give this small function its own scope
|
|
|
|
|
prc.addf("{$N", [])
|
|
|
|
|
# Keep a bogus frame in case the code needs one
|
|
|
|
|
prc.add("\tTFrame FR_; FR_.len = 0;\n")
|
|
|
|
|
prcBody.addScope():
|
|
|
|
|
# Keep a bogus frame in case the code needs one
|
|
|
|
|
prcBody.addVar(name = "FR_", typ = "TFrame")
|
|
|
|
|
prcBody.addFieldAssignment("FR_", "len", cIntValue(0))
|
|
|
|
|
|
|
|
|
|
writeSection(preInitProc, cpsLocals)
|
|
|
|
|
writeSection(preInitProc, cpsInit, m.hcrOn)
|
|
|
|
|
writeSection(preInitProc, cpsStmts)
|
|
|
|
|
prc.addf("}/* preInitProc end */$N", [])
|
|
|
|
|
writeSection(preInitProc, cpsLocals)
|
|
|
|
|
writeSection(preInitProc, cpsInit, m.hcrOn)
|
|
|
|
|
writeSection(preInitProc, cpsStmts)
|
|
|
|
|
when false:
|
|
|
|
|
m.initProc.blocks[0].sections[cpsLocals].add m.preInitProc.s(cpsLocals)
|
|
|
|
|
m.initProc.blocks[0].sections[cpsInit].prepend m.preInitProc.s(cpsInit)
|
|
|
|
|
@@ -2038,37 +2139,41 @@ proc genInitCode(m: BModule) =
|
|
|
|
|
|
|
|
|
|
# add new scope for following code, because old vcc compiler need variable
|
|
|
|
|
# be defined at the top of the block
|
|
|
|
|
prc.addf("{$N", [])
|
|
|
|
|
writeSection(initProc, cpsLocals)
|
|
|
|
|
prcBody.addScope():
|
|
|
|
|
writeSection(initProc, cpsLocals)
|
|
|
|
|
|
|
|
|
|
if m.initProc.s(cpsInit).buf.len > 0 or m.initProc.s(cpsStmts).buf.len > 0:
|
|
|
|
|
moduleInitRequired = true
|
|
|
|
|
if optStackTrace in m.initProc.options and frameDeclared notin m.flags:
|
|
|
|
|
# BUT: the generated init code might depend on a current frame, so
|
|
|
|
|
# declare it nevertheless:
|
|
|
|
|
incl m.flags, frameDeclared
|
|
|
|
|
if preventStackTrace notin m.flags:
|
|
|
|
|
var procname = makeCString(m.module.name.s)
|
|
|
|
|
prc.add(initFrame(m.initProc, procname, quotedFilename(m.config, m.module.info)))
|
|
|
|
|
else:
|
|
|
|
|
prc.add("\tTFrame FR_; FR_.len = 0;\n")
|
|
|
|
|
if m.initProc.s(cpsInit).buf.len > 0 or m.initProc.s(cpsStmts).buf.len > 0:
|
|
|
|
|
moduleInitRequired = true
|
|
|
|
|
if optStackTrace in m.initProc.options and frameDeclared notin m.flags:
|
|
|
|
|
# BUT: the generated init code might depend on a current frame, so
|
|
|
|
|
# declare it nevertheless:
|
|
|
|
|
incl m.flags, frameDeclared
|
|
|
|
|
if preventStackTrace notin m.flags:
|
|
|
|
|
var procname = makeCString(m.module.name.s)
|
|
|
|
|
prcBody.add(initFrame(m.initProc, procname, quotedFilename(m.config, m.module.info)))
|
|
|
|
|
else:
|
|
|
|
|
prcBody.addVar(name = "FR_", typ = "TFrame")
|
|
|
|
|
prcBody.addFieldAssignment("FR_", "len", cIntValue(0))
|
|
|
|
|
|
|
|
|
|
writeSection(initProc, cpsInit, m.hcrOn)
|
|
|
|
|
writeSection(initProc, cpsStmts)
|
|
|
|
|
writeSection(initProc, cpsInit, m.hcrOn)
|
|
|
|
|
writeSection(initProc, cpsStmts)
|
|
|
|
|
|
|
|
|
|
if beforeRetNeeded in m.initProc.flags:
|
|
|
|
|
prc.add("\tBeforeRet_: ;\n")
|
|
|
|
|
if beforeRetNeeded in m.initProc.flags:
|
|
|
|
|
prcBody.addLabel("BeforeRet_")
|
|
|
|
|
|
|
|
|
|
if m.config.exc == excGoto:
|
|
|
|
|
if getCompilerProc(m.g.graph, "nimTestErrorFlag") != nil:
|
|
|
|
|
m.appcg(prc, "\t#nimTestErrorFlag();$n", [])
|
|
|
|
|
if m.config.exc == excGoto:
|
|
|
|
|
if getCompilerProc(m.g.graph, "nimTestErrorFlag") != nil:
|
|
|
|
|
prcBody.addCallStmt(cgsymValue(m, "nimTestErrorFlag"))
|
|
|
|
|
|
|
|
|
|
if optStackTrace in m.initProc.options and preventStackTrace notin m.flags:
|
|
|
|
|
prc.add(deinitFrame(m.initProc))
|
|
|
|
|
if optStackTrace in m.initProc.options and preventStackTrace notin m.flags:
|
|
|
|
|
prcBody.add(deinitFrame(m.initProc))
|
|
|
|
|
|
|
|
|
|
prc.addf("}$N", [])
|
|
|
|
|
|
|
|
|
|
prc.addf("}$N$N", [])
|
|
|
|
|
var procs = newBuilder("")
|
|
|
|
|
let vis = if m.hcrOn: ExportLib else: Private
|
|
|
|
|
procs.addDeclWithVisibility(vis):
|
|
|
|
|
procs.addProcHeader(ccNimCall, initname, "void", cProcParams())
|
|
|
|
|
procs.finishProcHeaderWithBody():
|
|
|
|
|
procs.add(extract(prcBody))
|
|
|
|
|
|
|
|
|
|
# we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
|
|
|
|
|
# that would lead to a *nesting* of merge sections which the merger does
|
|
|
|
|
@@ -2077,33 +2182,43 @@ proc genInitCode(m: BModule) =
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
var procsToLoad = @["hcrRegisterProc", "hcrGetProc", "hcrRegisterGlobal", "hcrGetGlobal"]
|
|
|
|
|
|
|
|
|
|
m.s[cfsInitProc].addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void* handle, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*)) {$N", [getHcrInitName(m)])
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
# additional procs to load
|
|
|
|
|
procsToLoad.add("hcrInit")
|
|
|
|
|
procsToLoad.add("hcrAddModule")
|
|
|
|
|
# load procs
|
|
|
|
|
for curr in procsToLoad:
|
|
|
|
|
m.s[cfsInitProc].add(hcrGetProcLoadCode(m, curr, "", "handle", "getProcAddr"))
|
|
|
|
|
m.s[cfsInitProc].addf("}$N$N", [])
|
|
|
|
|
m.s[cfsInitProc].addDeclWithVisibility(ExportLib):
|
|
|
|
|
m.s[cfsInitProc].addProcHeaderWithParams(ccNimCall, getHcrInitName(m), "void"):
|
|
|
|
|
var hcrInitParams: ProcParamBuilder
|
|
|
|
|
m.s[cfsInitProc].addProcParams(hcrInitParams):
|
|
|
|
|
m.s[cfsInitProc].addParam(hcrInitParams, "handle", "void*")
|
|
|
|
|
m.s[cfsInitProc].addProcTypedParam(hcrInitParams, ccNimCall, "getProcAddr", "void*", cProcParams(
|
|
|
|
|
(name: "", typ: "void*"),
|
|
|
|
|
(name: "", typ: ptrType("char"))))
|
|
|
|
|
m.s[cfsInitProc].finishProcHeaderWithBody():
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
# additional procs to load
|
|
|
|
|
procsToLoad.add("hcrInit")
|
|
|
|
|
procsToLoad.add("hcrAddModule")
|
|
|
|
|
# load procs
|
|
|
|
|
for curr in procsToLoad:
|
|
|
|
|
hcrGetProcLoadCode(m.s[cfsInitProc], m, curr, "", "handle", "getProcAddr")
|
|
|
|
|
|
|
|
|
|
for i, el in pairs(m.extensionLoaders):
|
|
|
|
|
if el.buf.len != 0:
|
|
|
|
|
let ex = "NIM_EXTERNC N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N" %
|
|
|
|
|
[(i.ord - '0'.ord).rope, extract(el)]
|
|
|
|
|
moduleInitRequired = true
|
|
|
|
|
prc.add(ex)
|
|
|
|
|
procs.addDeclWithVisibility(ExternC):
|
|
|
|
|
procs.addProcHeader(ccNimCall, "nimLoadProcs" & $(i.ord - '0'.ord), "void", cProcParams())
|
|
|
|
|
procs.finishProcHeaderWithBody():
|
|
|
|
|
procs.add(extract(el))
|
|
|
|
|
|
|
|
|
|
if moduleInitRequired or sfMainModule in m.module.flags:
|
|
|
|
|
m.s[cfsInitProc].add(extract(prc))
|
|
|
|
|
m.s[cfsInitProc].add(extract(procs))
|
|
|
|
|
#rememberFlag(m.g.graph, m.module, HasModuleInitProc)
|
|
|
|
|
|
|
|
|
|
genDatInitCode(m)
|
|
|
|
|
|
|
|
|
|
if m.hcrOn:
|
|
|
|
|
m.s[cfsInitProc].addf("N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void) {$N", [])
|
|
|
|
|
m.s[cfsInitProc].add(extract(m.hcrCreateTypeInfosProc))
|
|
|
|
|
m.s[cfsInitProc].addf("}$N$N", [])
|
|
|
|
|
m.s[cfsInitProc].addDeclWithVisibility(ExportLib):
|
|
|
|
|
m.s[cfsInitProc].addProcHeader(ccNimCall, "HcrCreateTypeInfos", "void", cProcParams())
|
|
|
|
|
m.s[cfsInitProc].finishProcHeaderWithBody():
|
|
|
|
|
m.s[cfsInitProc].add(extract(m.hcrCreateTypeInfosProc))
|
|
|
|
|
m.s[cfsInitProc].addNewline()
|
|
|
|
|
|
|
|
|
|
registerModuleToMain(m.g, m)
|
|
|
|
|
|
|
|
|
|
@@ -2257,9 +2372,10 @@ proc writeHeader(m: BModule) =
|
|
|
|
|
openNamespaceNim(m.config.cppCustomNamespace, result)
|
|
|
|
|
result.add(extract(m.s[cfsInitProc]))
|
|
|
|
|
|
|
|
|
|
if optGenDynLib in m.config.globalOptions:
|
|
|
|
|
result.add("N_LIB_IMPORT ")
|
|
|
|
|
result.addf("N_CDECL(void, $1NimMain)(void);$n", [rope m.config.nimMainPrefix])
|
|
|
|
|
let vis = if optGenDynLib in m.config.globalOptions: ImportLib else: None
|
|
|
|
|
result.addDeclWithVisibility(vis):
|
|
|
|
|
result.addProcHeader(ccCDecl, m.config.nimMainPrefix & "NimMain", "void", cProcParams())
|
|
|
|
|
result.finishProcHeaderAsProto()
|
|
|
|
|
if m.config.cppCustomNamespace.len > 0: closeNamespaceNim(result)
|
|
|
|
|
result.addf("#endif /* $1 */$n", [guard])
|
|
|
|
|
if not writeRope(extract(result), m.filename):
|
|
|
|
|
@@ -2354,7 +2470,7 @@ proc writeModule(m: BModule, pending: bool) =
|
|
|
|
|
if sfMainModule in m.module.flags:
|
|
|
|
|
# generate main file:
|
|
|
|
|
genMainProc(m)
|
|
|
|
|
m.s[cfsProcHeaders].add(m.g.mainModProcs)
|
|
|
|
|
m.s[cfsProcHeaders].add(extract(m.g.mainModProcs))
|
|
|
|
|
generateThreadVarsSize(m)
|
|
|
|
|
|
|
|
|
|
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
|
|
|
|
|