Skip to content

Commit

Permalink
Merge branch 'version-0-19'
Browse files Browse the repository at this point in the history
  • Loading branch information
narimiran committed May 13, 2019
2 parents 7f3b686 + c6f601d commit fa7e6b3
Show file tree
Hide file tree
Showing 36 changed files with 335 additions and 150 deletions.
9 changes: 8 additions & 1 deletion compiler/aliases.nim
Expand Up @@ -181,9 +181,16 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
else: discard
of nkObjConstr:
result = arNo
for i in 1..<b.len:
for i in 1 ..< b.len:
let res = isPartOf(a, b[i][1])
if res != arNo:
result = res
if res == arYes: break
of nkCall:
result = arNo
for i in 1 ..< b.len:
let res = isPartOf(a, b[i])
if res != arNo:
result = res
if res == arYes: break
else: discard
15 changes: 7 additions & 8 deletions compiler/ast.nim
Expand Up @@ -990,7 +990,7 @@ const
miscPos* = 5 # used for undocumented and hacky stuff
bodyPos* = 6 # position of body; use rodread.getBody() instead!
resultPos* = 7
dispatcherPos* = 8 # caution: if method has no 'result' it can be position 7!
dispatcherPos* = 8

nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
nkCommand, nkCallStrLit, nkHiddenCallConv}
Expand Down Expand Up @@ -1711,28 +1711,27 @@ proc toVar*(typ: PType): PType =
proc toRef*(typ: PType): PType =
## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
## returned. Otherwise ``typ`` is simply returned as-is.
result = typ
if typ.kind == tyObject:
if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
result = newType(tyRef, typ.owner)
rawAddSon(result, typ)

proc toObject*(typ: PType): PType =
## If ``typ`` is a tyRef then its immediate son is returned (which in many
## cases should be a ``tyObject``).
## Otherwise ``typ`` is simply returned as-is.
result = typ
if result.kind == tyRef:
result = result.lastSon
let t = typ.skipTypes({tyAlias, tyGenericInst})
if t.kind == tyRef: t.lastSon
else: typ

proc isException*(t: PType): bool =
# check if `y` is object type and it inherits from Exception
assert(t != nil)

if t.kind != tyObject:
if t.kind notin {tyObject, tyGenericInst}:
return false

var base = t
while base != nil:
while base != nil and base.kind in {tyRef, tyObject, tyGenericInst}:
if base.sym != nil and base.sym.magic == mException:
return true
base = base.lastSon
Expand Down
1 change: 0 additions & 1 deletion compiler/ccgtypes.nim
Expand Up @@ -165,7 +165,6 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
of tySet:
if mapSetType(conf, base) == ctArray: result = ctPtrToArray
else: result = ctPtr
# XXX for some reason this breaks the pegs module
else: result = ctPtr
of tyPointer: result = ctPtr
of tySequence: result = ctNimSeq
Expand Down
20 changes: 10 additions & 10 deletions compiler/cgmeth.nim
Expand Up @@ -37,10 +37,9 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =

proc getDispatcher*(s: PSym): PSym =
## can return nil if is has no dispatcher.
let dispn = lastSon(s.ast)
if dispn.kind == nkSym:
let disp = dispn.sym
if sfDispatcher in disp.flags: result = disp
if dispatcherPos < s.ast.len:
result = s.ast[dispatcherPos].sym
doAssert sfDispatcher in result.flags

proc methodCall*(n: PNode; conf: ConfigRef): PNode =
result = n
Expand Down Expand Up @@ -99,13 +98,14 @@ proc sameMethodBucket(a, b: PSym): MethodResult =
return No

proc attachDispatcher(s: PSym, dispatcher: PNode) =
var L = s.ast.len-1
var x = s.ast.sons[L]
if x.kind == nkSym and sfDispatcher in x.sym.flags:
if dispatcherPos < s.ast.len:
# we've added a dispatcher already, so overwrite it
s.ast.sons[L] = dispatcher
s.ast.sons[dispatcherPos] = dispatcher
else:
s.ast.add(dispatcher)
setLen(s.ast.sons, dispatcherPos+1)
if s.ast[resultPos] == nil:
s.ast[resultPos] = newNodeI(nkEmpty, s.info)
s.ast.sons[dispatcherPos] = dispatcher

proc createDispatcher(s: PSym): PSym =
var disp = copySym(s)
Expand Down Expand Up @@ -165,7 +165,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
case sameMethodBucket(disp, s)
of Yes:
add(g.methods[i].methods, s)
attachDispatcher(s, lastSon(disp.ast))
attachDispatcher(s, disp.ast[dispatcherPos])
fixupDispatcher(s, disp, g.config)
#echo "fixup ", disp.name.s, " ", disp.id
when useEffectSystem: checkMethodEffects(g, disp, s)
Expand Down
4 changes: 2 additions & 2 deletions compiler/commands.nim
Expand Up @@ -48,14 +48,14 @@ const
"Copyright (c) 2006-" & copyrightYear & " by Andreas Rumpf\n"

const
Usage = slurp"../doc/basicopt.txt".replace("//", "")
Usage = slurp"../doc/basicopt.txt".replace(" //", " ")
FeatureDesc = block:
var x = ""
for f in low(Feature)..high(Feature):
if x.len > 0: x.add "|"
x.add $f
x
AdvancedUsage = slurp"../doc/advopt.txt".replace("//", "") % FeatureDesc
AdvancedUsage = slurp"../doc/advopt.txt".replace(" //", " ") % FeatureDesc

proc getCommandLineDesc(conf: ConfigRef): string =
result = (HelpMessage % [VersionAsString, platform.OS[conf.target.hostOS].name,
Expand Down
1 change: 1 addition & 0 deletions compiler/importer.nim
Expand Up @@ -92,6 +92,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
rawImportSymbol(c, e)
e = nextIdentIter(it, fromMod.tab)
else: rawImportSymbol(c, s)
suggestSym(c.config, n.info, s, c.graph.usageSym, false)

proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
var i: TTabIter
Expand Down
5 changes: 3 additions & 2 deletions compiler/jsgen.nim
Expand Up @@ -476,6 +476,7 @@ proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string,
r.res = "$1 = (($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer]
else:
r.res = "(($1 $2 $3) $4)" % [x.rdLoc, rope op, y.rdLoc, trimmer]
r.kind = resExpr

proc ternaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
var x, y, z: TCompRes
Expand Down Expand Up @@ -1706,13 +1707,13 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mHigh:
unaryExpr(p, n, r, "", "($1 != null ? ($1.length-1) : -1)")
of mInc:
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
if n[1].typ.skipTypes(abstractRange).kind in {tyUInt..tyUInt64}:
binaryUintExpr(p, n, r, "+", true)
else:
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 += $2")
else: binaryExpr(p, n, r, "addInt", "$1 = addInt($1, $2)")
of ast.mDec:
if n[1].typ.skipTypes(abstractRange).kind in tyUInt .. tyUInt64:
if n[1].typ.skipTypes(abstractRange).kind in {tyUInt..tyUInt64}:
binaryUintExpr(p, n, r, "-", true)
else:
if optOverflowCheck notin p.options: binaryExpr(p, n, r, "", "$1 -= $2")
Expand Down
7 changes: 4 additions & 3 deletions compiler/semstmts.nim
Expand Up @@ -823,11 +823,12 @@ proc semRaise(c: PContext, n: PNode): PNode =
checkSonsLen(n, 1, c.config)
if n[0].kind != nkEmpty:
n[0] = semExprWithType(c, n[0])
let typ = n[0].typ
var typ = n[0].typ
if not isImportedException(typ, c.config):
if typ.kind != tyRef or typ.lastSon.kind != tyObject:
typ = typ.skipTypes({tyAlias, tyGenericInst})
if typ.kind != tyRef:
localError(c.config, n.info, errExprCannotBeRaised)
if typ.len > 0 and not isException(typ.lastSon):
if not isException(typ.lastSon):
localError(c.config, n.info, "raised object of type $1 does not inherit from Exception",
[typeToString(typ)])

Expand Down
6 changes: 3 additions & 3 deletions compiler/semtypes.nim
Expand Up @@ -725,8 +725,8 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int,
of nkOfBranch, nkElse:
addInheritedFieldsAux(c, check, pos, lastSon(n.sons[i]))
else: internalError(c.config, n.info, "addInheritedFieldsAux(record case branch)")
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
of nkRecList, nkRecWhen, nkElifBranch, nkElse:
for i in 0 ..< sonsLen(n):
addInheritedFieldsAux(c, check, pos, n.sons[i])
of nkSym:
incl(check, n.sym.name.id)
Expand Down Expand Up @@ -972,7 +972,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
if lifted != nil: paramType.sons[i] = lifted

let body = paramType.base
if body.kind == tyForward:
if body.kind in {tyForward, tyError}:
# this may happen for proc type appearing in a type section
# before one of its param types
return
Expand Down
6 changes: 4 additions & 2 deletions compiler/semtypinst.nim
Expand Up @@ -67,11 +67,10 @@ proc cacheTypeInst*(inst: PType) =
# update the refcount
let gt = inst.sons[0]
let t = if gt.kind == tyGenericBody: gt.lastSon else: gt
if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses:
if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses:
return
gt.sym.typeInstCache.safeAdd(inst)


type
LayeredIdTable* = object
topLayer*: TIdTable
Expand Down Expand Up @@ -336,6 +335,9 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
# but we already raised an error!
rawAddSon(result, header.sons[i])

if body.kind == tyError:
return

let bbody = lastSon body
var newbody = replaceTypeVarsT(cl, bbody)
let bodyIsNew = newbody != bbody
Expand Down
29 changes: 17 additions & 12 deletions compiler/sighashes.nim
Expand Up @@ -196,18 +196,23 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
else:
c.hashSym(t.sym)
if {sfAnon, sfGenSym} * t.sym.flags != {}:
# generated object names can be identical, so we need to
# disambiguate furthermore by hashing the field types and names:
# mild hack to prevent endless recursions (makes nimforum compile again):
let oldFlags = t.sym.flags
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
let n = t.n
for i in 0 ..< n.len:
assert n[i].kind == nkSym
let s = n[i].sym
c.hashSym s
c.hashType s.typ, flags
t.sym.flags = oldFlags
# Generated object names can be identical, so we need to
# disambiguate furthermore by hashing the field types and names.
if t.n.len > 0:
let oldFlags = t.sym.flags
# Mild hack to prevent endless recursion.
t.sym.flags = t.sym.flags - {sfAnon, sfGenSym}
for n in t.n:
assert(n.kind == nkSym)
let s = n.sym
c.hashSym s
c.hashType s.typ, flags
t.sym.flags = oldFlags
else:
# The object has no fields: we _must_ add something here in order to
# make the hash different from the one we produce by hashing only the
# type name.
c &= ".empty"
else:
c &= t.id
if t.len > 0 and t.sons[0] != nil:
Expand Down
1 change: 1 addition & 0 deletions compiler/types.nim
Expand Up @@ -130,6 +130,7 @@ proc elemType*(t: PType): PType =
case t.kind
of tyGenericInst, tyDistinct, tyAlias, tySink: result = elemType(lastSon(t))
of tyArray: result = t.sons[1]
of tyError: result = t
else: result = t.lastSon
assert(result != nil)

Expand Down
5 changes: 5 additions & 0 deletions compiler/vm.nim
Expand Up @@ -1211,6 +1211,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcNarrowU:
decodeB(rkInt)
regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
of opcSignExtend:
# like opcNarrowS, but no out of range possible
decodeB(rkInt)
let imm = 64 - rb
regs[ra].intVal = ashr(regs[ra].intVal shl imm, imm)
of opcIsNil:
decodeB(rkInt)
let node = regs[rb].node
Expand Down
1 change: 1 addition & 0 deletions compiler/vmdef.nim
Expand Up @@ -71,6 +71,7 @@ type
opcSubStr, opcParseFloat, opcConv, opcCast,
opcQuit,
opcNarrowS, opcNarrowU,
opcSignExtend,

opcAddStrCh,
opcAddStrStr,
Expand Down
47 changes: 33 additions & 14 deletions compiler/vmgen.nim
Expand Up @@ -361,16 +361,28 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) =
for endPos in endings: c.patch(endPos)
c.clearDest(n, dest)

proc isTemp(c: PCtx; dest: TDest): bool =
result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown

proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) =
# asgn dest, a
# tjmp|fjmp L1
# asgn dest, b
# L1:
if dest < 0: dest = getTemp(c, n.typ)
c.gen(n.sons[1], dest)
let L1 = c.xjmp(n, opc, dest)
c.gen(n.sons[2], dest)
let copyBack = dest < 0 or not isTemp(c, dest)
let tmp = if copyBack:
getTemp(c, n.typ)
else:
TRegister dest
c.gen(n.sons[1], tmp)
let L1 = c.xjmp(n, opc, tmp)
c.gen(n.sons[2], tmp)
c.patch(L1)
if dest < 0:
dest = tmp
elif copyBack:
c.gABC(n, opcAsgnInt, dest, tmp)
freeTemp(c, tmp)

proc canonValue*(n: PNode): PNode =
result = n
Expand Down Expand Up @@ -938,11 +950,18 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.freeTemp(tmp)
c.freeTemp(tmp2)

of mShlI: genBinaryABCnarrowU(c, n, dest, opcShlInt)
of mAshrI: genBinaryABCnarrow(c, n, dest, opcAshrInt)
of mBitandI: genBinaryABCnarrowU(c, n, dest, opcBitandInt)
of mBitorI: genBinaryABCnarrowU(c, n, dest, opcBitorInt)
of mBitxorI: genBinaryABCnarrowU(c, n, dest, opcBitxorInt)
of mShlI:
genBinaryABC(c, n, dest, opcShlInt)
# genNarrowU modified
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8):
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
elif t.kind in {tyInt8..tyInt32} or (t.kind == tyInt and t.size < 8):
c.gABC(n, opcSignExtend, dest, TRegister(t.size*8))
of mAshrI: genBinaryABC(c, n, dest, opcAshrInt)
of mBitandI: genBinaryABC(c, n, dest, opcBitandInt)
of mBitorI: genBinaryABC(c, n, dest, opcBitorInt)
of mBitxorI: genBinaryABC(c, n, dest, opcBitxorInt)
of mAddU: genBinaryABCnarrowU(c, n, dest, opcAddu)
of mSubU: genBinaryABCnarrowU(c, n, dest, opcSubu)
of mMulU: genBinaryABCnarrowU(c, n, dest, opcMulu)
Expand All @@ -961,7 +980,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mLtPtr, mLtU, mLtU64: genBinaryABC(c, n, dest, opcLtu)
of mEqProc, mEqRef, mEqUntracedRef:
genBinaryABC(c, n, dest, opcEqRef)
of mXor: genBinaryABCnarrowU(c, n, dest, opcXor)
of mXor: genBinaryABC(c, n, dest, opcXor)
of mNot: genUnaryABC(c, n, dest, opcNot)
of mUnaryMinusI, mUnaryMinusI64:
genUnaryABC(c, n, dest, opcUnaryMinusInt)
Expand All @@ -970,7 +989,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of mUnaryPlusI, mUnaryPlusF64: gen(c, n.sons[1], dest)
of mBitnotI:
genUnaryABC(c, n, dest, opcBitnotInt)
genNarrowU(c, n, dest)
#genNarrowU modified, do not narrow signed types
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
if t.kind in {tyUInt8..tyUInt32} or (t.kind == tyUInt and t.size < 8):
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
of mToFloat, mToBiggestFloat, mToInt,
mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr,
mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr:
Expand Down Expand Up @@ -1386,9 +1408,6 @@ proc checkCanEval(c: PCtx; n: PNode) =
skIterator} and sfForward in s.flags:
cannotEval(c, n)

proc isTemp(c: PCtx; dest: TDest): bool =
result = dest >= 0 and c.prc.slots[dest].kind >= slotTempUnknown

template needsAdditionalCopy(n): untyped =
not c.isTemp(dest) and not fitsRegister(n.typ)

Expand Down

0 comments on commit fa7e6b3

Please sign in to comment.