Skip to content

Commit

Permalink
Deprecate asm stmt for js target (#23149)
Browse files Browse the repository at this point in the history
why ?

- We already have an emit that does the same thing
- The name asm itself is a bit confusing, you might think it's an alias
for asm.js or something else.
- The asm keyword is used differently on different compiler targets (it
makes it inexpressive).
- Does anyone (other than some compiler libraries) use asm instead of
emit ? If yes, it's a bit strange to use asm somewhere and emit
somewhere. By making the asm keyword for js target deprecated, there
would be even less use of the asm keyword for js target, reducing the
amount of confusion.
- New users might accidentally use a non-universal approach via the asm
keyword instead of emit, and then when they learn about asm, try to
figure out what the differences are.

see https://forum.nim-lang.org/t/10821

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
  • Loading branch information
ASVIEST and Araq authored Jan 2, 2024
1 parent c7d742e commit 20d79c9
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 114 deletions.
12 changes: 9 additions & 3 deletions compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1136,10 +1136,14 @@ proc genBreakStmt(p: PProc, n: PNode) =
p.blocks[idx].id = abs(p.blocks[idx].id) # label is used
lineF(p, "break Label$1;$n", [rope(p.blocks[idx].id)])

proc genAsmOrEmitStmt(p: PProc, n: PNode) =
proc genAsmOrEmitStmt(p: PProc, n: PNode; isAsmStmt = false) =
genLineDir(p, n)
p.body.add p.indentLine("")
for i in 0..<n.len:
let offset =
if isAsmStmt: 1 # first son is pragmas
else: 0

for i in offset..<n.len:
let it = n[i]
case it.kind
of nkStrLit..nkTripleStrLit:
Expand Down Expand Up @@ -2981,7 +2985,9 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
genLineDir(p, n)
gen(p, n[0], r)
r.res = "var _ = " & r.res
of nkAsmStmt: genAsmOrEmitStmt(p, n)
of nkAsmStmt:
warningDeprecated(p.config, n.info, "'asm' for the JS target is deprecated, use the 'emit' pragma")
genAsmOrEmitStmt(p, n, true)
of nkTryStmt, nkHiddenTryStmt: genTry(p, n, r)
of nkRaiseStmt: genRaiseStmt(p, n)
of nkTypeSection, nkCommentStmt, nkIncludeStmt,
Expand Down
4 changes: 2 additions & 2 deletions lib/js/asyncjs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ since (1, 5, 1):
else:
type A = impl(onSuccess(default(T)))
var ret: A
asm "`ret` = `future`.then(`onSuccess`, `onReject`)"
{.emit: "`ret` = `future`.then(`onSuccess`, `onReject`)".}
return ret

proc catch*[T](future: Future[T], onReject: OnReject): Future[void] =
Expand All @@ -266,4 +266,4 @@ since (1, 5, 1):

discard main()

asm "`result` = `future`.catch(`onReject`)"
{.emit: "`result` = `future`.catch(`onReject`)".}
2 changes: 1 addition & 1 deletion lib/js/jsre.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func contains*(pattern: cstring; self: RegExp): bool =
assert jsregex in r"abc"
assert jsregex notin r"abcd"
assert "xabc".contains jsregex
asm "`result` = `self`.test(`pattern`);"
{.emit: "`result` = `self`.test(`pattern`);".}

func startsWith*(pattern: cstring; self: RegExp): bool =
## Tests if string starts with given RegExp
Expand Down
6 changes: 3 additions & 3 deletions lib/pure/hashes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ proc hashData*(data: pointer, size: int): Hash =
var h: Hash = 0
when defined(js):
var p: cstring
asm """`p` = `Data`"""
{.emit: """`p` = `Data`""".}
else:
var p = cast[cstring](data)
var i = 0
Expand All @@ -217,7 +217,7 @@ else:
when defined(js):
var objectID = 0
proc getObjectId(x: pointer): int =
asm """
{.emit: """
if (typeof `x` == "object") {
if ("_NimID" in `x`)
`result` = `x`["_NimID"];
Expand All @@ -226,7 +226,7 @@ when defined(js):
`x`["_NimID"] = `result`;
}
}
"""
""".}

proc hash*(x: pointer): Hash {.inline.} =
## Efficient `hash` overload.
Expand Down
13 changes: 7 additions & 6 deletions lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,9 @@ when defined(js):
else: assert false

proc len(x: JsObject): int =
asm """
{.emit: """
`result` = `x`.length;
"""
""".}

proc convertObject(x: JsObject): JsonNode =
var isRawNumber = false
Expand All @@ -1004,14 +1004,15 @@ when defined(js):
result.add(x[i].convertObject())
of JObject:
result = newJObject()
asm """for (var property in `x`) {
{.emit: """for (var property in `x`) {
if (`x`.hasOwnProperty(property)) {
"""
""".}

var nimProperty: cstring
var nimValue: JsObject
asm "`nimProperty` = property; `nimValue` = `x`[property];"
{.emit: "`nimProperty` = property; `nimValue` = `x`[property];".}
result[$nimProperty] = nimValue.convertObject()
asm "}}"
{.emit: "}}".}
of JInt:
result = newJInt(x.to(int))
of JFloat:
Expand Down
4 changes: 2 additions & 2 deletions lib/pure/math.nim
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,13 @@ when defined(js):
let a = newFloat64Array(buffer)
let b = newUint32Array(buffer)
a[0] = x
asm """
{.emit: """
function updateBit(num, bitPos, bitVal) {
return (num & ~(1 << bitPos)) | (bitVal << bitPos);
}
`b`[1] = updateBit(`b`[1], 31, `sgn`);
`result` = `a`[0]
"""
""".}

proc signbit*(x: SomeFloat): bool {.inline, since: (1, 5, 1).} =
## Returns true if `x` is negative, false otherwise.
Expand Down
16 changes: 8 additions & 8 deletions lib/std/exitprocs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ initLock(gFunsLock)
when defined(js):
proc addAtExit(quitProc: proc() {.noconv.}) =
when defined(nodejs):
asm """
{.emit: """
process.on('exit', `quitProc`);
"""
""".}
elif defined(js):
asm """
{.emit: """
window.onbeforeunload = `quitProc`;
"""
""".}
else:
proc addAtExit(quitProc: proc() {.noconv.}) {.
importc: "atexit", header: "<stdlib.h>".}
Expand Down Expand Up @@ -72,16 +72,16 @@ proc addExitProc*(cl: proc() {.noconv.}) =
when not defined(nimscript) and (not defined(js) or defined(nodejs)):
proc getProgramResult*(): int =
when defined(js) and defined(nodejs):
asm """
{.emit: """
`result` = process.exitCode;
"""
""".}
else:
result = programResult

proc setProgramResult*(a: int) =
when defined(js) and defined(nodejs):
asm """
{.emit: """
process.exitCode = `a`;
"""
""".}
else:
programResult = a
4 changes: 2 additions & 2 deletions lib/std/formatfloat.nim
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ when defined(js):
proc nimFloatToString(a: float): cstring =
## ensures the result doesn't print like an integer, i.e. return 2.0, not 2
# print `-0.0` properly
asm """
{.emit: """
function nimOnlyDigitsOrMinus(n) {
return n.toString().match(/^-?\d+$/);
}
Expand All @@ -116,7 +116,7 @@ when defined(js):
`result` = `a`+".0"
}
}
"""
""".}

proc addFloat*(result: var string; x: float | float32) {.inline.} =
## Converts float to its string representation and appends it to `result`.
Expand Down
4 changes: 2 additions & 2 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1871,14 +1871,14 @@ when defined(js) or defined(nimdoc):
tmp.add(cstring("ab"))
tmp.add(cstring("cd"))
doAssert tmp == "abcd"
asm """
{.emit: """
if (`x` === null) { `x` = []; }
var off = `x`.length;
`x`.length += `y`.length;
for (var i = 0; i < `y`.length; ++i) {
`x`[off+i] = `y`.charCodeAt(i);
}
"""
""".}
proc add*(x: var cstring, y: cstring) {.magic: "AppendStrStr".} =
## Appends `y` to `x` in place.
## Only implemented for JS backend.
Expand Down
2 changes: 1 addition & 1 deletion lib/system/comparisons.nim
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
return true
else:
var sameObject = false
asm """`sameObject` = `x` === `y`"""
{.emit: """`sameObject` = `x` === `y`""".}
if sameObject: return true

if x.len != y.len:
Expand Down
Loading

0 comments on commit 20d79c9

Please sign in to comment.