summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-08-25 18:11:05 +0300
committerZahary Karadjov <zahary@gmail.com>2013-08-25 18:11:28 +0300
commit89086a8e19292ad986baa808ff42ccad32bf2636 (patch)
treedba214f1beaeac5556f33cccbb3a476aca94cae5
parent6378fbd66ef9ff85510bf0583610bfc84dc6528f (diff)
downloadNim-89086a8e19292ad986baa808ff42ccad32bf2636.tar.gz
prevent eval crashes due to PContext-dependent ops not being available in evalConstExpr
-rw-r--r--compiler/evals.nim9
-rw-r--r--compiler/sem.nim65
-rw-r--r--compiler/semexprs.nim6
-rw-r--r--compiler/semstmts.nim2
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