From 2754d221f002908d25f2f7a05a4c1b23d4f5f991 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Tue, 19 Mar 2024 21:53:33 +0100 Subject: [PATCH] Fixed and optimized linking with newer clang --- tests/config.nims | 5 ++--- wasmrt.nim | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/config.nims b/tests/config.nims index 56060f7..76f0bd4 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -6,12 +6,11 @@ --d:release --nomain --opt:size ---listCmd +# --listCmd --d:wasm --stackTrace:off --d:noSignalHandler --exceptions:goto ---app:lib --d:nimPreviewFloatRoundtrip # Avoid using sprintf as it's not available in wasm let llTarget = "wasm32-unknown-unknown-wasm" @@ -24,7 +23,7 @@ switch("passC", "-I/usr/include") # Wouldn't compile without this :( switch("passC", "-flto") # Important for code size! # gc-sections seems to not have any effect -var linkerOptions = "-nostdlib -Wl,--no-entry,--allow-undefined,--export-dynamic,--gc-sections,--strip-all" +var linkerOptions = "-nostdlib -Wl,--no-entry,--allow-undefined,--gc-sections,--strip-all" switch("clang.options.linker", linkerOptions) switch("clang.cpp.options.linker", linkerOptions) diff --git a/wasmrt.nim b/wasmrt.nim index 4e80baa..49abdfe 100644 --- a/wasmrt.nim +++ b/wasmrt.nim @@ -9,8 +9,9 @@ const wasmExportCodegenDecl = when defined(cpp): macro exportwasm*(p: untyped): untyped = expectKind(p, nnkProcDef) result = p - result.addPragma(ident"exportc") - result.addPragma(newColonExpr(ident"codegenDecl", newLit(wasmExportCodegenDecl))) + let name = $p.name + let codegenPragma = "__attribute__ ((export_name (\"" & name & "\"))) $# $#$#" + result.addPragma(newColonExpr(ident"codegenDecl", newLit(codegenPragma))) proc stripSinkFromArgType(t: NimNode): NimNode = result = t @@ -365,21 +366,22 @@ g._nimwd = (v, a) => new Float64Array(q.buffer, a).set(v); W.instantiate(m, {env: o}).then(m => { g._nimm = m; - g._nime = m.exports; - q = _nime.memory; + n = g._nime = m.exports; + q = n.memory; _nimmu(); - _nime.NimMain(); + for(i in n) if (i[0]==';') n[i]() }) """).minifyJs().escapeJs() {.emit: [""" -#define NIM_WASM_EXPORT N_LIB_EXPORT __attribute__((visibility ("default"))) - int stdout = 0; int stderr = 1; static int dummyErrno = 0; -NIM_WASM_EXPORT const char __nimWasmInit __asm__(""" & '"' & initCode & """") = 0; +void __nimWasmInit() __attribute__((export_name(""" & '"' & initCode & """"))) { + void NimMain(); + NimMain(); +} N_LIB_PRIVATE void* memcpy(void* a, const void* b, size_t s) { char* aa = (char*)a; @@ -572,8 +574,8 @@ macro defDyncall(sig: static[string]): untyped = let wrappedCall = newCall(bindSym"dyncallWrap", callbackCall) result = newProc(ident("dyncall"), params, wrappedCall) - result.addPragma(newColonExpr(ident"exportc", newLit("_d" & sig))) - result.addPragma(ident"dynlib") + let codegenPragma = "__attribute__ ((export_name (\"" & "_d" & sig & "\"))) $# $#$#" + result.addPragma(newColonExpr(ident"codegenDecl", newLit(codegenPragma))) # echo repr result proc defineDyncall*(sig: static[string]) = @@ -687,7 +689,7 @@ proc free(p: pointer) {.exportc.} = dealloc(p) # Suppress __wasm_call_ctors # https://stackoverflow.com/questions/72568387/why-is-an-objects-constructor-being-called-in-every-exported-wasm-function -proc initialize() {.stackTrace: off, exportc: "_initialize", codegenDecl: wasmExportCodegenDecl.} = +proc initialize() {.stackTrace: off, exportc: "_initialize".} = proc ctors() {.importc: "__wasm_call_ctors".} ctors()