This commit is contained in:
Araq
2023-09-12 19:12:03 +02:00
parent 7c7159f1f5
commit fb07fae613
9 changed files with 43 additions and 15 deletions

View File

@@ -161,3 +161,4 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimUseStrictDefs")
defineSymbol("nimHasNolineTooLong")
defineSymbol("nimHasQuirkyBoots")

View File

@@ -443,7 +443,8 @@ proc handleError(conf: ConfigRef; msg: TMsgKind, eh: TErrorHandling, s: string,
elif eh == doAbort and conf.cmd != cmdIdeTools:
quit(conf, msg)
elif eh == doRaise:
raiseRecoverableError(s)
#raiseRecoverableError(s)
quit(conf, msg)
proc `==`*(a, b: TLineInfo): bool =
result = a.line == b.line and a.fileIndex == b.fileIndex

View File

@@ -51,4 +51,6 @@ define:useStdoutAsStdmsg
#warningAsError[ProveInit]:on
@end
#--exceptions:quirky
@if nimHasQuirkyBoots:
exceptions:quirky
@end

View File

@@ -996,9 +996,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
incl(sym.flags, sfSideEffect)
of wNoreturn:
noVal(c, it)
# Disable the 'noreturn' annotation when in the "Quirky Exceptions" mode!
if c.config.exc != excQuirky:
incl(sym.flags, sfNoReturn)
incl(sym.flags, sfNoReturn)
if sym.typ[0] != nil:
localError(c.config, sym.ast[paramsPos][0].info,
".noreturn with return type not allowed")

View File

@@ -321,7 +321,7 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
# only in case of an error).
if c.config.m.errorOutputs == {}:
# fail fast:
globalError(c.config, n.info, "type mismatch")
localError(c.config, n.info, "type mismatch")
return
# see getMsgDiagnostic:
if nfExplicitCall notin n.flags and {nfDotField, nfDotSetter} * n.flags != {}:
@@ -483,7 +483,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
#writeMatches(alt)
if c.config.m.errorOutputs == {}:
# quick error message for performance of 'compiles' built-in:
globalError(c.config, n.info, errGenerated, "ambiguous call")
localError(c.config, n.info, errGenerated, "ambiguous call")
elif c.config.errorCounter == 0:
# don't cascade errors
var args = "("

View File

@@ -47,7 +47,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
template rejectEmptyNode(n: PNode) =
# No matter what a nkEmpty node is not what we want here
if n.kind == nkEmpty: illFormedAst(n, c.config)
if n.kind == nkEmpty: illFormedAstLocal(n, c.config)
proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
rejectEmptyNode(n)
@@ -1827,7 +1827,7 @@ proc goodLineInfo(arg: PNode): TLineInfo =
proc makeTupleAssignments(c: PContext; n: PNode): PNode =
## expand tuple unpacking assignment into series of assignments
##
##
## mirrored with semstmts.makeVarTupleSection
let lhs = n[0]
let value = semExprWithType(c, n[1], {efTypeAllowed})

View File

@@ -2274,11 +2274,17 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
inc pc
proc execute(c: PCtx, start: int): PNode =
if c.couldNotEval:
c.couldNotEval = false
return nil
var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil)
newSeq(tos.slots, c.prc.regInfo.len)
result = rawExecute(c, start, tos).regToNode
proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
if c.couldNotEval:
c.couldNotEval = false
return nil
c.loopIterations = c.config.maxLoopIterationsVM
if sym.kind in routineKinds:
if sym.typ.len-1 != args.len:
@@ -2309,6 +2315,10 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
proc evalStmt*(c: PCtx, n: PNode) =
let n = transformExpr(c.graph, c.idgen, c.module, n)
let start = genStmt(c, n)
if c.couldNotEval:
c.couldNotEval = false
return
# execute new instructions; this redundant opcEof check saves us lots
# of allocations in 'execute':
if c.code[start].opcode != opcEof:
@@ -2318,6 +2328,9 @@ proc evalExpr*(c: PCtx, n: PNode): PNode =
# deadcode
# `nim --eval:"expr"` might've used it at some point for idetools; could
# be revived for nimsuggest
if c.couldNotEval:
c.couldNotEval = false
return nil
let n = transformExpr(c.graph, c.idgen, c.module, n)
let start = genExpr(c, n)
assert c.code[start].opcode != opcEof
@@ -2373,6 +2386,10 @@ proc evalConstExprAux(module: PSym; idgen: IdGenerator;
let oldMode = c.mode
c.mode = mode
let start = genExpr(c, n, requiresValue = mode!=emStaticStmt)
if c.couldNotEval:
c.couldNotEval = false
return nil
if c.code[start].opcode == opcEof: return newNodeI(nkEmpty, n.info)
assert c.code[start].opcode != opcEof
when debugEchoCode: c.echoCode start

View File

@@ -257,6 +257,7 @@ type
mode*: TEvalMode
features*: TSandboxFlags
traceActive*: bool
couldNotEval*: bool
loopIterations*: int
comesFromHeuristic*: TLineInfo # Heuristic for better macro stack traces
callbacks*: seq[VmCallback]

View File

@@ -1535,7 +1535,8 @@ proc setSlot(c: PCtx; v: PSym) =
v.position = getFreeRegister(c, if v.kind == skLet: slotFixedLet else: slotFixedVar, start = 1)
proc cannotEval(c: PCtx; n: PNode) {.noinline.} =
globalError(c.config, n.info, "cannot evaluate at compile time: " &
c.couldNotEval = true
localError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
proc isOwnedBy(a, b: PSym): bool =
@@ -1747,7 +1748,10 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
s.kind in {skParam, skResult}):
if dest < 0:
dest = s.position + ord(s.kind == skParam)
internalAssert(c.config, c.prc.regInfo[dest].kind < slotSomeTemp)
if dest < c.prc.regInfo.len:
internalAssert(c.config, c.prc.regInfo[dest].kind < slotSomeTemp)
else:
cannotEval(c, n)
else:
# we need to generate an assignment:
let requiresCopy = c.prc.regInfo[dest].kind >= slotSomeTemp and
@@ -1781,6 +1785,7 @@ proc genArrAccessOpcode(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
c.freeTemp(b)
proc genObjAccessAux(c: PCtx; n: PNode; a, b: int, dest: var TDest; flags: TGenFlags) =
if c.couldNotEval: return
if dest < 0: dest = c.getTemp(n.typ)
if {gfNodeAddr} * flags != {}:
c.gABC(n, opcLdObjAddr, dest, a, b)
@@ -1796,8 +1801,6 @@ proc genObjAccessAux(c: PCtx; n: PNode; a, b: int, dest: var TDest; flags: TGenF
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
genObjAccessAux(c, n, c.genx(n[0], flags), genField(c, n[1]), dest, flags)
proc genCheckedObjAccessAux(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
internalAssert c.config, n.kind == nkCheckedFieldExpr
# nkDotExpr to access the requested field
@@ -1815,6 +1818,7 @@ proc genCheckedObjAccessAux(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags
# Load the object in `dest`
c.gen(accessExpr[0], dest, flags)
if c.couldNotEval: return
# Load the discriminant
var discVal = c.getTemp(disc.typ)
c.gABC(n, opcLdObj, discVal, dest, genField(c, disc))
@@ -1841,6 +1845,7 @@ proc genCheckedObjAccessAux(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags
proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
var objR: TDest = -1
genCheckedObjAccessAux(c, n, objR, flags)
if c.couldNotEval: return
let accessExpr = n[0]
# Field symbol
@@ -2119,6 +2124,7 @@ proc procIsCallback(c: PCtx; s: PSym): bool =
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
when defined(nimCompilerStacktraceHints):
setFrameMsg c.config$n.info & " " & $n.kind & " " & $flags
#if c.couldNotEval: return
case n.kind
of nkSym:
let s = n.sym
@@ -2289,7 +2295,8 @@ proc genStmt*(c: PCtx; n: PNode): int =
c.gen(n, d)
c.gABC(n, opcEof)
if d >= 0:
globalError(c.config, n.info, "VM problem: dest register is set")
c.couldNotEval = true
localError(c.config, n.info, "VM problem: dest register is set")
proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int =
c.removeLastEof
@@ -2298,7 +2305,8 @@ proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int =
c.gen(n, d)
if d < 0:
if requiresValue:
globalError(c.config, n.info, "VM problem: dest register is not set")
c.couldNotEval = true
localError(c.config, n.info, "VM problem: dest register is not set")
d = 0
c.gABC(n, opcEof, d)