mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 14:32:53 +00:00
compilation cache: DLL interfacing now works
This commit is contained in:
@@ -531,7 +531,9 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
|
||||
var check = initIntSet()
|
||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
|
||||
genProcParams(m, prc.typ, rettype, params, check)
|
||||
genCLineDir(result, prc.ast.sons[codePos])
|
||||
# careful here! don't access ``prc.ast`` as that could reload large parts of
|
||||
# the object graph!
|
||||
genCLineDir(result, prc.info)
|
||||
appf(result, "$1($2, $3)$4",
|
||||
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r, params])
|
||||
|
||||
|
||||
@@ -148,9 +148,9 @@ proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
||||
args: openarray[PRope]) =
|
||||
app(p.s[s], ropecg(p.module, frmt, args))
|
||||
|
||||
proc safeLineNm(t: PNode) : int =
|
||||
result = toLinenumber(t.info) # BUGFIX
|
||||
if result < 0: result = 0 # negative numbers are not allowed in #line
|
||||
proc safeLineNm(info: TLineInfo): int =
|
||||
result = toLinenumber(info)
|
||||
if result < 0: result = 0 # negative numbers are not allowed in #line
|
||||
|
||||
proc genCLineDir(r: var PRope, filename: string, line: int) =
|
||||
assert line >= 0
|
||||
@@ -158,11 +158,11 @@ proc genCLineDir(r: var PRope, filename: string, line: int) =
|
||||
appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
|
||||
[toRope(makeSingleLineCString(filename)), toRope(line)])
|
||||
|
||||
proc genCLineDir(r: var PRope, t: PNode) =
|
||||
genCLineDir(r, t.info.toFullPath, t.safeLineNm)
|
||||
proc genCLineDir(r: var PRope, info: TLineInfo) =
|
||||
genCLineDir(r, info.toFullPath, info.safeLineNm)
|
||||
|
||||
proc genLineDir(p: BProc, t: PNode) =
|
||||
var line = t.safeLineNm
|
||||
var line = t.info.safeLineNm
|
||||
genCLineDir(p.s[cpsStmts], t.info.toFullPath, line)
|
||||
if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
|
||||
(p.prc == nil or sfPure notin p.prc.flags):
|
||||
@@ -447,7 +447,6 @@ proc SymInDynamicLib(m: BModule, sym: PSym) =
|
||||
var lib = sym.annex
|
||||
var extname = sym.loc.r
|
||||
loadDynamicLib(m, lib)
|
||||
#discard cgsym(m, "nimGetProcAddr")
|
||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
||||
var tmp = mangleDynLibProc(sym)
|
||||
sym.loc.r = tmp # from now on we only need the internal name
|
||||
@@ -461,6 +460,10 @@ proc SymInDynamicLib(m: BModule, sym: PSym) =
|
||||
"$1 = linkonce global $2 zeroinitializer$n",
|
||||
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
|
||||
|
||||
proc SymInDynamicLibPartial(m: BModule, sym: PSym) =
|
||||
sym.loc.r = mangleDynLibProc(sym)
|
||||
sym.typ.sym = nil # generate a new name
|
||||
|
||||
proc cgsym(m: BModule, name: string): PRope =
|
||||
var sym = magicsys.getCompilerProc(name)
|
||||
if sym != nil:
|
||||
@@ -583,7 +586,7 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
useHeader(m, sym)
|
||||
if lfNoDecl in sym.loc.Flags: return
|
||||
if lfDynamicLib in sym.loc.Flags:
|
||||
if lfDynamicLib in sym.loc.Flags:
|
||||
if sym.owner.id != m.module.id and
|
||||
not ContainsOrIncl(m.declaredThings, sym.id):
|
||||
appf(m.s[cfsVars], "extern $1 $2;$n",
|
||||
@@ -610,6 +613,8 @@ proc genProcNoForward(m: BModule, prc: PSym) =
|
||||
var q = findPendingModule(m, prc)
|
||||
if q != nil and not ContainsOrIncl(q.declaredThings, prc.id):
|
||||
SymInDynamicLib(q, prc)
|
||||
else:
|
||||
SymInDynamicLibPartial(m, prc)
|
||||
elif sfImportc notin prc.flags:
|
||||
var q = findPendingModule(m, prc)
|
||||
if q != nil and not ContainsOrIncl(q.declaredThings, prc.id):
|
||||
|
||||
@@ -334,7 +334,7 @@ proc addFileToLink*(filename: string) =
|
||||
# BUGFIX: was ``appendStr``
|
||||
|
||||
proc execExternalProgram*(cmd: string) =
|
||||
if (optListCmd in gGlobalOptions) or (gVerbosity > 0): MsgWriteln(cmd)
|
||||
if optListCmd in gGlobalOptions or gVerbosity > 0: MsgWriteln(cmd)
|
||||
if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "")
|
||||
|
||||
proc generateScript(projectFile: string, script: PRope) =
|
||||
|
||||
@@ -70,11 +70,6 @@ proc getOrdValue*(n: PNode): biggestInt
|
||||
proc computeSize*(typ: PType): biggestInt
|
||||
proc getSize*(typ: PType): biggestInt
|
||||
proc isPureObject*(typ: PType): bool
|
||||
proc inheritanceDiff*(a, b: PType): int
|
||||
# | returns: 0 iff `a` == `b`
|
||||
# | returns: -x iff `a` is the x'th direct superclass of `b`
|
||||
# | returns: +x iff `a` is the x'th direct subclass of `b`
|
||||
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
||||
proc InvalidGenericInst*(f: PType): bool
|
||||
# for debugging
|
||||
type
|
||||
@@ -93,22 +88,6 @@ proc typeAllowed*(t: PType, kind: TSymKind): bool
|
||||
proc InvalidGenericInst(f: PType): bool =
|
||||
result = (f.kind == tyGenericInst) and (lastSon(f) == nil)
|
||||
|
||||
proc inheritanceDiff(a, b: PType): int =
|
||||
# conversion to superclass?
|
||||
var x = a
|
||||
result = 0
|
||||
while x != nil:
|
||||
if x.id == b.id: return
|
||||
x = x.sons[0]
|
||||
dec(result)
|
||||
var y = b
|
||||
result = 0
|
||||
while y != nil:
|
||||
if y.id == a.id: return
|
||||
y = y.sons[0]
|
||||
inc(result)
|
||||
result = high(int)
|
||||
|
||||
proc isPureObject(typ: PType): bool =
|
||||
var t = typ
|
||||
while t.sons[0] != nil: t = t.sons[0]
|
||||
@@ -553,24 +532,19 @@ type
|
||||
|
||||
TSameTypeClosure = object {.pure.}
|
||||
cmp: TDistinctCompare
|
||||
initSets: bool
|
||||
recCheck: int
|
||||
a: TIntSet
|
||||
b: TIntSet
|
||||
s: seq[tuple[a,b: int]] # seq for a set as it's hopefully faster
|
||||
# (few elements expected)
|
||||
|
||||
proc initSameTypeClosure: TSameTypeClosure =
|
||||
# we do the initialization lazy for performance (avoids memory allocations)
|
||||
nil
|
||||
|
||||
proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool =
|
||||
result = c.initSets and c.a.contains(a.id) and c.b.contains(b.id)
|
||||
result = not IsNil(c.s) and c.s.contains((a.id, b.id))
|
||||
if not result:
|
||||
if not c.initSets:
|
||||
c.initSets = true
|
||||
c.a = initIntSet()
|
||||
c.b = initIntSet()
|
||||
c.a.incl(a.id)
|
||||
c.b.incl(b.id)
|
||||
if IsNil(c.s): c.s = @[]
|
||||
c.s.add((a.id, b.id))
|
||||
|
||||
proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool
|
||||
proc SameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool =
|
||||
@@ -731,7 +705,7 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||
# again: Since the recursion check is only to not get caught in an endless
|
||||
# recursion, we use a counter and only if it's value is over some
|
||||
# threshold we perform the expansive exact cycle check:
|
||||
if c.recCheck < 20:
|
||||
if c.recCheck < 3:
|
||||
inc c.recCheck
|
||||
else:
|
||||
if containsOrIncl(c, a, b): return true
|
||||
@@ -797,6 +771,25 @@ proc compareTypes*(x, y: PType, cmp: TDistinctCompare): bool =
|
||||
c.cmp = cmp
|
||||
result = sameTypeAux(x, y, c)
|
||||
|
||||
proc inheritanceDiff*(a, b: PType): int =
|
||||
# | returns: 0 iff `a` == `b`
|
||||
# | returns: -x iff `a` is the x'th direct superclass of `b`
|
||||
# | returns: +x iff `a` is the x'th direct subclass of `b`
|
||||
# | returns: `maxint` iff `a` and `b` are not compatible at all
|
||||
var x = a
|
||||
result = 0
|
||||
while x != nil:
|
||||
if sameObjectTypes(x, b): return
|
||||
x = x.sons[0]
|
||||
dec(result)
|
||||
var y = b
|
||||
result = 0
|
||||
while y != nil:
|
||||
if sameObjectTypes(y, a): return
|
||||
y = y.sons[0]
|
||||
inc(result)
|
||||
result = high(int)
|
||||
|
||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
||||
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
||||
result = true
|
||||
|
||||
4
todo.txt
4
todo.txt
@@ -16,7 +16,6 @@ Version 0.8.14
|
||||
incremental compilation
|
||||
-----------------------
|
||||
|
||||
- fix DLL interfacing!
|
||||
- the loading has to be MUCH more lazy! --> next version: We should re-load
|
||||
symbol.ast lazily
|
||||
- adapt thread var implementation to care about the new merge operation
|
||||
@@ -28,6 +27,7 @@ incremental compilation
|
||||
- test type converters
|
||||
- test G, A, B example from the documentation; test init sections
|
||||
- test method generation
|
||||
- test DLL interfacing
|
||||
|
||||
|
||||
version 0.9.0
|
||||
@@ -35,7 +35,7 @@ version 0.9.0
|
||||
|
||||
- test the sort implementation again
|
||||
- const ptr/ref
|
||||
- unsigned ints and bignums
|
||||
- unsigned ints and bignums; requires abstract integer literal type
|
||||
- implement the high level optimizer
|
||||
- warning for implicit openArray -> varargs convention
|
||||
- implement explicit varargs
|
||||
|
||||
Reference in New Issue
Block a user