mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 08:04:20 +00:00
fixes #3882
This commit is contained in:
@@ -1818,7 +1818,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||
result = nil
|
||||
|
||||
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
|
||||
|
||||
# Check if the node is "when nimvm"
|
||||
@@ -1827,6 +1827,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||
# else:
|
||||
# ...
|
||||
var whenNimvm = false
|
||||
var typ = commonTypeBegin
|
||||
if n.sons.len == 2 and n.sons[0].kind == nkElifBranch and
|
||||
n.sons[1].kind == nkElse:
|
||||
let exprNode = n.sons[0].sons[0]
|
||||
@@ -1843,7 +1844,8 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||
checkSonsLen(it, 2)
|
||||
if whenNimvm:
|
||||
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
|
||||
else:
|
||||
var e = semConstExpr(c, it.sons[0])
|
||||
@@ -1857,12 +1859,14 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
||||
checkSonsLen(it, 1)
|
||||
if result == nil or whenNimvm:
|
||||
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:
|
||||
result = it.sons[0]
|
||||
else: illFormedAst(n)
|
||||
if result == nil:
|
||||
result = newNodeI(nkEmpty, n.info)
|
||||
if whenNimvm: result.typ = typ
|
||||
# The ``when`` statement implements the mechanism for platform dependent
|
||||
# code. Thus we try to ensure here consistent ID allocation after the
|
||||
# ``when`` statement.
|
||||
|
||||
@@ -3042,34 +3042,6 @@ when not defined(JS): #and not defined(nimscript):
|
||||
{.pop.} # stacktrace
|
||||
|
||||
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.} =
|
||||
## retrieves the raw proc pointer of the closure `x`. This is
|
||||
## useful for interfacing closures with C.
|
||||
@@ -3137,6 +3109,58 @@ proc quit*(errormsg: string, errorcode = QuitFailure) {.noReturn.} =
|
||||
{.pop.} # checks
|
||||
{.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.} =
|
||||
## integer division that results in a float.
|
||||
result = toFloat(x) / toFloat(y)
|
||||
|
||||
Reference in New Issue
Block a user