CT FFI: fix for windows; fix case transition; error msg shows more useful context (#13292)
* evalffi: fix case transition * evalffi: fix for windows * evallffi: `cannot import` errmsg now also shows which library it tried to import symbol from
This commit is contained in:
parent
bf22b44b1f
commit
4a747f0250
1 changed files with 8 additions and 3 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
## This file implements the FFI part of the evaluator for Nim code.
|
## This file implements the FFI part of the evaluator for Nim code.
|
||||||
|
|
||||||
import ast, types, options, tables, dynlib, msgs, lineinfos
|
import ast, types, options, tables, dynlib, msgs, lineinfos
|
||||||
|
from os import getAppFilename
|
||||||
import pkg/libffi
|
import pkg/libffi
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
|
@ -27,7 +28,7 @@ var
|
||||||
gDllCache = initTable[string, LibHandle]()
|
gDllCache = initTable[string, LibHandle]()
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var gExeHandle = loadLib(os.getAppFilename())
|
var gExeHandle = loadLib(getAppFilename())
|
||||||
else:
|
else:
|
||||||
var gExeHandle = loadLib()
|
var gExeHandle = loadLib()
|
||||||
|
|
||||||
|
|
@ -52,11 +53,13 @@ proc importcSymbol*(conf: ConfigRef, sym: PSym): PNode =
|
||||||
# that contains the address instead:
|
# that contains the address instead:
|
||||||
result = newNodeIT(nkPtrLit, sym.info, sym.typ)
|
result = newNodeIT(nkPtrLit, sym.info, sym.typ)
|
||||||
when true:
|
when true:
|
||||||
|
var libPathMsg = ""
|
||||||
let lib = sym.annex
|
let lib = sym.annex
|
||||||
if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}:
|
if lib != nil and lib.path.kind notin {nkStrLit..nkTripleStrLit}:
|
||||||
globalError(conf, sym.info, "dynlib needs to be a string lit")
|
globalError(conf, sym.info, "dynlib needs to be a string lit")
|
||||||
var theAddr: pointer
|
var theAddr: pointer
|
||||||
if (lib.isNil or lib.kind == libHeader) and not gExeHandle.isNil:
|
if (lib.isNil or lib.kind == libHeader) and not gExeHandle.isNil:
|
||||||
|
libPathMsg = "current exe: " & getAppFilename() & " nor libc: " & libcDll
|
||||||
# first try this exe itself:
|
# first try this exe itself:
|
||||||
theAddr = gExeHandle.symAddr(name)
|
theAddr = gExeHandle.symAddr(name)
|
||||||
# then try libc:
|
# then try libc:
|
||||||
|
|
@ -65,9 +68,11 @@ proc importcSymbol*(conf: ConfigRef, sym: PSym): PNode =
|
||||||
theAddr = dllhandle.symAddr(name)
|
theAddr = dllhandle.symAddr(name)
|
||||||
elif not lib.isNil:
|
elif not lib.isNil:
|
||||||
let dll = if lib.kind == libHeader: libcDll else: lib.path.strVal
|
let dll = if lib.kind == libHeader: libcDll else: lib.path.strVal
|
||||||
|
libPathMsg = dll
|
||||||
let dllhandle = getDll(conf, gDllCache, dll, sym.info)
|
let dllhandle = getDll(conf, gDllCache, dll, sym.info)
|
||||||
theAddr = dllhandle.symAddr(name)
|
theAddr = dllhandle.symAddr(name)
|
||||||
if theAddr.isNil: globalError(conf, sym.info, "cannot import: " & name)
|
if theAddr.isNil: globalError(conf, sym.info,
|
||||||
|
"cannot import symbol: " & name & " from " & libPathMsg)
|
||||||
result.intVal = cast[ByteAddress](theAddr)
|
result.intVal = cast[ByteAddress](theAddr)
|
||||||
|
|
||||||
proc mapType(conf: ConfigRef, t: ast.PType): ptr libffi.Type =
|
proc mapType(conf: ConfigRef, t: ast.PType): ptr libffi.Type =
|
||||||
|
|
@ -320,7 +325,7 @@ proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
reset n[]
|
reset n[]
|
||||||
result = n
|
result = n
|
||||||
result.kind = nkNilLit
|
result[] = TNode(kind: nkNilLit)
|
||||||
result.typ = typ
|
result.typ = typ
|
||||||
|
|
||||||
template awi(kind, v: untyped): untyped = aw(kind, v, intVal)
|
template awi(kind, v: untyped): untyped = aw(kind, v, intVal)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue