Skip to content

Commit

Permalink
signature hashing: more progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Nov 11, 2016
1 parent 72af7e6 commit 860cbd3
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 300 deletions.
71 changes: 33 additions & 38 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
of tyUInt64: result = uint64Literal(uint64(n.intVal))
else:
result = "(($1) $2)" % [getTypeDesc(p.module,
skipTypes(ty, abstractVarRange)), intLiteral(n.intVal)]
ty), intLiteral(n.intVal)]
of nkNilLit:
let t = skipTypes(ty, abstractVarRange)
if t.kind == tyProc and t.callConv == ccClosure:
Expand All @@ -61,7 +61,7 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
inc(p.module.labels)
addf(p.module.s[cfsData],
"static NIM_CONST $1 $2 = {NIM_NIL,NIM_NIL};$n",
[getTypeDesc(p.module, t), result])
[getTypeDesc(p.module, ty), result])
else:
result = rope("NIM_NIL")
of nkStrLit..nkTripleStrLit:
Expand Down Expand Up @@ -266,7 +266,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# little HACK to support the new 'var T' as return type:
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
return
var ty = skipTypes(dest.t, abstractRange)
let ty = skipTypes(dest.t, abstractRange)
case ty.kind
of tyRef:
genRefAssign(p, dest, src, flags)
Expand Down Expand Up @@ -315,8 +315,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
genGenericAsgn(p, dest, src, flags)
elif needsComplexAssignment(ty):
if ty.sons[0].isNil and asgnComplexity(ty.n) <= 4:
discard getTypeDesc(p.module, ty)
ty = getUniqueType(ty)
discard getTypeDesc(p.module, dest.t)
internalAssert ty.n != nil
genOptAsgnObject(p, dest, src, flags, ty.n)
else:
Expand All @@ -330,7 +329,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
useStringh(p.module)
linefmt(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
rdLoc(dest), rdLoc(src), getTypeDesc(p.module, ty))
rdLoc(dest), rdLoc(src), getTypeDesc(p.module, dest.t))
of tyOpenArray, tyVarargs:
# open arrays are always on the stack - really? What if a sequence is
# passed to an open array?
Expand Down Expand Up @@ -494,12 +493,12 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
# later via 'chckRange'
let t = e.typ.skipTypes(abstractRange)
if optOverflowCheck notin p.options:
let res = opr[m] % [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)]
let res = opr[m] % [getTypeDesc(p.module, e.typ), rdLoc(a), rdLoc(b)]
putIntoDest(p, d, e.typ, res)
else:
let res = binaryArithOverflowRaw(p, t, a, b,
if t.kind == tyInt64: prc64[m] else: prc[m])
putIntoDest(p, d, e.typ, "($#)($#)" % [getTypeDesc(p.module, t), res])
putIntoDest(p, d, e.typ, "($#)($#)" % [getTypeDesc(p.module, e.typ), res])

proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
const
Expand Down Expand Up @@ -700,12 +699,11 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
template inheritLocation(d: var TLoc, a: TLoc) =
if d.k == locNone: d.s = a.s

proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc) =
initLocExpr(p, e.sons[0], a)
if e.sons[1].kind != nkSym: internalError(e.info, "genRecordFieldAux")
d.inheritLocation(a)
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
result = a.t.getUniqueType

proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
var
Expand All @@ -714,13 +712,12 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[0], a)
d.inheritLocation(a)
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
var ty = a.t.getUniqueType
var r = rdLoc(a)
case e.sons[1].kind
of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal)
else: internalError(e.info, "genTupleElem")
addf(r, ".Field$1", [rope(i)])
putIntoDest(p, d, ty.sons[i], r, a.s)
putIntoDest(p, d, a.t.sons[i], r, a.s)

proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope): PSym =
var ty = ty
Expand All @@ -731,22 +728,23 @@ proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope): PSym =
result = lookupInRecord(ty.n, field.name)
if result != nil: break
if not p.module.compileToCpp: add(r, ".Sup")
ty = getUniqueType(ty.sons[0])
ty = ty.sons[0]
if result == nil: internalError(field.info, "genCheckedRecordField")

proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
var a: TLoc
var ty = genRecordFieldAux(p, e, d, a)
genRecordFieldAux(p, e, d, a)
var r = rdLoc(a)
var f = e.sons[1].sym
let ty = skipTypes(a.t, abstractInst)
if ty.kind == tyTuple:
# we found a unique tuple type which lacks field information
# so we use Field$i
addf(r, ".Field$1", [rope(f.position)])
putIntoDest(p, d, f.typ, r, a.s)
else:
let field = lookupFieldAgain(p, ty, f, r)
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
if field.loc.r == nil: internalError(e.info, "genRecordField 3 " & typeToString(ty))
addf(r, ".$1", [field.loc.r])
putIntoDest(p, d, field.typ, r, a.s)
#d.s = a.s
Expand Down Expand Up @@ -789,7 +787,8 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym;
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
if optFieldCheck in p.options:
var a: TLoc
let ty = genRecordFieldAux(p, e.sons[0], d, a)
genRecordFieldAux(p, e.sons[0], d, a)
let ty = skipTypes(a.t, abstractInst)
var r = rdLoc(a)
let f = e.sons[0].sons[1].sym
let field = lookupFieldAgain(p, ty, f, r)
Expand Down Expand Up @@ -1029,10 +1028,10 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
var a, b, dest: TLoc
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
let bt = skipTypes(e.sons[2].typ, abstractVar)
let bt = skipTypes(e.sons[2].typ, {tyVar})
lineCg(p, cpsStmts, seqAppendPattern, [
rdLoc(a),
getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
getTypeDesc(p.module, e.sons[1].typ),
getTypeDesc(p.module, bt)])
#if bt != b.t:
# echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t)
Expand All @@ -1046,16 +1045,17 @@ proc genReset(p: BProc, n: PNode) =
var a: TLoc
initLocExpr(p, n.sons[1], a)
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange)))
addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, {tyVar})))

proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
var sizeExpr = sizeExpr
let refType = skipTypes(a.t, abstractVarRange)
let refType = a.t
var b: TLoc
initLoc(b, locExpr, a.t, OnHeap)
let bt = refType.lastSon
if sizeExpr.isNil:
sizeExpr = "sizeof($1)" %
[getTypeDesc(p.module, skipTypes(refType.sons[0], abstractRange))]
[getTypeDesc(p.module, bt)]
let args = [getTypeDesc(p.module, refType),
genTypeInfo(p.module, refType),
sizeExpr]
Expand All @@ -1070,7 +1070,6 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
else:
b.r = ropecg(p.module, "($1) #newObj($2, $3)", args)
genAssignment(p, a, b, {}) # set the object type:
let bt = skipTypes(refType.sons[0], abstractRange)
genObjectInit(p, cpsStmts, bt, a, false)

proc genNew(p: BProc, e: PNode) =
Expand Down Expand Up @@ -1122,7 +1121,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
proc genConstExpr(p: BProc, n: PNode): Rope
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
if d.k == locNone and n.len > ord(n.kind == nkObjConstr) and n.isDeepConstExpr:
var t = getUniqueType(n.typ)
let t = n.typ
discard getTypeDesc(p.module, t) # so that any fields are initialized
let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels)
fillLoc(d, locData, t, p.module.tmpBase & rope(id), OnStatic)
Expand Down Expand Up @@ -1322,7 +1321,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
gcUsage(e)

proc genGetTypeInfo(p: BProc, e: PNode, d: var TLoc) =
var t = skipTypes(e.sons[1].typ, abstractVarRange)
let t = e.sons[1].typ
putIntoDest(p, d, e.typ, genTypeInfo(p.module, t))

proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
Expand All @@ -1336,7 +1335,7 @@ proc genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) =
proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
var a = e.sons[1]
if a.kind == nkHiddenAddr: a = a.sons[0]
var typ = skipTypes(a.typ, abstractVar)
let typ = skipTypes(a.typ, abstractVar)
case typ.kind
of tyOpenArray, tyVarargs:
if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)")
Expand All @@ -1363,15 +1362,15 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
assert(d.k == locNone)
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
var t = skipTypes(e.sons[1].typ, abstractVar)
let t = skipTypes(e.sons[1].typ, {tyVar})
let setLenPattern = if not p.module.compileToCpp:
"$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
else:
"$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"

lineCg(p, cpsStmts, setLenPattern, [
rdLoc(a), rdLoc(b), getTypeDesc(p.module, t),
getTypeDesc(p.module, t.sons[0])])
getTypeDesc(p.module, t.skipTypes(abstractInst).sons[0])])
gcUsage(e)

proc genSetLengthStr(p: BProc, e: PNode, d: var TLoc) =
Expand Down Expand Up @@ -1562,7 +1561,7 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
var tmp: TLoc
tmp.r = "LOC$1.source" % [lbl]
linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
getTypeDesc(p.module, srct), getTypeDesc(p.module, destt), lbl)
getTypeDesc(p.module, e.sons[1].typ), getTypeDesc(p.module, e.typ), lbl)
tmp.k = locExpr
tmp.t = srct
tmp.s = OnStack
Expand Down Expand Up @@ -1796,7 +1795,7 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
var rec: TLoc
if not handleConstExpr(p, n, d):
var t = getUniqueType(n.typ)
let t = n.typ
discard getTypeDesc(p.module, t) # so that any fields are initialized
if d.k == locNone: getTemp(p, t, d)
for i in countup(0, sonsLen(n) - 1):
Expand All @@ -1805,11 +1804,6 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
initLoc(rec, locExpr, it.typ, d.s)
rec.r = "$1.Field$2" % [rdLoc(d), rope(i)]
expr(p, it, rec)
when false:
initLoc(rec, locExpr, it.typ, d.s)
if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genTupleConstr")
rec.r = "$1.$2" % [rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)]
expr(p, it, rec)

proc isConstClosure(n: PNode): bool {.inline.} =
result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
Expand Down Expand Up @@ -1863,7 +1857,7 @@ proc genStmtListExpr(p: BProc, n: PNode, d: var TLoc) =
proc upConv(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc
initLocExpr(p, n.sons[0], a)
var dest = skipTypes(n.typ, abstractPtrs)
let dest = skipTypes(n.typ, abstractPtrs)
if optObjCheck in p.options and not isObjLackingTypeField(dest):
var r = rdLoc(a)
var nilCheck: Rope = nil
Expand Down Expand Up @@ -1925,7 +1919,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
putIntoDest(p, d, n.typ, r, a.s)

proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
var t = getUniqueType(n.typ)
let t = n.typ
discard getTypeDesc(p.module, t) # so that any fields are initialized
let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels)
let tmp = p.module.tmpBase & rope(id)
Expand Down Expand Up @@ -2161,13 +2155,14 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): Rope =
data.add("}")

result = getTempName(p.module)
let base = t.skipTypes(abstractInst).sons[0]

appcg(p.module, cfsData,
"NIM_CONST struct {$n" &
" #TGenericSeq Sup;$n" &
" $1 data[$2];$n" &
"} $3 = $4;$n", [
getTypeDesc(p.module, t.sons[0]), n.len.rope, result, data])
getTypeDesc(p.module, base), n.len.rope, result, data])

result = "(($1)&$2)" % [getTypeDesc(p.module, t), result]

Expand All @@ -2182,7 +2177,7 @@ proc genConstExpr(p: BProc, n: PNode): Rope =
of nkBracket, nkPar, nkClosure, nkObjConstr:
var t = skipTypes(n.typ, abstractInst)
if t.kind == tySequence:
result = genConstSeq(p, n, t)
result = genConstSeq(p, n, n.typ)
else:
result = genConstSimpleList(p, n)
else:
Expand Down
27 changes: 14 additions & 13 deletions compiler/ccgmerge.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import
ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils,
intsets, platform, llstream
intsets, platform, llstream, tables, sighashes

# Careful! Section marks need to contain a tabulator so that they cannot
# be part of C string literals.
Expand Down Expand Up @@ -69,17 +69,17 @@ proc genSectionEnd*(ps: TCProcSection): Rope =
if compilationCachePresent:
result = rope(NimMergeEndMark & tnl)

proc writeTypeCache(a: TIdTable, s: var string) =
proc writeTypeCache(a: TypeCache, s: var string) =
var i = 0
for id, value in pairs(a):
if i == 10:
i = 0
s.add(tnl)
else:
s.add(' ')
encodeVInt(id, s)
encodeStr($id, s)
s.add(':')
encodeStr($Rope(value), s)
encodeStr($value, s)
inc i
s.add('}')

Expand All @@ -103,8 +103,9 @@ proc genMergeInfo*(m: BModule): Rope =
writeTypeCache(m.typeCache, s)
s.add("declared:{")
writeIntSet(m.declaredThings, s)
s.add("typeInfo:{")
writeIntSet(m.typeInfoMarker, s)
when false:
s.add("typeInfo:{")
writeIntSet(m.typeInfoMarker, s)
s.add("labels:")
encodeVInt(m.labels, s)
s.add(" flags:")
Expand Down Expand Up @@ -185,19 +186,18 @@ proc newFakeType(id: int): PType =
new(result)
result.id = id

proc readTypeCache(L: var TBaseLexer, result: var TIdTable) =
proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
if ^L.bufpos != '{': internalError("ccgmerge: '{' expected")
inc L.bufpos
while ^L.bufpos != '}':
skipWhite(L)
var key = decodeVInt(L.buf, L.bufpos)
var key = decodeStr(L.buf, L.bufpos)
if ^L.bufpos != ':': internalError("ccgmerge: ':' expected")
inc L.bufpos
var value = decodeStr(L.buf, L.bufpos)
# XXX little hack: we create a "fake" type object with the correct Id
# better would be to adapt the data structure to not even store the
# object as key, but only the Id
idTablePut(result, newFakeType(key), value.rope)
# XXX implement me
when false:
idTablePut(result, newFakeType(key), value.rope)
inc L.bufpos

proc readIntSet(L: var TBaseLexer, result: var IntSet) =
Expand All @@ -220,7 +220,8 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
case k
of "typeCache": readTypeCache(L, m.typeCache)
of "declared": readIntSet(L, m.declaredThings)
of "typeInfo": readIntSet(L, m.typeInfoMarker)
of "typeInfo":
when false: readIntSet(L, m.typeInfoMarker)
of "labels": m.labels = decodeVInt(L.buf, L.bufpos)
of "flags":
m.flags = cast[set[CodegenFlag]](decodeVInt(L.buf, L.bufpos) != 0)
Expand Down
Loading

0 comments on commit 860cbd3

Please sign in to comment.