diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semstmts.nim | 18 | ||||
-rw-r--r-- | compiler/vm.nim | 5 | ||||
-rw-r--r-- | compiler/vmgen.nim | 10 |
3 files changed, 20 insertions, 13 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 68da6d3b2..d77e619f9 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1863,7 +1863,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, " operator has to be enabled with {.experimental: \"callOperator\".}") 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: localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s) let usePseudoGenerics = kind in {skMacro, skTemplate} @@ -1881,12 +1881,11 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, c.p.wasForwarded = proto != nil maybeAddResult(c, s, n) - if lfDynamicLib notin s.loc.flags: - # no semantic checking for importc: - s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos])) - # unfortunately we cannot skip this step when in 'system.compiles' - # context as it may even be evaluated in 'system.compiles': - trackProc(c, s, s.ast[bodyPos]) + # semantic checking also needed with importc in case used in VM + s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos])) + # unfortunately we cannot skip this step when in 'system.compiles' + # context as it may even be evaluated in 'system.compiles': + trackProc(c, s, s.ast[bodyPos]) if s.kind == skMethod: semMethodPrototype(c, s, n) else: if (s.typ.sons[0] != nil and kind != skIterator) or kind == skMacro: @@ -1899,8 +1898,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, fixupInstantiatedSymbols(c, s) if s.kind == skMethod: semMethodPrototype(c, s, n) if sfImportc in s.flags: - # so we just ignore the body after semantic checking for importc: - n.sons[bodyPos] = c.graph.emptyNode + # don't ignore the body in case used in VM + # n.sons[bodyPos] = c.graph.emptyNode + discard popProcCon(c) else: if s.kind == skMethod: semMethodPrototype(c, s, n) diff --git a/compiler/vm.nim b/compiler/vm.nim index 2919e865a..f2b288216 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1082,12 +1082,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs), currentException: c.currentExceptionA, currentLineInfo: c.debug[pc])) - elif sfImportc in prc.flags: + elif importcCond(prc): if compiletimeFFI notin c.config.features: 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 # 'regs' in a register: 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] if prcValue.kind == nkEmpty: globalError(c.config, c.debug[pc], "cannot run " & prc.name.s) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 08d79bbb7..9e1c4d602 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1544,8 +1544,11 @@ proc genTypeLit(c: PCtx; t: PType; dest: var TDest) = n.typ = t genLit(c, n, dest) -proc importcCond(s: PSym): bool {.inline.} = - sfImportc in s.flags and (lfDynamicLib notin s.loc.flags or s.ast == nil) +proc importcCond*(s: PSym): bool {.inline.} = + ## 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) = when hasFFI: @@ -1553,7 +1556,8 @@ proc importcSym(c: PCtx; info: TLineInfo; s: PSym) = c.globals.add(importcSymbol(c.config, s)) s.position = c.globals.len 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: localError(c.config, info, "cannot 'importc' variable at compile time; " & s.name.s) |