bugfix: typeinfo generation for tuples

This commit is contained in:
Araq 2011-06-19 15:47:10 +02:00
commit 18bec94e22
7 changed files with 82 additions and 41 deletions

View file

@ -641,20 +641,16 @@ proc genObjectInfo(m: BModule, typ: PType, name: PRope) =
genObjectFields(m, typ, typ.n, tmp)
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, tmp])
proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
var
tmp, expr, tmp2: PRope
length: int
a: PType
proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
genTypeInfoAuxBase(m, typ, name, toRope("0"))
expr = getNimNode(m)
length = sonsLen(typ)
var expr = getNimNode(m)
var length = sonsLen(typ)
if length > 0:
tmp = getTempName()
var tmp = getTempName()
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, toRope(length)])
for i in countup(0, length - 1):
a = typ.sons[i]
tmp2 = getNimNode(m)
var a = typ.sons[i]
var tmp2 = getNimNode(m)
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2])
appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
"$1.offset = offsetof($2, Field$3);$n" & "$1.typ = $4;$n" &
@ -665,7 +661,7 @@ proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
else:
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n",
[expr, toRope(length)])
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, tmp])
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, expr])
proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
# Type information for enumerations is quite heavy, so we do some

View file

@ -36,9 +36,8 @@ proc GenericCacheGet(c: PContext, genericSym, instSym: PSym): PSym =
var a = c.generics.sons[i].sons[0].sym
if genericSym.id == a.id:
var b = c.generics.sons[i].sons[1].sym
if equalParams(b.typ.n, instSym.typ.n) == paramsEqual:
#if gVerbosity > 0 then
# MessageOut('found in cache: ' + getProcHeader(instSym));
if equalParams(b.typ.n, instSym.typ.n) == paramsEqual:
#echo "found in cache: ", getProcHeader(instSym)
return b
proc GenericCacheAdd(c: PContext, genericSym, instSym: PSym) =
@ -66,20 +65,17 @@ proc removeDefaultParamValues(n: PNode) =
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym =
# generates an instantiated proc
var
oldPrc, oldMod: PSym
n: PNode
if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep")
inc(c.InstCounter)
# NOTE: for access of private fields within generics from a different module
# and other identifiers we fake the current module temporarily!
# XXX bad hack!
oldMod = c.module
var oldMod = c.module
c.module = getModule(fn)
result = copySym(fn, false)
incl(result.flags, sfFromGeneric)
result.owner = getCurrOwner().owner
n = copyTree(fn.ast)
var n = copyTree(fn.ast)
result.ast = n
pushOwner(result)
openScope(c.tab)
@ -98,7 +94,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
result.typ = newTypeS(tyProc, c)
addSon(result.typ, nil)
result.typ.callConv = fn.typ.callConv
oldPrc = GenericCacheGet(c, fn, result)
var oldPrc = GenericCacheGet(c, fn, result)
if oldPrc == nil:
# add it here, so that recursive generic procs are possible:
GenericCacheAdd(c, fn, result)
@ -110,6 +106,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
addResultNode(c, n)
n.sons[codePos] = semStmtScope(c, n.sons[codePos])
popProcCon(c)
#echo "code instantiated ", result.name.s
else:
result = oldPrc
popInfoContext()

View file

@ -32,7 +32,7 @@ proc containsGenericType*(t: PType): bool =
proc searchInstTypes(tab: TIdTable, key: PType): PType =
# returns nil if we need to declare this type
result = PType(IdTableGet(tab, key))
if (result == nil) and (tab.counter > 0):
if result == nil and tab.counter > 0:
# we have to do a slow linear search because types may need
# to be compared by their structure:
for h in countup(0, high(tab.data)):
@ -127,13 +127,13 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
of tyGenericBody:
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
result = ReplaceTypeVarsT(cl, lastSon(t))
else:
if containsGenericType(t):
else:
if containsGenericType(t):
result = copyType(t, t.owner, false)
for i in countup(0, sonsLen(result) - 1):
for i in countup(0, sonsLen(result) - 1):
result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i])
result.n = ReplaceTypeVarsN(cl, result.n)
if result.Kind in GenericTypes:
if result.Kind in GenericTypes:
LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName))
#writeln(output, ropeToStr(Typetoyaml(result)))
#checkConstructedType(cl.info, result)

View file

@ -514,10 +514,10 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
popTransCon(c)
proc getMagicOp(call: PNode): TMagic =
if (call.sons[0].kind == nkSym) and
(call.sons[0].sym.kind in {skProc, skMethod, skConverter}):
if call.sons[0].kind == nkSym and
call.sons[0].sym.kind in {skProc, skMethod, skConverter}:
result = call.sons[0].sym.magic
else:
else:
result = mNone
proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
@ -528,10 +528,10 @@ proc gatherVars(c: PTransf, n: PNode, marked: var TIntSet, owner: PSym,
var s = n.sym
var found = false
case s.kind
of skVar: found = not (sfGlobal in s.flags)
of skVar: found = sfGlobal notin s.flags
of skTemp, skForVar, skParam: found = true
else: nil
if found and (owner.id != s.owner.id) and not ContainsOrIncl(marked, s.id):
if found and owner.id != s.owner.id and not ContainsOrIncl(marked, s.id):
incl(s.flags, sfInClosure)
addSon(container, copyNode(n)) # DON'T make a copy of the symbol!
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit:
@ -559,7 +559,7 @@ proc indirectAccess(a, b: PSym): PNode =
proc transformLambda(c: PTransf, n: PNode): PNode =
var marked = initIntSet()
result = n
if (n.sons[namePos].kind != nkSym): InternalError(n.info, "transformLambda")
if n.sons[namePos].kind != nkSym: InternalError(n.info, "transformLambda")
var s = n.sons[namePos].sym
var closure = newNodeI(nkRecList, n.sons[codePos].info)
gatherVars(c, n.sons[codePos], marked, s, closure)