next steps for FFI support

This commit is contained in:
Araq 2013-11-25 13:04:11 +01:00
commit 9035d15ed2
9 changed files with 179 additions and 63 deletions

View file

@ -11,7 +11,10 @@
import
unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
trees, intsets, rodread, magicsys
trees, intsets, rodread, magicsys, options
when hasFFI:
import evalffi
proc codeListing(c: PCtx, result: var string) =
# first iteration: compute all necessary labels:
@ -395,9 +398,14 @@ proc genReturn(c: PCtx; n: PNode) =
proc genCall(c: PCtx; n: PNode; dest: var TDest) =
if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ)
let x = c.getTempRange(n.len, slotTempUnknown)
for i in 0.. <n.len:
# varargs need 'opcSetType' for the FFI support:
let fntyp = n.sons[0].typ
for i in 0.. <n.len:
var r: TRegister = x+i
c.gen(n.sons[i], r)
if i >= fntyp.len:
internalAssert tfVarargs in fntyp.flags
c.gABx(n, opcSetType, r, c.genType(n.sons[i].typ))
if dest < 0:
c.gABC(n, opcIndCall, 0, x, n.len)
else:
@ -884,13 +892,26 @@ proc genLit(c: PCtx; n: PNode; dest: var TDest) =
let lit = genLiteral(c, n)
c.gABx(n, opc, dest, lit)
proc importcSym(c: PCtx; info: TLineInfo; s: PSym) =
when hasFFI:
if allowFFI in c.features:
c.globals.add(importcSymbol(s))
s.position = c.globals.len
else:
localError(info, errGenerated, "VM is not allowed to 'importc'")
else:
localError(info, errGenerated,
"cannot 'importc' variable at compile time")
proc genRdVar(c: PCtx; n: PNode; dest: var TDest) =
let s = n.sym
if sfGlobal in s.flags:
if dest < 0: dest = c.getTemp(s.typ)
if s.position == 0:
c.globals.add(s.ast)
s.position = c.globals.len
if sfImportc in s.flags: c.importcSym(n.info, s)
else:
c.globals.add(s.ast)
s.position = c.globals.len
# XXX var g = codeHere() ?
c.gABx(n, opcLdGlobal, dest, s.position)
else:
@ -1003,9 +1024,11 @@ proc genVarSection(c: PCtx; n: PNode) =
let s = a.sons[0].sym
if sfGlobal in s.flags:
if s.position == 0:
let sa = if s.ast.isNil: getNullValue(s.typ, a.info) else: s.ast
c.globals.add(sa)
s.position = c.globals.len
if sfImportc in s.flags: c.importcSym(a.info, s)
else:
let sa = if s.ast.isNil: getNullValue(s.typ, a.info) else: s.ast
c.globals.add(sa)
s.position = c.globals.len
if a.sons[2].kind == nkEmpty:
when false:
withTemp(tmp, s.typ):
@ -1103,6 +1126,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
of skVar, skForVar, skTemp, skLet, skParam, skResult:
genRdVar(c, n, dest)
of skProc, skConverter, skMacro, skMethod, skIterator:
if sfImportc in s.flags: c.importcSym(n.info, s)
genLit(c, n, dest)
of skConst:
gen(c, s.ast, dest)
@ -1317,11 +1341,11 @@ proc genProc(c: PCtx; s: PSym): int =
c.patch(procStart)
c.gABC(body, opcEof, eofInstr.regA)
c.optimizeJumps(result)
s.position = c.prc.maxSlots
s.offset = c.prc.maxSlots
#if s.name.s == "innerProc":
# c.echoCode
# echo renderTree(body)
c.prc = oldPrc
else:
c.prc.maxSlots = s.position
c.prc.maxSlots = s.offset
result = x.intVal.int