You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -23,8 +23,7 @@ Builtins should be simple and only provide functionality that is semantically al
23
23
24
24
The proposed list of builtins is based on experience with the Scala.js-to-Wasm compiler.
25
25
Through benchmarking and profiling, we have identified a number of operations that show up high on profiles for no good reason, other than they require glue code to JavaScript.
26
-
We have extrapolated to some additional operations that we think are likely relevant to other toolchains.
27
-
The `bigint` were requested by the `wasm_of_caml` toolchain.
26
+
We have extrapolated to operations that we think are likely relevant to other toolchains: conversions of *unsigned* integers (Scala happens to only have signed integer semantics in hot paths, but this is quite peculiar), and symbol equality (though that is still an open question).
28
27
29
28
Here is a quick overview of the builtins we propose.
30
29
The original set was fairly broad, so that we could discuss what is actually useful and what might be overreaching.
@@ -50,10 +49,7 @@ During Stage 1 discussions, the set was significantly reduced.
50
49
* (creation is achieved by importing the functions `Symbol` and `Symbol.for`)
51
50
* Bigint (`wasm:js-bigint`):
52
51
* Type test: `test`
53
-
* Create from primitive: `fromF64`, `fromI64`, `fromU64`
54
-
* Extract to primitive: `convertToF64`, `wrapToI64`
55
-
* Operations: `add`, `pow`, `shl`, etc. (the ones corresponding to JS operators)
56
-
* Conversion to string: `toString`
52
+
* (all other manipulations lacked motivation and were removed)
57
53
58
54
## About the "universal representation"
59
55
@@ -426,145 +422,6 @@ func test(
426
422
}
427
423
```
428
424
429
-
### "wasm:js-bigint" "fromF64"
430
-
431
-
```js
432
-
func fromF64(
433
-
x: f64
434
-
) -> (ref extern) {
435
-
// NOTE: BigInt(x) would throw a RangeError in the situation below.
436
-
// Trap instead.
437
-
if (!Number.isInteger(x))
438
-
trap();
439
-
440
-
returnBigInt(x);
441
-
}
442
-
```
443
-
444
-
### "wasm:js-bigint" "fromI64"
445
-
446
-
```js
447
-
func fromI64(
448
-
x: i64
449
-
) -> (ref extern) {
450
-
// NOTE: `x` is interpreted as a signed JS `bigint` by the Wasm-to-JS
451
-
// interface, so this appears as a no-op.
452
-
return x;
453
-
}
454
-
```
455
-
456
-
### "wasm:js-bigint" "fromU64"
457
-
458
-
```js
459
-
func fromU64(
460
-
x: i64
461
-
) -> (ref extern) {
462
-
// NOTE: `x` is interpreted as a signed JS `bigint` by the Wasm-to-JS
463
-
// interface. Reinterpret it as unsigned.
464
-
returnBigInt.asUint(64, x);
465
-
}
466
-
```
467
-
468
-
### "wasm:js-bigint" "convertToF64"
469
-
470
-
```js
471
-
func convertToF64(
472
-
x: externref
473
-
) -> f64 {
474
-
if (typeof x !=="bigint")
475
-
trap();
476
-
477
-
returnNumber(x);
478
-
}
479
-
```
480
-
481
-
### "wasm:js-bigint" "wrapToI64"
482
-
483
-
```js
484
-
func wrapToI64(
485
-
x: externref
486
-
) -> i64 {
487
-
if (typeof x !=="bigint")
488
-
trap();
489
-
490
-
// NOTE: ToWebAssemblyValue specifies a wrapping conversion via ToBigInt64
491
-
return x;
492
-
}
493
-
```
494
-
495
-
A hypothetical `wrapToU64` would be equivalent, and is therefore not proposed.
496
-
497
-
### "wasm:js-bigint" "add" (and other JS operators)
498
-
499
-
```js
500
-
func add(
501
-
x: externref,
502
-
y: externref
503
-
) -> f64 {
504
-
if (typeof x !=="bigint")
505
-
trap();
506
-
if (typeof y !=="bigint")
507
-
trap();
508
-
509
-
return x + y;
510
-
}
511
-
```
512
-
513
-
The full list of considered operators and corresponding function names are the following.
514
-
See [Table 2 in Numeric Types](https://262.ecma-international.org/#sec-numeric-types) in the ECMAScript specification.
515
-
516
-
| JS operator | Builtin name |
517
-
|-------------|--------------|
518
-
|`-x`|`neg`|
519
-
|`~x`|`not`|
520
-
|`x ** y`|`pow`|
521
-
|`x * y`|`mul`|
522
-
|`x / y`|`div`|
523
-
|`x % y`|`mod`|
524
-
|`x + y`|`add`|
525
-
|`x - y`|`sub`|
526
-
|`x << y`|`shl`|
527
-
|`x >> y`|`sar`|
528
-
|`x === y`|`equals`|
529
-
|`x & y`|`and`|
530
-
|`x ^ y`|`xor`|
531
-
|`x \| y`|`or`|
532
-
533
-
### "wasm:js-bigint" "compare"
534
-
535
-
For consistency with JS String Builtins, we provide a single comparison builtin instead of the 4 operators `<`, `>`, `<=` and `>=`.
536
-
537
-
```js
538
-
func compared(
539
-
x: externref,
540
-
y: externref
541
-
) -> f64 {
542
-
if (typeof x !=="bigint")
543
-
trap();
544
-
if (typeof y !=="bigint")
545
-
trap();
546
-
547
-
if (x < y)
548
-
return-1;
549
-
if (x > y)
550
-
return1;
551
-
return0;
552
-
}
553
-
```
554
-
555
-
### "wasm:js-bigint" "toString"
556
-
557
-
```js
558
-
func toString(
559
-
bigint: externref
560
-
) -> f64 {
561
-
if (typeof bigint !=="bigint")
562
-
trap();
563
-
564
-
return""+ bigint;
565
-
}
566
-
```
567
-
568
425
## Not included
569
426
570
427
This section keeps track of a few things that were considered at some point but removed, although a case could still be made to bring them back.
@@ -623,3 +480,16 @@ A case could be made to provide a builtin to extract the `[[Description]]` of a
623
480
In JavaScript, we do this with the accessor `Symbol.prototype.description`.
624
481
However, compared to the rest of `"wasm:js-symbol"`, it looks out of place.
625
482
It is unlikely that getting the description of a symbol would be on a performance-sensitive path, so we leave it out.
483
+
484
+
### `bigint` operations
485
+
486
+
Initially, this proposal considered operations on `bigint`s (besides the type test).
487
+
The following operations were considered:
488
+
489
+
* Bigint (`wasm:js-bigint`):
490
+
* Create from primitive: `fromF64`, `fromI64`, `fromU64`
491
+
* Extract to primitive: `convertToF64`, `wrapToI64`
492
+
* Operations: `add`, `pow`, `shl`, etc. (the ones corresponding to JS operators)
493
+
* Conversion to string: `toString`
494
+
495
+
This was based on the assumption that some toolchains would use them in hot paths, but that was apparently a misunderstanding (see [#24](https://github.com/WebAssembly/js-primitive-builtins/issues/24)), so we removed them.
0 commit comments