diff options
author | Zahary Karadjov <zahary@gmail.com> | 2013-08-25 18:11:05 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2013-08-25 18:11:28 +0300 |
commit | 89086a8e19292ad986baa808ff42ccad32bf2636 (patch) | |
tree | dba214f1beaeac5556f33cccbb3a476aca94cae5 | |
parent | 6378fbd66ef9ff85510bf0583610bfc84dc6528f (diff) | |
download | Nim-89086a8e19292ad986baa808ff42ccad32bf2636.tar.gz |
prevent eval crashes due to PContext-dependent ops not being available in evalConstExpr
-rw-r--r-- | compiler/evals.nim | 9 | ||||
-rw-r--r-- | compiler/sem.nim | 65 | ||||
-rw-r--r-- | compiler/semexprs.nim | 6 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 |
4 files changed, 40 insertions, 42 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim index 7bd74b04a..be6f625ec 100644 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -1440,8 +1440,7 @@ proc eval*(c: PEvalContext, n: PNode): PNode = else: stackTrace(c, result.info, errCannotInterpretNodeX, renderTree(n)) -proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode = - var p = newEvalContext(module, mode) +proc evalConstExprAux*(p: PEvalContext, module, prc: PSym, e: PNode): PNode = var s = newStackFrame() s.call = e s.prc = prc @@ -1450,12 +1449,6 @@ proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode = if result != nil and result.kind == nkExceptBranch: result = nil popStackFrame(p) -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 setupMacroParam(x: PNode): PNode = result = x if result.kind == nkHiddenStdConv: result = result.sons[1] diff --git a/compiler/sem.nim b/compiler/sem.nim index c411d8ac4..71951dd3f 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -132,14 +132,42 @@ proc ParamsTypeCheck(c: PContext, typ: PType) {.inline.} = LocalError(typ.n.info, errXisNoType, typeToString(typ)) proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym - proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode - -proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, - semCheck: bool = true): PNode proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode - proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode +proc IsOpImpl(c: PContext, n: PNode): PNode +proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, + semCheck: bool = true): PNode + +proc symFromType(t: PType, info: TLineInfo): PSym = + if t.sym != nil: return t.sym + result = newSym(skType, getIdent"AnonType", t.owner, info) + result.flags.incl sfAnon + result.typ = t + +proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = + result = newSymNode(symFromType(t, info), info) + result.typ = makeTypeDesc(c, t) + +proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext = + result = newEvalContext(c.module, mode) + result.getType = proc (n: PNode): PNode = + var e = tryExpr(c, n) + if e == nil: + result = symNodeFromType(c, errorType(c), n.info) + elif e.typ == nil: + result = newSymNode(getSysSym"void") + else: + result = symNodeFromType(c, e.typ, n.info) + + result.handleIsOperator = proc (n: PNode): PNode = + result = IsOpImpl(c, n) + +proc evalConstExpr(c: PContext, module: PSym, e: PNode): PNode = + result = evalConstExprAux(c.createEvalContext(emConst), module, nil, e) + +proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode = + result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e) proc semConstExpr(c: PContext, n: PNode): PNode = var e = semExprWithType(c, n) @@ -148,7 +176,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode = return n result = getConstExpr(c.module, e) if result == nil: - result = evalConstExpr(c.module, e) + result = evalConstExpr(c, c.module, e) if result == nil or result.kind == nkEmpty: if e.info != n.info: pushInfoContext(n.info) @@ -161,16 +189,6 @@ proc semConstExpr(c: PContext, n: PNode): PNode = include hlo, seminst, semcall -proc symFromType(t: PType, info: TLineInfo): PSym = - if t.sym != nil: return t.sym - result = newSym(skType, getIdent"AnonType", t.owner, info) - result.flags.incl sfAnon - result.typ = t - -proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode = - result = newSymNode(symFromType(t, info), info) - result.typ = makeTypeDesc(c, t) - proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = inc(evalTemplateCounter) if evalTemplateCounter > 100: @@ -198,8 +216,6 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) dec(evalTemplateCounter) -proc IsOpImpl(c: PContext, n: PNode): PNode - proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode = markUsed(n, sym) @@ -207,18 +223,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, GlobalError(n.info, errRecursiveDependencyX, sym.name.s) if c.evalContext == nil: - c.evalContext = newEvalContext(c.module, emStatic) - c.evalContext.getType = proc (n: PNode): PNode = - var e = tryExpr(c, n) - if e == nil: - result = symNodeFromType(c, errorType(c), n.info) - elif e.typ == nil: - result = newSymNode(getSysSym"void") - else: - result = symNodeFromType(c, e.typ, n.info) - - c.evalContext.handleIsOperator = proc (n: PNode): PNode = - result = IsOpImpl(c, n) + c.evalContext = c.createEvalContext(emStatic) result = evalMacroCall(c.evalContext, n, nOrig, sym) if semCheck: result = semAfterMacroCall(c, result, sym) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d80a1cb5a..d0b81364e 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -627,18 +627,18 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = call.add(a) #echo "NOW evaluating at compile time: ", call.renderTree if sfCompileTime in callee.flags: - result = evalStaticExpr(c.module, call, c.p.owner) + result = evalStaticExpr(c, c.module, call, c.p.owner) if result.isNil: LocalError(n.info, errCannotInterpretNodeX, renderTree(call)) else: - result = evalConstExpr(c.module, call) + result = evalConstExpr(c, c.module, call) if result.isNil: result = n #if result != n: # echo "SUCCESS evaluated at compile time: ", call.renderTree proc semStaticExpr(c: PContext, n: PNode): PNode = let a = semExpr(c, n.sons[0]) - result = evalStaticExpr(c.module, a, c.p.owner) + result = evalStaticExpr(c, c.module, a, c.p.owner) if result.isNil: LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) result = emptyNode diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index a15b3e10a..3b83290ea 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1144,7 +1144,7 @@ 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) + result = evalStaticExpr(c, c.module, a, c.p.owner) if result.isNil: LocalError(n.info, errCannotInterpretNodeX, renderTree(n)) result = emptyNode |