0947f85299
This also allows the BigIntParsePrint benchmark to actually run on dart2wasm. Bug: #61550 Change-Id: I6a6a6964d95195e8e06fcecbcad776045dddc733 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/453682 Reviewed-by: Srujan Gaddam <srujzs@google.com>
132 lines
3.3 KiB
Dart
132 lines
3.3 KiB
Dart
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
@JS()
|
|
library;
|
|
|
|
import 'dart:js_interop';
|
|
|
|
import 'native_version.dart';
|
|
|
|
const NativeBigIntMethods nativeBigInt = _Methods();
|
|
|
|
@JS('eval')
|
|
external JSAny? _eval(String s);
|
|
|
|
@JS('bigint_parse')
|
|
external JSBigInt _parse(String s);
|
|
|
|
@JS('bigint_toString')
|
|
external String _toStringMethod(JSBigInt o);
|
|
|
|
@JS('bigint_bitLength')
|
|
external int _bitLength(JSBigInt o);
|
|
|
|
@JS('bigint_isEven')
|
|
external bool _isEven(JSBigInt o);
|
|
|
|
@JS('bigint_add')
|
|
external JSBigInt _add(JSBigInt left, JSBigInt right);
|
|
|
|
@JS('bigint_shiftLeft')
|
|
external JSBigInt _shiftLeft(JSBigInt o, JSBigInt i);
|
|
|
|
@JS('bigint_shiftRight')
|
|
external JSBigInt _shiftRight(JSBigInt o, JSBigInt i);
|
|
|
|
@JS('bigint_subtract')
|
|
external JSBigInt _subtract(JSBigInt left, JSBigInt right);
|
|
|
|
@JS('bigint_fromInt')
|
|
external JSBigInt _fromInt(int i);
|
|
|
|
class _Methods implements NativeBigIntMethods<JSBigInt> {
|
|
static bool _initialized = false;
|
|
static bool _enabled = false;
|
|
|
|
const _Methods();
|
|
|
|
@override
|
|
bool get enabled {
|
|
if (!_initialized) {
|
|
_initialize();
|
|
}
|
|
return _enabled;
|
|
}
|
|
|
|
void _initialize() {
|
|
_initialized = true;
|
|
try {
|
|
_setup();
|
|
_enabled = true;
|
|
} catch (e) {
|
|
// We get here if the JavaScript implementation does not have BigInt (or
|
|
// run in a stand-alone JavaScript implementation without the right
|
|
// 'preamble').
|
|
//
|
|
// Print so we can see what failed.
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
@override
|
|
JSBigInt parse(String string) => _parse(string);
|
|
|
|
@override
|
|
String toStringMethod(JSBigInt value) => _toStringMethod(value);
|
|
|
|
@override
|
|
JSBigInt fromInt(int i) => _fromInt(i);
|
|
|
|
@override
|
|
JSBigInt get one => _one;
|
|
|
|
@override
|
|
JSBigInt get eight => _eight;
|
|
|
|
@override
|
|
int bitLength(JSBigInt value) => _bitLength(value);
|
|
|
|
@override
|
|
bool isEven(JSBigInt value) => _isEven(value);
|
|
|
|
@override
|
|
JSBigInt add(JSBigInt left, JSBigInt right) => _add(left, right);
|
|
|
|
@override
|
|
JSBigInt shiftLeft(JSBigInt value, JSBigInt count) =>
|
|
_shiftLeft(value, count);
|
|
|
|
@override
|
|
JSBigInt shiftRight(JSBigInt value, JSBigInt count) =>
|
|
_shiftRight(value, count);
|
|
|
|
@override
|
|
JSBigInt subtract(JSBigInt left, JSBigInt right) => _subtract(left, right);
|
|
}
|
|
|
|
void _setup() {
|
|
_one = _eval('1n'); // Throws if JavaScript does not have BigInt.
|
|
_eight = _eval('8n');
|
|
|
|
_eval('self.bigint_parse = function parse(s) { return BigInt(s); }');
|
|
_eval('self.bigint_toString = function toString(b) { return b.toString(); }');
|
|
_eval('self.bigint_add = function add(a, b) { return a + b; }');
|
|
_eval('self.bigint_shiftLeft = function shl(v, i) { return v << i; }');
|
|
_eval('self.bigint_shiftRight = function shr(v, i) { return v >> i; }');
|
|
_eval('self.bigint_subtract = function subtract(a, b) { return a - b; }');
|
|
_eval('self.bigint_fromInt = function fromInt(i) { return BigInt(i); }');
|
|
|
|
_eval(
|
|
'self.bigint_bitLength = function bitLength(b) {'
|
|
'return b == 0 ? 0 : (b < 0 ? ~b : b).toString(2).length;'
|
|
'}',
|
|
);
|
|
_eval('self.bigint_isEven = function isEven(b) { return (b & 1n) == 0n; }');
|
|
}
|
|
|
|
// `dynamic` to allow null initialization pre- and post- NNBD.
|
|
dynamic _one;
|
|
dynamic _eight;
|