diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgcalls.nim | 5 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 23 | ||||
-rw-r--r-- | compiler/ccgstmts.nim | 13 | ||||
-rw-r--r-- | compiler/cgendata.nim | 2 | ||||
-rw-r--r-- | compiler/closureiters.nim | 81 | ||||
-rw-r--r-- | compiler/lexer.nim | 2 | ||||
-rw-r--r-- | compiler/pragmas.nim | 4 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 8 |
8 files changed, 91 insertions, 47 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 7d355db5f..22733f6ac 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -83,7 +83,7 @@ proc isInCurrentFrame(p: BProc, n: PNode): bool = result = isInCurrentFrame(p, n.sons[0]) else: discard -proc genIndexCheck(p: BProc; arr, idx: TLoc) +proc genBoundsCheck(p: BProc; arr, a, b: TLoc) proc openArrayLoc(p: BProc, n: PNode): Rope = var a: TLoc @@ -97,8 +97,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope = initLocExpr(p, q[3], c) # but first produce the required index checks: if optBoundsCheck in p.options: - genIndexCheck(p, a, b) - genIndexCheck(p, a, c) + genBoundsCheck(p, a, b, c) let ty = skipTypes(a.t, abstractVar+{tyPtr}) case ty.kind of tyArray: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 352402e0e..20b68b0aa 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -351,7 +351,9 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: useStringh(p.module) linefmt(p, cpsStmts, - "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n", + # bug #4799, keep the memcpy for a while + #"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1[0])*$1Len_0);$n", + "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tySet: if mapType(ty) == ctArray: @@ -873,21 +875,26 @@ proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) = putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage) -proc genIndexCheck(p: BProc; arr, idx: TLoc) = +proc genBoundsCheck(p: BProc; arr, a, b: TLoc) = let ty = skipTypes(arr.t, abstractVarRange) case ty.kind of tyOpenArray, tyVarargs: - linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)) #raiseIndexError();$n", - rdLoc(idx), rdLoc(arr)) + linefmt(p, cpsStmts, + "if ($2-$1 != -1 && " & + "((NU)($1) >= (NU)($3Len_0) || (NU)($2) >= (NU)($3Len_0))) #raiseIndexError();$n", + rdLoc(a), rdLoc(b), rdLoc(arr)) of tyArray: let first = intLiteral(firstOrd(ty)) if tfUncheckedArray notin ty.flags: - linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", - rdCharLoc(idx), first, intLiteral(lastOrd(ty))) + linefmt(p, cpsStmts, + "if ($2-$1 != -1 && " & + "($2-$1 < -1 || $1 < $3 || $1 > $4 || $2 < $3 || $2 > $4)) #raiseIndexError();$n", + rdCharLoc(a), rdCharLoc(b), first, intLiteral(lastOrd(ty))) of tySequence, tyString: linefmt(p, cpsStmts, - "if (!$2 || (NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", - rdLoc(idx), rdLoc(arr), lenField(p)) + "if ($2-$1 != -1 && " & + "(!$3 || (NU)($1) >= (NU)($3->$4) || (NU)($2) >= (NU)($3->$4))) #raiseIndexError();$n", + rdLoc(a), rdLoc(b), rdLoc(arr), lenField(p)) else: discard proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 91a3add70..f99ee9270 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -775,6 +775,13 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) = else: genOrdinalCase(p, t, d) +proc genRestoreFrameAfterException(p: BProc) = + if optStackTrace in p.module.config.options: + if not p.hasCurFramePointer: + p.hasCurFramePointer = true + p.procSec(cpsLocals).add(ropecg(p.module, "\tTFrame* _nimCurFrame;$n", [])) + p.procSec(cpsInit).add(ropecg(p.module, "\t_nimCurFrame = #getFrame();$n", [])) + linefmt(p, cpsStmts, "#setFrame(_nimCurFrame);$n") proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = # code to generate: @@ -794,8 +801,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = # finallyPart(); template genExceptBranchBody(body: PNode) {.dirty.} = - if optStackTrace in p.options: - linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n") + genRestoreFrameAfterException(p) expr(p, body, d) if not isEmptyType(t.typ) and d.k == locNone: @@ -898,8 +904,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = endBlock(p) startBlock(p, "else {$n") linefmt(p, cpsStmts, "#popSafePoint();$n") - if optStackTrace in p.options: - linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n") + genRestoreFrameAfterException(p) p.nestedTryStmts[^1].inExcept = true var i = 1 while (i < length) and (t.sons[i].kind == nkExceptBranch): diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index ce3fc2f90..843677654 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -69,6 +69,8 @@ type prc*: PSym # the Nim proc that this C proc belongs to beforeRetNeeded*: bool # true iff 'BeforeRet' label for proc is needed threadVarAccessed*: bool # true if the proc already accessed some threadvar + hasCurFramePointer*: bool # true if _nimCurFrame var needed to recover after + # exception is generated lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements currLineInfo*: TLineInfo # AST codegen will make this superfluous nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]] diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 86b63e34b..5568fd37b 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -155,6 +155,10 @@ type nearestFinally: int # Index of the nearest finally block. For try/except it # is their finally. For finally it is parent finally. Otherwise -1 +const + nkSkip = { nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt, + nkCommentStmt } + procDefs + proc newStateAccess(ctx: var Ctx): PNode = if ctx.stateVarSym.isNil: result = rawIndirectAccess(newSymNode(getEnvParam(ctx.fn)), @@ -247,8 +251,7 @@ proc hasYields(n: PNode): bool = case n.kind of nkYieldStmt: result = true - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard else: for c in n: @@ -259,8 +262,7 @@ proc hasYields(n: PNode): bool = proc transformBreaksAndContinuesInWhile(ctx: var Ctx, n: PNode, before, after: PNode): PNode = result = n case n.kind - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkWhileStmt: discard # Do not recurse into nested whiles of nkContinueStmt: @@ -279,8 +281,7 @@ proc transformBreaksAndContinuesInWhile(ctx: var Ctx, n: PNode, before, after: P proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode = result = n case n.kind - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkBlockStmt, nkWhileStmt: inc ctx.blockLevel @@ -380,8 +381,7 @@ proc getFinallyNode(n: PNode): PNode = proc hasYieldsInExpressions(n: PNode): bool = case n.kind - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkStmtListExpr: if isEmptyType(n.typ): @@ -397,18 +397,17 @@ proc hasYieldsInExpressions(n: PNode): bool = proc exprToStmtList(n: PNode): tuple[s, res: PNode] = assert(n.kind == nkStmtListExpr) + result.s = newNodeI(nkStmtList, n.info) + result.s.sons = @[] - var parent = n - var lastSon = n[^1] + var n = n + while n.kind == nkStmtListExpr: + result.s.sons.add(n.sons) + result.s.sons.setLen(result.s.sons.len - 1) # delete last son + n = n[^1] - while lastSon.kind == nkStmtListExpr: - parent = lastSon - lastSon = lastSon[^1] + result.res = n - result.s = newNodeI(nkStmtList, n.info) - result.s.sons = parent.sons - result.s.sons.setLen(result.s.sons.len - 1) # delete last son - result.res = lastSon proc newEnvVarAsgn(ctx: Ctx, s: PSym, v: PNode): PNode = result = newTree(nkFastAsgn, ctx.newEnvVarAccess(s), v) @@ -433,8 +432,7 @@ proc newNotCall(g: ModuleGraph; e: PNode): PNode = proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = result = n case n.kind - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkYieldStmt: @@ -443,7 +441,6 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = n[i] = ctx.lowerStmtListExprs(n[i], ns) if ns: - assert(n[0].kind == nkStmtListExpr) result = newNodeI(nkStmtList, n.info) let (st, ex) = exprToStmtList(n[0]) result.add(st) @@ -663,7 +660,6 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = c[^1] = ctx.lowerStmtListExprs(c[^1], ns) if ns: needsSplit = true - assert(c[^1].kind == nkStmtListExpr) let (st, ex) = exprToStmtList(c[^1]) result.add(st) c[^1] = ex @@ -736,6 +732,33 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = n[0] = newSymNode(ctx.g.getSysSym(n[0].info, "true")) n[1] = newBody + + of nkDotExpr: + var ns = false + n[0] = ctx.lowerStmtListExprs(n[0], ns) + if ns: + needsSplit = true + result = newNodeI(nkStmtListExpr, n.info) + result.typ = n.typ + let (st, ex) = exprToStmtList(n[0]) + result.add(st) + n[0] = ex + result.add(n) + + of nkBlockExpr: + var ns = false + n[1] = ctx.lowerStmtListExprs(n[1], ns) + if ns: + needsSplit = true + result = newNodeI(nkStmtListExpr, n.info) + result.typ = n.typ + let (st, ex) = exprToStmtList(n[1]) + n.kind = nkBlockStmt + n.typ = nil + n[1] = st + result.add(n) + result.add(ex) + else: for i in 0 ..< n.len: n[i] = ctx.lowerStmtListExprs(n[i], needsSplit) @@ -797,8 +820,7 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode = let goto = newTree(nkGotoState, ctx.g.newIntLit(n.info, ctx.nearestFinally)) result.add(goto) - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard else: for i in 0 ..< n.len: @@ -807,8 +829,7 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode = proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode = result = n case n.kind: - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkStmtList, nkStmtListExpr: @@ -846,8 +867,8 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode result[0] = ctx.transformClosureIteratorBody(result[0], gotoOut) of nkElifBranch, nkElifExpr, nkOfBranch: - result[1] = addGotoOut(result[1], gotoOut) - result[1] = ctx.transformClosureIteratorBody(result[1], gotoOut) + result[^1] = addGotoOut(result[^1], gotoOut) + result[^1] = ctx.transformClosureIteratorBody(result[^1], gotoOut) of nkIfStmt, nkCaseStmt: for i in 0 ..< n.len: @@ -1013,8 +1034,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode = for i in 0 ..< n.len: n[i] = ctx.tranformStateAssignments(n[i]) - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkReturnStmt: @@ -1066,8 +1086,7 @@ proc skipEmptyStates(ctx: Ctx, stateIdx: int): int = proc skipThroughEmptyStates(ctx: var Ctx, n: PNode): PNode = result = n case n.kind - of nkCharLit..nkUInt64Lit, nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit, - nkSym, nkIdent, procDefs, nkTemplateDef: + of nkSkip: discard of nkGotoState: result = copyTree(n) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 591561987..d498cf4af 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -25,7 +25,7 @@ const SymChars*: set[char] = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF'} SymStartChars*: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} OpChars*: set[char] = {'+', '-', '*', '/', '\\', '<', '>', '!', '?', '^', '.', - '|', '=', '%', '&', '$', '@', '~', ':', '\x80'..'\xFF'} + '|', '=', '%', '&', '$', '@', '~', ':'} # don't forget to update the 'highlite' module if these charsets should change diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index de98a5e42..d3fa506cb 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -374,6 +374,10 @@ proc processPush(c: PContext, n: PNode, start: int) = x.otherPragmas.add n.sons[i] #localError(c.config, n.info, errOptionExpected) + # If stacktrace is disabled globally we should not enable it + if optStackTrace notin c.optionStack[0].options: + c.config.options.excl(optStackTrace) + proc processPop(c: PContext, n: PNode) = if c.optionStack.len <= 1: localError(c.config, n.info, "{.pop.} without a corresponding {.push.}") diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 41cac2a4a..fcfdda8bb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -2013,6 +2013,14 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, if r == isGeneric: result.typ = getInstantiatedType(c, arg, m, base(f)) m.baseTypeMatch = true + # bug #4799, varargs accepting subtype relation object + elif r == isSubtype: + inc(m.subtypeMatches) + if f.kind == tyTypeDesc: + result = arg + else: + result = implicitConv(nkHiddenSubConv, f, arg, m, c) + m.baseTypeMatch = true else: result = userConvMatch(c, m, base(f), a, arg) if result != nil: m.baseTypeMatch = true |