fixes #8405: -d:useNimRtl now works even when {.rtl.} procs are used at compile time; CTFFI now works with {dynlib} (#11635)
This commit is contained in:
parent
0718d6c2cd
commit
64168d4aea
5 changed files with 68 additions and 61 deletions
|
|
@ -1863,7 +1863,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
" operator has to be enabled with {.experimental: \"callOperator\".}")
|
" operator has to be enabled with {.experimental: \"callOperator\".}")
|
||||||
|
|
||||||
if n.sons[bodyPos].kind != nkEmpty and sfError notin s.flags:
|
if n.sons[bodyPos].kind != nkEmpty and sfError notin s.flags:
|
||||||
# for DLL generation it is annoying to check for sfImportc!
|
# for DLL generation we allow sfImportc to have a body, for use in VM
|
||||||
if sfBorrow in s.flags:
|
if sfBorrow in s.flags:
|
||||||
localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s)
|
localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s)
|
||||||
let usePseudoGenerics = kind in {skMacro, skTemplate}
|
let usePseudoGenerics = kind in {skMacro, skTemplate}
|
||||||
|
|
@ -1881,8 +1881,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
|
|
||||||
c.p.wasForwarded = proto != nil
|
c.p.wasForwarded = proto != nil
|
||||||
maybeAddResult(c, s, n)
|
maybeAddResult(c, s, n)
|
||||||
if lfDynamicLib notin s.loc.flags:
|
# semantic checking also needed with importc in case used in VM
|
||||||
# no semantic checking for importc:
|
|
||||||
s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
# unfortunately we cannot skip this step when in 'system.compiles'
|
# unfortunately we cannot skip this step when in 'system.compiles'
|
||||||
# context as it may even be evaluated in 'system.compiles':
|
# context as it may even be evaluated in 'system.compiles':
|
||||||
|
|
@ -1899,8 +1898,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
fixupInstantiatedSymbols(c, s)
|
fixupInstantiatedSymbols(c, s)
|
||||||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
if sfImportc in s.flags:
|
if sfImportc in s.flags:
|
||||||
# so we just ignore the body after semantic checking for importc:
|
# don't ignore the body in case used in VM
|
||||||
n.sons[bodyPos] = c.graph.emptyNode
|
# n.sons[bodyPos] = c.graph.emptyNode
|
||||||
|
discard
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
else:
|
else:
|
||||||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||||
|
|
|
||||||
|
|
@ -1082,12 +1082,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
|
VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
|
||||||
currentException: c.currentExceptionA,
|
currentException: c.currentExceptionA,
|
||||||
currentLineInfo: c.debug[pc]))
|
currentLineInfo: c.debug[pc]))
|
||||||
elif sfImportc in prc.flags:
|
elif importcCond(prc):
|
||||||
if compiletimeFFI notin c.config.features:
|
if compiletimeFFI notin c.config.features:
|
||||||
globalError(c.config, c.debug[pc], "VM not allowed to do FFI, see `compiletimeFFI`")
|
globalError(c.config, c.debug[pc], "VM not allowed to do FFI, see `compiletimeFFI`")
|
||||||
# we pass 'tos.slots' instead of 'regs' so that the compiler can keep
|
# we pass 'tos.slots' instead of 'regs' so that the compiler can keep
|
||||||
# 'regs' in a register:
|
# 'regs' in a register:
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
|
if prc.position - 1 < 0:
|
||||||
|
globalError(c.config, c.debug[pc],
|
||||||
|
"VM call invalid: prc.position: " & $prc.position)
|
||||||
let prcValue = c.globals.sons[prc.position-1]
|
let prcValue = c.globals.sons[prc.position-1]
|
||||||
if prcValue.kind == nkEmpty:
|
if prcValue.kind == nkEmpty:
|
||||||
globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
|
globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
|
||||||
|
|
|
||||||
|
|
@ -1544,8 +1544,11 @@ proc genTypeLit(c: PCtx; t: PType; dest: var TDest) =
|
||||||
n.typ = t
|
n.typ = t
|
||||||
genLit(c, n, dest)
|
genLit(c, n, dest)
|
||||||
|
|
||||||
proc importcCond(s: PSym): bool {.inline.} =
|
proc importcCond*(s: PSym): bool {.inline.} =
|
||||||
sfImportc in s.flags and (lfDynamicLib notin s.loc.flags or s.ast == nil)
|
## return true to importc `s`, false to execute its body instead (refs #8405)
|
||||||
|
if sfImportc in s.flags:
|
||||||
|
if s.kind in routineKinds:
|
||||||
|
return s.ast.sons[bodyPos].kind == nkEmpty
|
||||||
|
|
||||||
proc importcSym(c: PCtx; info: TLineInfo; s: PSym) =
|
proc importcSym(c: PCtx; info: TLineInfo; s: PSym) =
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
|
|
@ -1553,7 +1556,8 @@ proc importcSym(c: PCtx; info: TLineInfo; s: PSym) =
|
||||||
c.globals.add(importcSymbol(c.config, s))
|
c.globals.add(importcSymbol(c.config, s))
|
||||||
s.position = c.globals.len
|
s.position = c.globals.len
|
||||||
else:
|
else:
|
||||||
localError(c.config, info, "VM is not allowed to 'importc'")
|
localError(c.config, info,
|
||||||
|
"VM is not allowed to 'importc' without --experimental:compiletimeFFI")
|
||||||
else:
|
else:
|
||||||
localError(c.config, info,
|
localError(c.config, info,
|
||||||
"cannot 'importc' variable at compile time; " & s.name.s)
|
"cannot 'importc' variable at compile time; " & s.name.s)
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,6 @@ proc next*(p: var OptParser) {.rtl, extern: "npo$1".} =
|
||||||
inc p.idx
|
inc p.idx
|
||||||
p.pos = 0
|
p.pos = 0
|
||||||
|
|
||||||
when declared(os.paramCount):
|
|
||||||
proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
|
proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo$1".} =
|
||||||
## Retrieves the rest of the command line that has not been parsed yet.
|
## Retrieves the rest of the command line that has not been parsed yet.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,7 @@ when not defined(useNimRtl):
|
||||||
add result, "(invalid data!)"
|
add result, "(invalid data!)"
|
||||||
inc(cl.recdepth)
|
inc(cl.recdepth)
|
||||||
|
|
||||||
|
when not defined(useNimRtl):
|
||||||
proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
|
proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
|
||||||
compilerRtl.} =
|
compilerRtl.} =
|
||||||
var
|
var
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue