| // 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. |
| |
| // @dart=2.9 |
| |
| @JS() |
| library native_version_javascript; |
| |
| import 'package:js/js.dart'; |
| import 'native_version.dart'; |
| |
| const NativeBigIntMethods nativeBigInt = _Methods(); |
| |
| @JS('eval') |
| external Object _eval(String s); |
| |
| @JS('bigint_parse') |
| external Object _parse(String s); |
| |
| @JS('bigint_toString') |
| external String _toStringMethod(Object o); |
| |
| @JS('bigint_bitLength') |
| external int _bitLength(Object o); |
| |
| @JS('bigint_isEven') |
| external bool _isEven(Object o); |
| |
| @JS('bigint_add') |
| external Object _add(Object left, Object right); |
| |
| @JS('bigint_shiftLeft') |
| external Object _shiftLeft(Object o, Object i); |
| |
| @JS('bigint_shiftRight') |
| external Object _shiftRight(Object o, Object i); |
| |
| @JS('bigint_subtract') |
| external Object _subtract(Object left, Object right); |
| |
| @JS('bigint_fromInt') |
| external Object _fromInt(int i); |
| |
| class _Methods implements NativeBigIntMethods { |
| 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 |
| Object parse(String string) => _parse(string); |
| |
| @override |
| String toStringMethod(Object value) => _toStringMethod(value); |
| |
| @override |
| Object fromInt(int i) => _fromInt(i); |
| |
| @override |
| Object get one => _one; |
| |
| @override |
| Object get eight => _eight; |
| |
| @override |
| int bitLength(Object value) => _bitLength(value); |
| |
| @override |
| bool isEven(Object value) => _isEven(value); |
| |
| @override |
| Object add(Object left, Object right) => _add(left, right); |
| |
| @override |
| Object shiftLeft(Object value, Object count) => _shiftLeft(value, count); |
| |
| @override |
| Object shiftRight(Object value, Object count) => _shiftRight(value, count); |
| |
| @override |
| Object subtract(Object left, Object 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; |