From 6ddd4e6a3f46f4fdcaec8ae0b08758858085ec26 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Mon, 19 Aug 2013 01:27:05 +0300 Subject: Revert "Revert "bugfix: emulated thread vars used in combination with the mark & sweep GC"" This reverts commit 75c586bbe1cc649b36fc00362ab40ebb1d163d9f. --- compiler/cgen.nim | 3 +++ 1 file changed, 3 insertions(+) (limited to 'compiler/cgen.nim') diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 18f33f32a..b801add6c 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -284,6 +284,9 @@ proc genLineDir(p: BProc, t: PNode) = linefmt(p, cpsStmts, "nimln($1, $2);$n", line.toRope, t.info.quotedFilename) +proc accessThreadLocalVar(p: BProc, s: PSym) +proc emulatedThreadVars(): bool {.inline.} + include "ccgtypes.nim" # ------------------------------ Manager of temporaries ------------------ -- cgit 1.4.1-2-gfad0 From b01d9b6181be56b1300847cc1352652caa77e437 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Sat, 27 Jul 2013 10:17:58 +0300 Subject: work-in-progress for compiling generics in their owner module --- compiler/ccgstmts.nim | 2 +- compiler/cgen.nim | 12 +++++++++++- compiler/cgendata.nim | 4 +--- compiler/seminst.nim | 7 ++++--- 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'compiler/cgen.nim') diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 4d52e3aab..c3374a354 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -152,7 +152,7 @@ proc genSingleVar(p: BProc, a: PNode) = var immediateAsgn = a.sons[2].kind != nkEmpty if sfGlobal in v.flags: if v.owner.kind != skModule: - targetProc = p.module.preInitProc + targetProc = p.module.postInitProc assignGlobalVar(targetProc, v) # XXX: be careful here. # Global variables should not be zeromem-ed within loops diff --git a/compiler/cgen.nim b/compiler/cgen.nim index b801add6c..787a2143f 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1031,8 +1031,9 @@ proc genInitCode(m: BModule) = app(prc, initGCFrame(m.initProc)) app(prc, genSectionStart(cpsLocals)) - app(prc, m.initProc.s(cpsLocals)) app(prc, m.preInitProc.s(cpsLocals)) + app(prc, m.initProc.s(cpsLocals)) + app(prc, m.postInitProc.s(cpsLocals)) app(prc, genSectionEnd(cpsLocals)) if optStackTrace in m.initProc.options and not m.FrameDeclared: @@ -1048,11 +1049,13 @@ proc genInitCode(m: BModule) = app(prc, genSectionStart(cpsInit)) app(prc, m.preInitProc.s(cpsInit)) app(prc, m.initProc.s(cpsInit)) + app(prc, m.postInitProc.s(cpsInit)) app(prc, genSectionEnd(cpsInit)) app(prc, genSectionStart(cpsStmts)) app(prc, m.preInitProc.s(cpsStmts)) app(prc, m.initProc.s(cpsStmts)) + app(prc, m.postInitProc.s(cpsStmts)) app(prc, genSectionEnd(cpsStmts)) if optStackTrace in m.initProc.options and not m.PreventStackTrace: app(prc, deinitFrame(m.initProc)) @@ -1097,6 +1100,11 @@ proc newPreInitProc(m: BModule): BProc = # little hack so that unique temporaries are generated: result.labels = 100_000 +proc newPostInitProc(m: BModule): BProc = + result = newProc(nil, m) + # little hack so that unique temporaries are generated: + result.labels = 200_000 + proc rawNewModule(module: PSym, filename: string): BModule = new(result) InitLinkedList(result.headerFiles) @@ -1111,6 +1119,7 @@ proc rawNewModule(module: PSym, filename: string): BModule = result.initProc = newProc(nil, result) result.initProc.options = gOptions result.preInitProc = newPreInitProc(result) + result.postInitProc = newPostInitProc(result) initNodeTable(result.dataCache) result.typeStack = @[] result.forwardedProcs = @[] @@ -1131,6 +1140,7 @@ proc resetModule*(m: var BModule) = m.initProc = newProc(nil, m) m.initProc.options = gOptions m.preInitProc = newPreInitProc(m) + m.postInitProc = newPostInitProc(m) initNodeTable(m.dataCache) m.typeStack = @[] m.forwardedProcs = @[] diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index ad17194df..b5888d0f4 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -100,10 +100,8 @@ type headerFiles*: TLinkedList # needed headers to include typeInfoMarker*: TIntSet # needed for generating type information initProc*: BProc # code for init procedure + postInitProc*: BProc # code to be executed after the init proc preInitProc*: BProc # code executed before the init proc - # used for initialization code for - # .global. variables - # (or instantiated generic variables) typeStack*: TTypeSeq # used for type generation dataCache*: TNodeTable forwardedProcs*: TSymSeq # keep forwarded procs here diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 15be33261..47d889a60 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -233,11 +233,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # we set the friend module: var oldFriend = c.friendModule c.friendModule = getModule(fn) + #let oldScope = c.currentScope + #c.currentScope = fn.scope result = copySym(fn, false) incl(result.flags, sfFromGeneric) - # keep the owner if it's an inner proc (for proper closure transformations): - if fn.owner.kind == skModule: - result.owner = getCurrOwner().owner + result.owner = fn result.ast = n pushOwner(result) openScope(c) @@ -267,6 +267,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, popInfoContext() closeScope(c) # close scope for parameters popOwner() + #c.currentScope = oldScope c.friendModule = oldFriend dec(c.InstCounter) if result.kind == skMethod: finishMethod(c, result) -- cgit 1.4.1-2-gfad0 From ca3a4ce6721c87cfcbb9eb02002ecf8aeb89233c Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Thu, 15 Aug 2013 22:55:11 +0300 Subject: hacky fix for generic constraints matching --- compiler/ccgexprs.nim | 4 ++-- compiler/cgen.nim | 4 ++-- compiler/seminst.nim | 2 ++ compiler/sigmatch.nim | 23 ++++++++++++++++++++++- compiler/types.nim | 10 ++++++---- tests/reject/tgenconstraints.nim | 30 ++++++++++++++++++++++++++++++ tests/run/tfieldindex.nim | 2 +- tests/run/tfinally.nim | 10 +++------- 8 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 tests/reject/tgenconstraints.nim (limited to 'compiler/cgen.nim') diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index bb1035ab6..635756220 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1932,12 +1932,12 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = nil of nkPragma: genPragma(p, n) of nkProcDef, nkMethodDef, nkConverterDef: - if (n.sons[genericParamsPos].kind == nkEmpty): + if (n.sons[genericParamsPos].kind == nkEmpty): var prc = n.sons[namePos].sym # due to a bug/limitation in the lambda lifting, unused inner procs # are not transformed correctly. We work around this issue (#411) here # by ensuring it's no inner proc (owner is a module): - if prc.owner.kind == skModule: + if prc.skipGenericOwner.kind == skModule: if (optDeadCodeElim notin gGlobalOptions and sfDeadCodeElim notin getModule(prc).flags) or ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 787a2143f..0c3f2da84 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -861,8 +861,8 @@ proc isActivated(prc: PSym): bool = prc.typ != nil proc genProc(m: BModule, prc: PSym) = if sfBorrow in prc.flags or not isActivated(prc): return fillProcLoc(prc) - if {sfForward, sfFromGeneric} * prc.flags != {}: addForwardedProc(m, prc) - else: + if sfForward in prc.flags: addForwardedProc(m, prc) + else: genProcNoForward(m, prc) if {sfExportc, sfCompilerProc} * prc.flags == {sfExportc} and generatedHeader != nil and lfNoDecl notin prc.loc.Flags: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 47d889a60..601072833 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -87,6 +87,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) proc instantiateBody(c: PContext, n: PNode, result: PSym) = if n.sons[bodyPos].kind != nkEmpty: + inc c.InGenericInst # add it here, so that recursive generic procs are possible: addDecl(c, result) pushProcCon(c, result) @@ -107,6 +108,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = #echo "code instantiated ", result.name.s excl(result.flags, sfForward) popProcCon(c) + dec c.InGenericInst proc fixupInstantiatedSymbols(c: PContext, s: PSym) = for i in countup(0, c.generics.len - 1): diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 41268d6d0..626d16d64 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -38,6 +38,7 @@ type proxyMatch*: bool # to prevent instantiations genericConverter*: bool # true if a generic converter needs to # be instantiated + typedescMatched: bool inheritancePenalty: int # to prefer closest father object type TTypeRelation* = enum # order is important! @@ -499,8 +500,11 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation = of tyOrdinal: if isOrdinalType(a): var x = if a.kind == tyOrdinal: a.sons[0] else: a + result = typeRel(c, f.sons[0], x) if result < isGeneric: result = isNone + elif a.kind == tyGenericParam: + result = isGeneric of tyForward: InternalError("forward type in typeRel()") of tyNil: if a.kind == f.kind: result = isEqual @@ -618,7 +622,24 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation = of tyGenericParam, tyTypeClass: var x = PType(idTableGet(c.bindings, f)) if x == nil: - result = matchTypeClass(c, f, a) + if c.calleeSym.kind == skType and f.kind == tyGenericParam and not c.typedescMatched: + # XXX: The fact that generic types currently use tyGenericParam for + # their parameters is really a misnomer. tyGenericParam means "match + # any value" and what we need is "match any type", which can be encoded + # by a tyTypeDesc params. Unfortunately, this requires more substantial + # changes in semtypinst and elsewhere. + if a.kind == tyTypeDesc: + if f.sons == nil or f.sons.len == 0: + result = isGeneric + else: + InternalAssert a.sons != nil and a.sons.len > 0 + c.typedescMatched = true + result = typeRel(c, f.sons[0], a.sons[0]) + else: + result = isNone + else: + result = matchTypeClass(c, f, a) + if result == isGeneric: var concrete = concreteType(c, a) if concrete == nil: diff --git a/compiler/types.nim b/compiler/types.nim index b8aaed45e..2564741d8 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -969,8 +969,8 @@ proc skipGenericAlias*(t: PType): PType = proc matchTypeClass*(bindings: var TIdTable, typeClass, t: PType): bool = for i in countup(0, typeClass.sonsLen - 1): let req = typeClass.sons[i] - var match = req.kind == skipTypes(t, {tyGenericInst, tyRange}).kind or - req.kind == skipTypes(t, {tyGenericInst}).kind + var match = req.kind == skipTypes(t, {tyRange, tyGenericInst}).kind + if not match: case req.kind of tyGenericBody: @@ -979,7 +979,9 @@ proc matchTypeClass*(bindings: var TIdTable, typeClass, t: PType): bool = IdTablePut(bindings, typeClass, t) of tyTypeClass: match = matchTypeClass(bindings, req, t) - else: nil + elif t.kind == tyTypeClass: + match = matchTypeClass(bindings, t, req) + elif t.kind in {tyObject} and req.len != 0: # empty 'object' is fine as constraint in a type class match = sameType(t, req) @@ -1046,7 +1048,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind, result = typeAllowedAux(marker, lastSon(t), kind, flags) of tyRange: result = skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind in - {tyChar, tyEnum, tyInt..tyUInt64} + {tyChar, tyEnum, tyInt..tyFloat128} of tyOpenArray, tyVarargs: result = (kind == skParam) and typeAllowedAux(marker, t.sons[0], skVar, flags) of tySequence: diff --git a/tests/reject/tgenconstraints.nim b/tests/reject/tgenconstraints.nim new file mode 100644 index 000000000..e32aa877b --- /dev/null +++ b/tests/reject/tgenconstraints.nim @@ -0,0 +1,30 @@ +discard """ + file: "tgenconstraints.nim" + line: 25 + errormsg: "cannot instantiate T2" +""" + +type + T1[T: int|string] = object + x: T + + T2[T: Ordinal] = object + x: T + +var x1: T1[int] +var x2: T1[string] +var x3: T2[int] + +proc foo[T](x: T): T2[T] {.discardable.} = + var o: T1[T] + +foo(10) + +proc bar(x: string|TNumber): T1[type(x)] {.discardable.} = + when type(x) is TNumber: + var o: T2[type(x)] + +bar "test" +bar 100 +bar 1.1 + diff --git a/tests/run/tfieldindex.nim b/tests/run/tfieldindex.nim index 3ffa65e58..f0674af54 100644 --- a/tests/run/tfieldindex.nim +++ b/tests/run/tfieldindex.nim @@ -5,7 +5,7 @@ discard """ type TMyTuple = tuple[a, b: int] -proc indexOf*(t: typedesc, name: string): int {.compiletime.} = +proc indexOf*(t: typedesc, name: string): int = ## takes a tuple and looks for the field by name. ## returs index of that field. var diff --git a/tests/run/tfinally.nim b/tests/run/tfinally.nim index 273aac72b..16fb3e7da 100644 --- a/tests/run/tfinally.nim +++ b/tests/run/tfinally.nim @@ -1,8 +1,6 @@ discard """ file: "tfinally.nim" - output: '''came -here -3''' + output: "came\nhere\n3" """ # Test return in try statement: @@ -14,10 +12,8 @@ proc main: int = echo("came") return 2 finally: - echo("here ") + echo("here") return 3 - -echo main() #OUT came here 3 - +echo main() #OUT came here 3 -- cgit 1.4.1-2-gfad0