fixes #3882
This commit is contained in:
parent
a406ebbac9
commit
426306eeb4
2 changed files with 59 additions and 31 deletions
|
|
@ -1818,7 +1818,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
template setResult(e: expr) =
|
template setResult(e: expr) =
|
||||||
if semCheck: result = semStmt(c, e) # do not open a new scope!
|
if semCheck: result = semExpr(c, e) # do not open a new scope!
|
||||||
else: result = e
|
else: result = e
|
||||||
|
|
||||||
# Check if the node is "when nimvm"
|
# Check if the node is "when nimvm"
|
||||||
|
|
@ -1827,6 +1827,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
# else:
|
# else:
|
||||||
# ...
|
# ...
|
||||||
var whenNimvm = false
|
var whenNimvm = false
|
||||||
|
var typ = commonTypeBegin
|
||||||
if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and
|
if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and
|
||||||
n.sons[1].kind == nkElse:
|
n.sons[1].kind == nkElse:
|
||||||
let exprNode = n.sons[0].sons[0]
|
let exprNode = n.sons[0].sons[0]
|
||||||
|
|
@ -1843,7 +1844,8 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
checkSonsLen(it, 2)
|
checkSonsLen(it, 2)
|
||||||
if whenNimvm:
|
if whenNimvm:
|
||||||
if semCheck:
|
if semCheck:
|
||||||
it.sons[1] = semStmt(c, it.sons[1])
|
it.sons[1] = semExpr(c, it.sons[1])
|
||||||
|
typ = commonType(typ, it.sons[1].typ)
|
||||||
result = n # when nimvm is not elimited until codegen
|
result = n # when nimvm is not elimited until codegen
|
||||||
else:
|
else:
|
||||||
var e = semConstExpr(c, it.sons[0])
|
var e = semConstExpr(c, it.sons[0])
|
||||||
|
|
@ -1857,12 +1859,14 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||||
checkSonsLen(it, 1)
|
checkSonsLen(it, 1)
|
||||||
if result == nil or whenNimvm:
|
if result == nil or whenNimvm:
|
||||||
if semCheck:
|
if semCheck:
|
||||||
it.sons[0] = semStmt(c, it.sons[0])
|
it.sons[0] = semExpr(c, it.sons[0])
|
||||||
|
typ = commonType(typ, it.sons[0].typ)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = it.sons[0]
|
result = it.sons[0]
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = newNodeI(nkEmpty, n.info)
|
result = newNodeI(nkEmpty, n.info)
|
||||||
|
if whenNimvm: result.typ = typ
|
||||||
# The ``when`` statement implements the mechanism for platform dependent
|
# The ``when`` statement implements the mechanism for platform dependent
|
||||||
# code. Thus we try to ensure here consistent ID allocation after the
|
# code. Thus we try to ensure here consistent ID allocation after the
|
||||||
# ``when`` statement.
|
# ``when`` statement.
|
||||||
|
|
|
||||||
|
|
@ -3042,34 +3042,6 @@ when not defined(JS): #and not defined(nimscript):
|
||||||
{.pop.} # stacktrace
|
{.pop.} # stacktrace
|
||||||
|
|
||||||
when not defined(nimscript):
|
when not defined(nimscript):
|
||||||
proc likely*(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}
|
|
||||||
## Hints the optimizer that `val` is likely going to be true.
|
|
||||||
##
|
|
||||||
## You can use this proc to decorate a branch condition. On certain
|
|
||||||
## platforms this can help the processor predict better which branch is
|
|
||||||
## going to be run. Example:
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
## for value in inputValues:
|
|
||||||
## if likely(value <= 100):
|
|
||||||
## process(value)
|
|
||||||
## else:
|
|
||||||
## echo "Value too big!"
|
|
||||||
|
|
||||||
proc unlikely*(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}
|
|
||||||
## Hints the optimizer that `val` is likely going to be false.
|
|
||||||
##
|
|
||||||
## You can use this proc to decorate a branch condition. On certain
|
|
||||||
## platforms this can help the processor predict better which branch is
|
|
||||||
## going to be run. Example:
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
## for value in inputValues:
|
|
||||||
## if unlikely(value > 100):
|
|
||||||
## echo "Value too big!"
|
|
||||||
## else:
|
|
||||||
## process(value)
|
|
||||||
|
|
||||||
proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
|
proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
|
||||||
## retrieves the raw proc pointer of the closure `x`. This is
|
## retrieves the raw proc pointer of the closure `x`. This is
|
||||||
## useful for interfacing closures with C.
|
## useful for interfacing closures with C.
|
||||||
|
|
@ -3137,6 +3109,58 @@ proc quit*(errormsg: string, errorcode = QuitFailure) {.noReturn.} =
|
||||||
{.pop.} # checks
|
{.pop.} # checks
|
||||||
{.pop.} # hints
|
{.pop.} # hints
|
||||||
|
|
||||||
|
when not defined(JS):
|
||||||
|
proc likely_proc(val: bool): bool {.importc: "likely", nodecl, nosideeffect.}
|
||||||
|
proc unlikely_proc(val: bool): bool {.importc: "unlikely", nodecl, nosideeffect.}
|
||||||
|
|
||||||
|
template likely*(val: bool): bool =
|
||||||
|
## Hints the optimizer that `val` is likely going to be true.
|
||||||
|
##
|
||||||
|
## You can use this template to decorate a branch condition. On certain
|
||||||
|
## platforms this can help the processor predict better which branch is
|
||||||
|
## going to be run. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
## for value in inputValues:
|
||||||
|
## if likely(value <= 100):
|
||||||
|
## process(value)
|
||||||
|
## else:
|
||||||
|
## echo "Value too big!"
|
||||||
|
##
|
||||||
|
## On backends without branch prediction (JS and the nimscript VM), this
|
||||||
|
## template will not affect code execution.
|
||||||
|
when nimvm:
|
||||||
|
val
|
||||||
|
else:
|
||||||
|
when defined(JS):
|
||||||
|
val
|
||||||
|
else:
|
||||||
|
likely_proc(val)
|
||||||
|
|
||||||
|
template unlikely*(val: bool): bool =
|
||||||
|
## Hints the optimizer that `val` is likely going to be false.
|
||||||
|
##
|
||||||
|
## You can use this proc to decorate a branch condition. On certain
|
||||||
|
## platforms this can help the processor predict better which branch is
|
||||||
|
## going to be run. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
## for value in inputValues:
|
||||||
|
## if unlikely(value > 100):
|
||||||
|
## echo "Value too big!"
|
||||||
|
## else:
|
||||||
|
## process(value)
|
||||||
|
##
|
||||||
|
## On backends without branch prediction (JS and the nimscript VM), this
|
||||||
|
## template will not affect code execution.
|
||||||
|
when nimvm:
|
||||||
|
val
|
||||||
|
else:
|
||||||
|
when defined(JS):
|
||||||
|
val
|
||||||
|
else:
|
||||||
|
unlikely_proc(val)
|
||||||
|
|
||||||
proc `/`*(x, y: int): float {.inline, noSideEffect.} =
|
proc `/`*(x, y: int): float {.inline, noSideEffect.} =
|
||||||
## integer division that results in a float.
|
## integer division that results in a float.
|
||||||
result = toFloat(x) / toFloat(y)
|
result = toFloat(x) / toFloat(y)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue