proper error message when attempting to eval C'imported procs
This commit is contained in:
parent
1392049aea
commit
04e5c6718e
3 changed files with 53 additions and 63 deletions
|
|
@ -70,6 +70,11 @@ proc popStackFrame*(c: PEvalContext) {.inline.} =
|
||||||
proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode
|
proc evalMacroCall*(c: PEvalContext, n: PNode, sym: PSym): PNode
|
||||||
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
|
||||||
|
|
||||||
|
proc raiseCannotEval(c: PEvalContext, n: PNode): PNode =
|
||||||
|
result = newNodeI(nkExceptBranch, n.info)
|
||||||
|
# creating a nkExceptBranch without sons
|
||||||
|
# means that it could not be evaluated
|
||||||
|
|
||||||
proc stackTraceAux(x: PStackFrame) =
|
proc stackTraceAux(x: PStackFrame) =
|
||||||
if x != nil:
|
if x != nil:
|
||||||
stackTraceAux(x.next)
|
stackTraceAux(x.next)
|
||||||
|
|
@ -89,7 +94,7 @@ proc stackTraceAux(x: PStackFrame) =
|
||||||
proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg = "") =
|
proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg = "") =
|
||||||
MsgWriteln("stack trace: (most recent call last)")
|
MsgWriteln("stack trace: (most recent call last)")
|
||||||
stackTraceAux(c.tos)
|
stackTraceAux(c.tos)
|
||||||
Fatal(n.info, msg, arg)
|
LocalError(n.info, msg, arg)
|
||||||
|
|
||||||
proc isSpecial(n: PNode): bool {.inline.} =
|
proc isSpecial(n: PNode): bool {.inline.} =
|
||||||
result = (n.kind == nkExceptBranch)
|
result = (n.kind == nkExceptBranch)
|
||||||
|
|
@ -335,15 +340,17 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
if (idx >= 0) and (idx < sonsLen(x)):
|
if (idx >= 0) and (idx < sonsLen(x)):
|
||||||
result = x.sons[int(idx)]
|
result = x.sons[int(idx)]
|
||||||
if result.kind == nkExprColonExpr: result = result.sons[1]
|
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||||
else: stackTrace(c, n, errIndexOutOfBounds)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
if not aliasNeeded(result, flags): result = copyTree(result)
|
else:
|
||||||
|
stackTrace(c, n, errIndexOutOfBounds)
|
||||||
of nkBracket, nkMetaNode:
|
of nkBracket, nkMetaNode:
|
||||||
if (idx >= 0) and (idx < sonsLen(x)): result = x.sons[int(idx)]
|
if (idx >= 0) and (idx < sonsLen(x)):
|
||||||
else: stackTrace(c, n, errIndexOutOfBounds)
|
result = x.sons[int(idx)]
|
||||||
if not aliasNeeded(result, flags): result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
of nkStrLit..nkTripleStrLit:
|
else:
|
||||||
if efLValue in flags:
|
stackTrace(c, n, errIndexOutOfBounds)
|
||||||
InternalError(n.info, "cannot evaluate write access to char")
|
of nkStrLit..nkTripleStrLit:
|
||||||
|
if efLValue in flags: return raiseCannotEval(c, n)
|
||||||
result = newNodeIT(nkCharLit, x.info, getSysType(tyChar))
|
result = newNodeIT(nkCharLit, x.info, getSysType(tyChar))
|
||||||
if (idx >= 0) and (idx < len(x.strVal)):
|
if (idx >= 0) and (idx < len(x.strVal)):
|
||||||
result.intVal = ord(x.strVal[int(idx) + 0])
|
result.intVal = ord(x.strVal[int(idx) + 0])
|
||||||
|
|
@ -359,7 +366,7 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], flags)
|
result = evalAux(c, n.sons[0], flags)
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var x = result
|
var x = result
|
||||||
if x.kind != nkPar: InternalError(n.info, "evalFieldAccess")
|
if x.kind != nkPar: return raiseCannotEval(c, n)
|
||||||
var field = n.sons[1].sym
|
var field = n.sons[1].sym
|
||||||
for i in countup(0, sonsLen(x) - 1):
|
for i in countup(0, sonsLen(x) - 1):
|
||||||
var it = x.sons[i]
|
var it = x.sons[i]
|
||||||
|
|
@ -389,7 +396,7 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
|
||||||
|
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
if result.kind != nkCharLit: InternalError(n.info, "no character")
|
if result.kind != nkCharLit: return raiseCannotEval(c, n)
|
||||||
|
|
||||||
if (idx >= 0) and (idx < len(x.strVal)):
|
if (idx >= 0) and (idx < len(x.strVal)):
|
||||||
x.strVal[int(idx)] = chr(int(result.intVal))
|
x.strVal[int(idx)] = chr(int(result.intVal))
|
||||||
|
|
@ -408,8 +415,10 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
|
||||||
of nkCharLit..nkInt64Lit: x.intVal = result.intVal
|
of nkCharLit..nkInt64Lit: x.intVal = result.intVal
|
||||||
of nkFloatLit..nkFloat64Lit: x.floatVal = result.floatVal
|
of nkFloatLit..nkFloat64Lit: x.floatVal = result.floatVal
|
||||||
of nkStrLit..nkTripleStrLit: x.strVal = result.strVal
|
of nkStrLit..nkTripleStrLit: x.strVal = result.strVal
|
||||||
|
of nkIdent: x.ident = result.ident
|
||||||
|
of nkSym: x.sym = result.sym
|
||||||
else:
|
else:
|
||||||
if not (x.kind in {nkEmpty..nkNilLit}):
|
if x.kind notin {nkEmpty..nkNilLit}:
|
||||||
discardSons(x)
|
discardSons(x)
|
||||||
for i in countup(0, sonsLen(result) - 1): addSon(x, result.sons[i])
|
for i in countup(0, sonsLen(result) - 1): addSon(x, result.sons[i])
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -421,22 +430,15 @@ proc evalSwap(c: PEvalContext, n: PNode): PNode =
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
if (x.kind != result.kind):
|
if x.kind != result.kind:
|
||||||
stackTrace(c, n, errCannotInterpretNodeX, $n.kind)
|
stackTrace(c, n, errCannotInterpretNodeX, $n.kind)
|
||||||
else:
|
else:
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkInt64Lit: swap(x.intVal, result.intVal)
|
||||||
var tmpi = x.intVal
|
of nkFloatLit..nkFloat64Lit: swap(x.floatVal, result.floatVal)
|
||||||
x.intVal = result.intVal
|
of nkStrLit..nkTripleStrLit: swap(x.strVal, result.strVal)
|
||||||
result.intVal = tmpi
|
of nkIdent: swap(x.ident, result.ident)
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkSym: swap(x.sym, result.sym)
|
||||||
var tmpf = x.floatVal
|
|
||||||
x.floatVal = result.floatVal
|
|
||||||
result.floatVal = tmpf
|
|
||||||
of nkStrLit..nkTripleStrLit:
|
|
||||||
var tmps = x.strVal
|
|
||||||
x.strVal = result.strVal
|
|
||||||
result.strVal = tmps
|
|
||||||
else:
|
else:
|
||||||
var tmpn = copyTree(x)
|
var tmpn = copyTree(x)
|
||||||
discardSons(x)
|
discardSons(x)
|
||||||
|
|
@ -444,7 +446,7 @@ proc evalSwap(c: PEvalContext, n: PNode): PNode =
|
||||||
discardSons(result)
|
discardSons(result)
|
||||||
for i in countup(0, sonsLen(tmpn) - 1): addSon(result, tmpn.sons[i])
|
for i in countup(0, sonsLen(tmpn) - 1): addSon(result, tmpn.sons[i])
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
var s = n.sym
|
var s = n.sym
|
||||||
case s.kind
|
case s.kind
|
||||||
|
|
@ -460,10 +462,9 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = c.tos.params[s.position + 1]
|
result = c.tos.params[s.position + 1]
|
||||||
of skConst: result = s.ast
|
of skConst: result = s.ast
|
||||||
of skEnumField: result = newIntNodeT(s.position, n)
|
of skEnumField: result = newIntNodeT(s.position, n)
|
||||||
else:
|
else: result = nil
|
||||||
stackTrace(c, n, errCannotInterpretNodeX, $s.kind)
|
if result == nil or sfImportc in s.flags:
|
||||||
result = emptyNode
|
result = raiseCannotEval(c, n)
|
||||||
if result == nil: stackTrace(c, n, errCannotInterpretNodeX, s.name.s)
|
|
||||||
|
|
||||||
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
|
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
|
|
@ -474,7 +475,7 @@ proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
|
||||||
var b = result
|
var b = result
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b)
|
of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b)
|
||||||
else: internalError(n.info, "evalIncDec")
|
else: return raiseCannotEval(c, n)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc getStrValue(n: PNode): string =
|
proc getStrValue(n: PNode): string =
|
||||||
|
|
@ -510,13 +511,8 @@ proc evalAnd(c: PEvalContext, n: PNode): PNode =
|
||||||
if result.kind != nkIntLit: InternalError(n.info, "evalAnd")
|
if result.kind != nkIntLit: InternalError(n.info, "evalAnd")
|
||||||
if result.intVal != 0: result = evalAux(c, n.sons[2], {})
|
if result.intVal != 0: result = evalAux(c, n.sons[2], {})
|
||||||
|
|
||||||
proc evalNoOpt(c: PEvalContext, n: PNode): PNode =
|
|
||||||
result = newNodeI(nkExceptBranch, n.info)
|
|
||||||
# creating a nkExceptBranch without sons
|
|
||||||
# means that it could not be evaluated
|
|
||||||
|
|
||||||
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
||||||
if c.optEval: return evalNoOpt(c, n)
|
if c.optEval: return raiseCannotEval(c, n)
|
||||||
# we ignore the finalizer for now and most likely forever :-)
|
# we ignore the finalizer for now and most likely forever :-)
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -539,7 +535,8 @@ proc evalDeref(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
of nkRefTy:
|
of nkRefTy:
|
||||||
# XXX efLValue?
|
# XXX efLValue?
|
||||||
result = result.sons[0]
|
result = result.sons[0]
|
||||||
else: InternalError(n.info, "evalDeref " & $result.kind)
|
else:
|
||||||
|
result = raiseCannotEval(c, n)
|
||||||
|
|
||||||
proc evalAddr(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
proc evalAddr(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
result = evalAux(c, n.sons[0], {efLValue})
|
||||||
|
|
@ -737,7 +734,7 @@ proc evalAppendStrCh(c: PEvalContext, n: PNode): PNode =
|
||||||
var b = result
|
var b = result
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkStrLit..nkTripleStrLit: add(a.strVal, chr(int(getOrdValue(b))))
|
of nkStrLit..nkTripleStrLit: add(a.strVal, chr(int(getOrdValue(b))))
|
||||||
else: InternalError(n.info, "evalAppendStrCh")
|
else: return raiseCannotEval(c, n)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalConStrStr(c: PEvalContext, n: PNode): PNode =
|
proc evalConStrStr(c: PEvalContext, n: PNode): PNode =
|
||||||
|
|
@ -759,7 +756,7 @@ proc evalAppendStrStr(c: PEvalContext, n: PNode): PNode =
|
||||||
var b = result
|
var b = result
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkStrLit..nkTripleStrLit: a.strVal = a.strVal & getStrOrChar(b)
|
of nkStrLit..nkTripleStrLit: a.strVal = a.strVal & getStrOrChar(b)
|
||||||
else: InternalError(n.info, "evalAppendStrStr")
|
else: return raiseCannotEval(c, n)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalAppendSeqElem(c: PEvalContext, n: PNode): PNode =
|
proc evalAppendSeqElem(c: PEvalContext, n: PNode): PNode =
|
||||||
|
|
@ -770,7 +767,7 @@ proc evalAppendSeqElem(c: PEvalContext, n: PNode): PNode =
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var b = result
|
var b = result
|
||||||
if a.kind == nkBracket: addSon(a, copyTree(b))
|
if a.kind == nkBracket: addSon(a, copyTree(b))
|
||||||
else: InternalError(n.info, "evalAppendSeqElem")
|
else: return raiseCannotEval(c, n)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalRepr(c: PEvalContext, n: PNode): PNode =
|
proc evalRepr(c: PEvalContext, n: PNode): PNode =
|
||||||
|
|
@ -820,28 +817,19 @@ proc evalTemplateAux*(templ, actual: PNode, sym: PSym): PNode =
|
||||||
result.sons[i] = evalTemplateAux(templ.sons[i], actual, sym)
|
result.sons[i] = evalTemplateAux(templ.sons[i], actual, sym)
|
||||||
|
|
||||||
proc evalTemplateArgs(n: PNode, s: PSym): PNode =
|
proc evalTemplateArgs(n: PNode, s: PSym): PNode =
|
||||||
var
|
|
||||||
f, a: int
|
|
||||||
arg: PNode
|
|
||||||
|
|
||||||
f = sonsLen(s.typ)
|
|
||||||
|
|
||||||
# if the template has zero arguments, it can be called without ``()``
|
# if the template has zero arguments, it can be called without ``()``
|
||||||
# `n` is then a nkSym or something similar
|
# `n` is then a nkSym or something similar
|
||||||
|
var a: int
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
|
||||||
a = sonsLen(n)
|
a = sonsLen(n)
|
||||||
else: a = 0
|
else: a = 0
|
||||||
|
var f = sonsLen(s.typ)
|
||||||
if a > f: GlobalError(n.info, errWrongNumberOfArguments)
|
if a > f: GlobalError(n.info, errWrongNumberOfArguments)
|
||||||
|
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
for i in countup(1, f - 1):
|
for i in countup(1, f - 1):
|
||||||
if i < a:
|
var arg = if i < a: n.sons[i] else: copyTree(s.typ.n.sons[i].sym.ast)
|
||||||
arg = n.sons[i]
|
|
||||||
else:
|
|
||||||
arg = copyTree(s.typ.n.sons[i].sym.ast)
|
|
||||||
|
|
||||||
addSon(result, arg)
|
addSon(result, arg)
|
||||||
|
|
||||||
var evalTemplateCounter = 0
|
var evalTemplateCounter = 0
|
||||||
|
|
@ -886,7 +874,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
case m
|
case m
|
||||||
of mNone: result = evalCall(c, n)
|
of mNone: result = evalCall(c, n)
|
||||||
of mOf: result = evalOf(c, n)
|
of mOf: result = evalOf(c, n)
|
||||||
of mSizeOf: internalError(n.info, "sizeof() should have been evaluated")
|
of mSizeOf: result = raiseCannotEval(c, n)
|
||||||
of mHigh: result = evalHigh(c, n)
|
of mHigh: result = evalHigh(c, n)
|
||||||
of mAssert: result = evalAssert(c, n)
|
of mAssert: result = evalAssert(c, n)
|
||||||
of mExit: result = evalExit(c, n)
|
of mExit: result = evalExit(c, n)
|
||||||
|
|
@ -1070,7 +1058,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
internalError(n.info, "request to create a NimNode with invalid kind")
|
internalError(n.info, "request to create a NimNode with invalid kind")
|
||||||
result = newNodeI(TNodeKind(int(k)),
|
result = newNodeI(TNodeKind(int(k)),
|
||||||
if a.kind == nkNilLit: n.info else: a.info)
|
if a.kind == nkNilLit: n.info else: a.info)
|
||||||
of mNCopyNimNode:
|
of mNCopyNimNode:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
result = copyNode(result)
|
result = copyNode(result)
|
||||||
|
|
@ -1235,9 +1223,9 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
|
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
|
||||||
nkLambda, nkContinueStmt, nkIdent:
|
nkLambda, nkContinueStmt, nkIdent:
|
||||||
stackTrace(c, n, errCannotInterpretNodeX, $n.kind)
|
result = raiseCannotEval(c, n)
|
||||||
else: InternalError(n.info, "evalAux: " & $n.kind)
|
else: InternalError(n.info, "evalAux: " & $n.kind)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
||||||
inc(gNestedEvals)
|
inc(gNestedEvals)
|
||||||
|
|
||||||
|
|
@ -1248,8 +1236,11 @@ proc eval*(c: PEvalContext, n: PNode): PNode =
|
||||||
gWhileCounter = evalMaxIterations
|
gWhileCounter = evalMaxIterations
|
||||||
gNestedEvals = evalMaxRecDepth
|
gNestedEvals = evalMaxRecDepth
|
||||||
result = evalAux(c, n, {})
|
result = evalAux(c, n, {})
|
||||||
if (result.kind == nkExceptBranch) and (sonsLen(result) >= 1):
|
if result.kind == nkExceptBranch:
|
||||||
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
|
if sonsLen(result) >= 1:
|
||||||
|
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
|
||||||
|
else:
|
||||||
|
stackTrace(c, n, errCannotInterpretNodeX, renderTree(n))
|
||||||
|
|
||||||
proc evalConstExpr*(module: PSym, e: PNode): PNode =
|
proc evalConstExpr*(module: PSym, e: PNode): PNode =
|
||||||
var p = newEvalContext(module, "", true)
|
var p = newEvalContext(module, "", true)
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ const
|
||||||
errXExpectsObjectTypes: "\'$1\' expects object types",
|
errXExpectsObjectTypes: "\'$1\' expects object types",
|
||||||
errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype",
|
errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype",
|
||||||
errTooManyIterations: "interpretation requires too many iterations",
|
errTooManyIterations: "interpretation requires too many iterations",
|
||||||
errCannotInterpretNodeX: "cannot interpret node kind \'$1\'",
|
errCannotInterpretNodeX: "cannot evaluate \'$1\'",
|
||||||
errFieldXNotFound: "field \'$1\' cannot be found",
|
errFieldXNotFound: "field \'$1\' cannot be found",
|
||||||
errInvalidConversionFromTypeX: "invalid conversion from type \'$1\'",
|
errInvalidConversionFromTypeX: "invalid conversion from type \'$1\'",
|
||||||
errAssertionFailed: "assertion failed",
|
errAssertionFailed: "assertion failed",
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -3,11 +3,11 @@ Version 0.8.14
|
||||||
|
|
||||||
- optimize unused constants away (affected by HLO)
|
- optimize unused constants away (affected by HLO)
|
||||||
- fix thread tests
|
- fix thread tests
|
||||||
- error message for imported procs in compiletime mode
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
- GC: marker procs for native Nimrod GC and Boehm GC; precise stack marking
|
||||||
- dead code elim for JS backend; 'of' operator for JS backend
|
- dead code elim for JS backend; 'of' operator for JS backend
|
||||||
- test the sort implementation again
|
- test the sort implementation again
|
||||||
- 'let x = y'
|
- 'let x = y'
|
||||||
|
|
@ -56,7 +56,6 @@ Bugs
|
||||||
version 0.9.XX
|
version 0.9.XX
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- GC: marker procs for native Nimrod GC and Boehm GC; precise stack marking
|
|
||||||
- implicit ref/ptr->var conversion; the compiler may store an object
|
- implicit ref/ptr->var conversion; the compiler may store an object
|
||||||
implicitly on the heap for write barrier efficiency; better:
|
implicitly on the heap for write barrier efficiency; better:
|
||||||
proc specialization in the code gen
|
proc specialization in the code gen
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue