diff options
-rw-r--r-- | compiler/msgs.nim | 4 | ||||
-rw-r--r-- | compiler/semstmts.nim | 19 | ||||
-rw-r--r-- | compiler/vm.nim | 13 | ||||
-rw-r--r-- | compiler/vmdef.nim | 3 | ||||
-rw-r--r-- | compiler/vmgen.nim | 28 | ||||
-rw-r--r-- | tests/compile/tbindtypedesc.nim | 4 |
6 files changed, 45 insertions, 26 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 895ba71f3..2a7d54d4e 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -700,11 +700,9 @@ type proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = template maybeTrace = - if defined(debug) or gVerbosity >= 3: + if defined(debug) or gVerbosity >= 3 or msg == errInternal: writeStackTrace() - if msg == errInternal: - writeStackTrace() # we always want a stack trace here if msg >= fatalMin and msg <= fatalMax: maybeTrace() quit(1) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index cd714ef6e..6f0cc3c8b 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1168,13 +1168,18 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode = proc semStaticStmt(c: PContext, n: PNode): PNode = let a = semStmt(c, n.sons[0]) - result = evalStaticExpr(c.module, a, c.p.owner) - if result.isNil: - LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) - result = emptyNode - elif result.kind == nkEmpty: - result = newNodeI(nkDiscardStmt, n.info, 1) - result.sons[0] = emptyNode + n.sons[0] = a + evalStaticStmt(c.module, a, c.p.owner) + result = newNodeI(nkDiscardStmt, n.info, 1) + result.sons[0] = emptyNode + when false: + result = evalStaticStmt(c.module, a, c.p.owner) + if result.isNil: + LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) + result = emptyNode + elif result.kind == nkEmpty: + result = newNodeI(nkDiscardStmt, n.info, 1) + result.sons[0] = emptyNode proc usesResult(n: PNode): bool = # nkStmtList(expr) properly propagates the void context, diff --git a/compiler/vm.nim b/compiler/vm.nim index 019397bbc..a6cdc81b2 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -515,7 +515,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = regs[rb].sons == regs[rc].sons) of opcEqNimrodNode: decodeBC(nkIntLit) - regs[ra].intVal = ord(regs[rb].uast == regs[rc].uast) + regs[ra].intVal = ord(regs[rb].skipMeta == regs[rc].skipMeta) of opcXor: decodeBC(nkIntLit) regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal) @@ -746,7 +746,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = decodeB(nkStrLit) regs[ra].strVal = renderTree(regs[rb].skipMeta, {renderNoComments}) of opcQuit: - if c.mode in {emRepl, emStatic}: + if c.mode in {emRepl, emStaticExpr, emStaticStmt}: Message(c.debug[pc], hintQuitCalled) quit(int(getOrdValue(regs[ra]))) else: @@ -1036,7 +1036,7 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode = setupGlobalCtx(module) var c = globalCtx c.mode = mode - let start = genExpr(c, n) + let start = genExpr(c, n, requiresValue = mode!=emStaticStmt) assert c.code[start].opcode != opcEof var tos = PStackFrame(prc: prc, comesFrom: 0, next: nil) newSeq(tos.slots, c.prc.maxSlots) @@ -1047,8 +1047,11 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode = proc evalConstExpr*(module: PSym, e: PNode): PNode = result = evalConstExprAux(module, nil, e, emConst) -proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = - result = evalConstExprAux(module, prc, e, emStatic) +proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode = + result = evalConstExprAux(module, prc, e, emStaticExpr) + +proc evalStaticStmt*(module: PSym, e: PNode, prc: PSym) = + discard evalConstExprAux(module, prc, e, emStaticStmt) proc setupMacroParam(x: PNode): PNode = result = x diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 15ea9767b..1869b69c4 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -134,8 +134,9 @@ type emConst, ## evaluate for 'const' according to spec emOptimize, ## evaluate for optimization purposes (same as ## emConst?) - emStatic ## evaluate for enforced compile time eval + emStaticExpr, ## evaluate for enforced compile time eval ## ('static' context) + emStaticStmt ## 'static' as an expression TSandboxFlag* = enum ## what the evaluation engine should allow allowCast, ## allow unsafe language feature: 'cast' diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index cc395f6c5..802fa1706 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -314,6 +314,11 @@ proc genLiteral(c: PCtx; n: PNode): int = if sameConstant(c.constants[i], n): return i result = rawGenLiteral(c, n) +proc unused(n: PNode; x: TDest) {.inline.} = + if x >= 0: + #debug(n) + InternalError(n.info, "not unused") + proc genCase(c: PCtx; n: PNode; dest: var TDest) = # if (!expr1) goto L1; # thenPart @@ -325,7 +330,10 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) = # L2: # elsePart # Lend: - if dest < 0 and not isEmptyType(n.typ): dest = getTemp(c, n.typ) + if not isEmptyType(n.typ): + if dest < 0: dest = getTemp(c, n.typ) + else: + unused(n, dest) var endings: seq[TPosition] = @[] withTemp(tmp, n.sons[0].typ): c.gen(n.sons[0], tmp) @@ -503,11 +511,6 @@ proc genAddSubInt(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) = else: genBinaryABC(c, n, dest, opc) -proc unused(n: PNode; x: TDest) {.inline.} = - if x >= 0: - #debug(n) - InternalError(n.info, "not unused") - proc genConv(c: PCtx; n, arg: PNode; dest: var TDest; opc=opcConv) = let tmp = c.genx(arg) c.gABx(n, opcSetType, tmp, genType(c, arg.typ)) @@ -1168,7 +1171,10 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) = c.gABx(n, opcLdImmInt, dest, n.intVal.int) else: genLit(c, n, dest) - of nkUIntLit..nkNilLit: genLit(c, n, dest) + of nkUIntLit..pred(nkNilLit): genLit(c, n, dest) + of nkNilLit: + if not n.typ.isEmptyType: genLit(c, n, dest) + else: unused(n, dest) of nkAsgn, nkFastAsgn: unused(n, dest) genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn) @@ -1253,14 +1259,16 @@ proc genStmt*(c: PCtx; n: PNode): int = var d: TDest = -1 c.gen(n, d) c.gABC(n, opcEof) - InternalAssert d < 0 + if d >= 0: internalError(n.info, "some destination set") -proc genExpr*(c: PCtx; n: PNode): int = +proc genExpr*(c: PCtx; n: PNode, requiresValue = true): int = c.removeLastEof result = c.code.len var d: TDest = -1 c.gen(n, d) - InternalAssert d >= 0 + if d < 0: + if requiresValue: internalError(n.info, "no destination set") + d = 0 c.gABC(n, opcEof, d) proc genParams(c: PCtx; params: PNode) = diff --git a/tests/compile/tbindtypedesc.nim b/tests/compile/tbindtypedesc.nim index dd4ef854c..4ebfd12bb 100644 --- a/tests/compile/tbindtypedesc.nim +++ b/tests/compile/tbindtypedesc.nim @@ -44,6 +44,10 @@ good(genericParamOnce(TFoo, TFoo)) bad(genericParamOnce(string, int)) bad(genericParamOnce(TFoo, float)) +type + type1 = typedesc + type2 = typedesc + proc typePairs(A, B: type1; C, D: type2) = nil good(typePairs(int, int, TFoo, TFOO)) |