Skip to content

Commit cbc9470

Browse files
authored
Merge pull request #26 from WebAssembly/remove-bigints
Close #24: Remove bigint operations.
2 parents 74b00d3 + 3e24fd5 commit cbc9470

File tree

1 file changed

+15
-145
lines changed

1 file changed

+15
-145
lines changed

proposals/js-primitive-builtins/Overview.md

Lines changed: 15 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ Builtins should be simple and only provide functionality that is semantically al
2323

2424
The proposed list of builtins is based on experience with the Scala.js-to-Wasm compiler.
2525
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).
2827

2928
Here is a quick overview of the builtins we propose.
3029
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.
5049
* (creation is achieved by importing the functions `Symbol` and `Symbol.for`)
5150
* Bigint (`wasm:js-bigint`):
5251
* 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)
5753

5854
## About the "universal representation"
5955

@@ -426,145 +422,6 @@ func test(
426422
}
427423
```
428424

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-
return BigInt(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-
return BigInt.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-
return Number(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-
return 1;
551-
return 0;
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-
568425
## Not included
569426

570427
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
623480
In JavaScript, we do this with the accessor `Symbol.prototype.description`.
624481
However, compared to the rest of `"wasm:js-symbol"`, it looks out of place.
625482
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

Comments
 (0)