diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index fafc19210e..b5ecee5da0 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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]) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 51d6f2f849..a5343e3f7b 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -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): diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index b48c65f872..485ccc7d48 100755 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -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) = diff --git a/compiler/types.nim b/compiler/types.nim index 7c88e23352..9d5d12b06b 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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 diff --git a/todo.txt b/todo.txt index 8e12797bbe..84543fae9e 100755 --- a/todo.txt +++ b/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