mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 23:48:11 +00:00
LibJS: Convert to_bigint() to ThrowCompletionOr
This commit is contained in:
parent
b8f101888b
commit
e87cea8248
10 changed files with 27 additions and 56 deletions
|
@ -96,9 +96,7 @@ static ThrowCompletionOr<Value> atomic_read_modify_write(GlobalObject& global_ob
|
||||||
|
|
||||||
// 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
|
// 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
|
||||||
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
||||||
value_to_set = value.to_bigint(global_object);
|
value_to_set = TRY(value.to_bigint(global_object));
|
||||||
if (auto* exception = vm.exception())
|
|
||||||
return throw_completion(exception->value());
|
|
||||||
}
|
}
|
||||||
// 5. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
|
// 5. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
|
||||||
else {
|
else {
|
||||||
|
@ -228,14 +226,10 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(GlobalObject& globa
|
||||||
// 5. If typedArray.[[ContentType]] is BigInt, then
|
// 5. If typedArray.[[ContentType]] is BigInt, then
|
||||||
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
||||||
// a. Let expected be ? ToBigInt(expectedValue).
|
// a. Let expected be ? ToBigInt(expectedValue).
|
||||||
expected = vm.argument(2).to_bigint(global_object);
|
expected = TRY(vm.argument(2).to_bigint(global_object));
|
||||||
if (auto* exception = vm.exception())
|
|
||||||
return throw_completion(exception->value());
|
|
||||||
|
|
||||||
// b. Let replacement be ? ToBigInt(replacementValue).
|
// b. Let replacement be ? ToBigInt(replacementValue).
|
||||||
replacement = vm.argument(3).to_bigint(global_object);
|
replacement = TRY(vm.argument(3).to_bigint(global_object));
|
||||||
if (auto* exception = vm.exception())
|
|
||||||
return throw_completion(exception->value());
|
|
||||||
}
|
}
|
||||||
// 6. Else,
|
// 6. Else,
|
||||||
else {
|
else {
|
||||||
|
@ -396,9 +390,7 @@ JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::store)
|
||||||
auto value = vm.argument(2);
|
auto value = vm.argument(2);
|
||||||
Value value_to_set;
|
Value value_to_set;
|
||||||
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt) {
|
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt) {
|
||||||
value_to_set = value.to_bigint(global_object);
|
value_to_set = TRY_OR_DISCARD(value.to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
} else {
|
} else {
|
||||||
value_to_set = Value(value.to_integer_or_infinity(global_object));
|
value_to_set = Value(value.to_integer_or_infinity(global_object));
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
|
|
|
@ -55,7 +55,7 @@ Value BigIntConstructor::call()
|
||||||
return number_to_bigint(global_object, primitive);
|
return number_to_bigint(global_object, primitive);
|
||||||
|
|
||||||
// 4. Otherwise, return ? ToBigInt(value).
|
// 4. Otherwise, return ? ToBigInt(value).
|
||||||
return value.to_bigint(global_object);
|
return TRY_OR_DISCARD(value.to_bigint(global_object));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.2.1.1 BigInt ( value ), https://tc39.es/ecma262/#sec-bigint-constructor-number-value
|
// 21.2.1.1 BigInt ( value ), https://tc39.es/ecma262/#sec-bigint-constructor-number-value
|
||||||
|
|
|
@ -108,7 +108,7 @@ static Value set_view_value(GlobalObject& global_object, Value request_index, Va
|
||||||
|
|
||||||
Value number_value;
|
Value number_value;
|
||||||
if constexpr (IsIntegral<T> && sizeof(T) == 8)
|
if constexpr (IsIntegral<T> && sizeof(T) == 8)
|
||||||
number_value = value.to_bigint(global_object);
|
number_value = TRY_OR_DISCARD(value.to_bigint(global_object));
|
||||||
else
|
else
|
||||||
number_value = value.to_number(global_object);
|
number_value = value.to_number(global_object);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
|
|
|
@ -56,9 +56,7 @@ Value InstantConstructor::construct(FunctionObject& new_target)
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
|
||||||
// 2. Let epochNanoseconds be ? ToBigInt(epochNanoseconds).
|
// 2. Let epochNanoseconds be ? ToBigInt(epochNanoseconds).
|
||||||
auto* epoch_nanoseconds = vm.argument(0).to_bigint(global_object);
|
auto* epoch_nanoseconds = TRY_OR_DISCARD(vm.argument(0).to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// 3. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
// 3. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
||||||
|
@ -141,9 +139,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_milliseconds)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_microseconds)
|
JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_microseconds)
|
||||||
{
|
{
|
||||||
// 1. Set epochMicroseconds to ? ToBigInt(epochMicroseconds).
|
// 1. Set epochMicroseconds to ? ToBigInt(epochMicroseconds).
|
||||||
auto* epoch_microseconds = vm.argument(0).to_bigint(global_object);
|
auto* epoch_microseconds = TRY_OR_DISCARD(vm.argument(0).to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// 2. Let epochNanoseconds be epochMicroseconds × 1000ℤ.
|
// 2. Let epochNanoseconds be epochMicroseconds × 1000ℤ.
|
||||||
auto* epoch_nanoseconds = js_bigint(vm, epoch_microseconds->big_integer().multiplied_by(Crypto::UnsignedBigInteger { 1'000 }));
|
auto* epoch_nanoseconds = js_bigint(vm, epoch_microseconds->big_integer().multiplied_by(Crypto::UnsignedBigInteger { 1'000 }));
|
||||||
|
@ -162,9 +158,7 @@ JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_microseconds)
|
||||||
JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_nanoseconds)
|
JS_DEFINE_NATIVE_FUNCTION(InstantConstructor::from_epoch_nanoseconds)
|
||||||
{
|
{
|
||||||
// 1. Set epochNanoseconds to ? ToBigInt(epochNanoseconds).
|
// 1. Set epochNanoseconds to ? ToBigInt(epochNanoseconds).
|
||||||
auto* epoch_nanoseconds = vm.argument(0).to_bigint(global_object);
|
auto* epoch_nanoseconds = TRY_OR_DISCARD(vm.argument(0).to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// 2. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
// 2. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
||||||
|
|
|
@ -49,9 +49,7 @@ Value ZonedDateTimeConstructor::construct(FunctionObject& new_target)
|
||||||
auto& global_object = this->global_object();
|
auto& global_object = this->global_object();
|
||||||
|
|
||||||
// 2. Set epochNanoseconds to ? ToBigInt(epochNanoseconds).
|
// 2. Set epochNanoseconds to ? ToBigInt(epochNanoseconds).
|
||||||
auto* epoch_nanoseconds = vm.argument(0).to_bigint(global_object);
|
auto* epoch_nanoseconds = TRY_OR_DISCARD(vm.argument(0).to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// 3. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
// 3. If ! IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
|
||||||
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
if (!is_valid_epoch_nanoseconds(*epoch_nanoseconds)) {
|
||||||
|
|
|
@ -142,9 +142,10 @@ inline void integer_indexed_element_set(TypedArrayBase& typed_array, Value prope
|
||||||
|
|
||||||
// 2. If O.[[ContentType]] is BigInt, let numValue be ? ToBigInt(value).
|
// 2. If O.[[ContentType]] is BigInt, let numValue be ? ToBigInt(value).
|
||||||
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
|
||||||
num_value = value.to_bigint(global_object);
|
auto num_value_or_error = value.to_bigint(global_object);
|
||||||
if (vm.exception())
|
if (num_value_or_error.is_error())
|
||||||
return;
|
return;
|
||||||
|
num_value = num_value_or_error.release_value();
|
||||||
}
|
}
|
||||||
// 3. Otherwise, let numValue be ? ToNumber(value).
|
// 3. Otherwise, let numValue be ? ToNumber(value).
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -249,9 +249,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::fill)
|
||||||
|
|
||||||
Value value;
|
Value value;
|
||||||
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt) {
|
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt) {
|
||||||
value = vm.argument(0).to_bigint(global_object);
|
value = TRY_OR_DISCARD(vm.argument(0).to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
} else {
|
} else {
|
||||||
value = vm.argument(0).to_number(global_object);
|
value = vm.argument(0).to_number(global_object);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
|
@ -827,7 +825,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set)
|
||||||
while (target_byte_index < limit) {
|
while (target_byte_index < limit) {
|
||||||
auto value = TRY_OR_DISCARD(src->get(k));
|
auto value = TRY_OR_DISCARD(src->get(k));
|
||||||
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt)
|
if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt)
|
||||||
value = value.to_bigint(global_object);
|
value = TRY_OR_DISCARD(value.to_bigint(global_object));
|
||||||
else
|
else
|
||||||
value = value.to_number(global_object);
|
value = value.to_number(global_object);
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
|
|
|
@ -514,17 +514,15 @@ Value Value::to_number(GlobalObject& global_object) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.1.13 ToBigInt ( argument ), https://tc39.es/ecma262/#sec-tobigint
|
// 7.1.13 ToBigInt ( argument ), https://tc39.es/ecma262/#sec-tobigint
|
||||||
BigInt* Value::to_bigint(GlobalObject& global_object) const
|
ThrowCompletionOr<BigInt*> Value::to_bigint(GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
auto& vm = global_object.vm();
|
auto& vm = global_object.vm();
|
||||||
auto primitive = TRY_OR_DISCARD(to_primitive(global_object, PreferredType::Number));
|
auto primitive = TRY(to_primitive(global_object, PreferredType::Number));
|
||||||
switch (primitive.type()) {
|
switch (primitive.type()) {
|
||||||
case Type::Undefined:
|
case Type::Undefined:
|
||||||
vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "undefined", "BigInt");
|
return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "undefined", "BigInt");
|
||||||
return nullptr;
|
|
||||||
case Type::Null:
|
case Type::Null:
|
||||||
vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "null", "BigInt");
|
return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "null", "BigInt");
|
||||||
return nullptr;
|
|
||||||
case Type::Boolean: {
|
case Type::Boolean: {
|
||||||
auto value = primitive.as_bool() ? 1 : 0;
|
auto value = primitive.as_bool() ? 1 : 0;
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger { value });
|
return js_bigint(vm, Crypto::SignedBigInteger { value });
|
||||||
|
@ -533,19 +531,15 @@ BigInt* Value::to_bigint(GlobalObject& global_object) const
|
||||||
return &primitive.as_bigint();
|
return &primitive.as_bigint();
|
||||||
case Type::Int32:
|
case Type::Int32:
|
||||||
case Type::Double:
|
case Type::Double:
|
||||||
vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "number", "BigInt");
|
return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "number", "BigInt");
|
||||||
return {};
|
|
||||||
case Type::String: {
|
case Type::String: {
|
||||||
auto& string = primitive.as_string().string();
|
auto& string = primitive.as_string().string();
|
||||||
if (!is_valid_bigint_value(string)) {
|
if (!is_valid_bigint_value(string))
|
||||||
vm.throw_exception<SyntaxError>(global_object, ErrorType::BigIntInvalidValue, string);
|
return vm.throw_completion<SyntaxError>(global_object, ErrorType::BigIntInvalidValue, string);
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return js_bigint(vm, Crypto::SignedBigInteger::from_base(10, string.trim_whitespace()));
|
return js_bigint(vm, Crypto::SignedBigInteger::from_base(10, string.trim_whitespace()));
|
||||||
}
|
}
|
||||||
case Type::Symbol:
|
case Type::Symbol:
|
||||||
vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "symbol", "BigInt");
|
return vm.throw_completion<TypeError>(global_object, ErrorType::Convert, "symbol", "BigInt");
|
||||||
return {};
|
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -554,18 +548,14 @@ BigInt* Value::to_bigint(GlobalObject& global_object) const
|
||||||
// 7.1.15 ToBigInt64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobigint64
|
// 7.1.15 ToBigInt64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobigint64
|
||||||
i64 Value::to_bigint_int64(GlobalObject& global_object) const
|
i64 Value::to_bigint_int64(GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
auto* bigint = to_bigint(global_object);
|
auto* bigint = TRY_OR_DISCARD(to_bigint(global_object));
|
||||||
if (global_object.vm().exception())
|
|
||||||
return {};
|
|
||||||
return static_cast<i64>(bigint->big_integer().to_u64());
|
return static_cast<i64>(bigint->big_integer().to_u64());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.1.16 ToBigUint64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobiguint64
|
// 7.1.16 ToBigUint64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobiguint64
|
||||||
u64 Value::to_bigint_uint64(GlobalObject& global_object) const
|
u64 Value::to_bigint_uint64(GlobalObject& global_object) const
|
||||||
{
|
{
|
||||||
auto* bigint = to_bigint(global_object);
|
auto* bigint = TRY_OR_DISCARD(to_bigint(global_object));
|
||||||
if (global_object.vm().exception())
|
|
||||||
return {};
|
|
||||||
return bigint->big_integer().to_u64();
|
return bigint->big_integer().to_u64();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ public:
|
||||||
ThrowCompletionOr<Object*> to_object(GlobalObject&) const;
|
ThrowCompletionOr<Object*> to_object(GlobalObject&) const;
|
||||||
ThrowCompletionOr<Value> to_numeric(GlobalObject&) const;
|
ThrowCompletionOr<Value> to_numeric(GlobalObject&) const;
|
||||||
Value to_number(GlobalObject&) const;
|
Value to_number(GlobalObject&) const;
|
||||||
BigInt* to_bigint(GlobalObject&) const;
|
ThrowCompletionOr<BigInt*> to_bigint(GlobalObject&) const;
|
||||||
i64 to_bigint_int64(GlobalObject&) const;
|
i64 to_bigint_int64(GlobalObject&) const;
|
||||||
u64 to_bigint_uint64(GlobalObject&) const;
|
u64 to_bigint_uint64(GlobalObject&) const;
|
||||||
double to_double(GlobalObject&) const;
|
double to_double(GlobalObject&) const;
|
||||||
|
|
|
@ -388,9 +388,7 @@ Optional<Wasm::Value> to_webassembly_value(JS::Value value, const Wasm::ValueTyp
|
||||||
|
|
||||||
switch (type.kind()) {
|
switch (type.kind()) {
|
||||||
case Wasm::ValueType::I64: {
|
case Wasm::ValueType::I64: {
|
||||||
auto bigint = value.to_bigint(global_object);
|
auto bigint = TRY_OR_DISCARD(value.to_bigint(global_object));
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
auto value = bigint->big_integer().divided_by(two_64).remainder;
|
auto value = bigint->big_integer().divided_by(two_64).remainder;
|
||||||
VERIFY(value.unsigned_value().trimmed_length() <= 2);
|
VERIFY(value.unsigned_value().trimmed_length() <= 2);
|
||||||
i64 integer = static_cast<i64>(value.unsigned_value().to_u64());
|
i64 integer = static_cast<i64>(value.unsigned_value().to_u64());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue