mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibJS: Add a bunch of numeric conversions to Value
Namely: - BigInt64 - BigUint64 - i16 - u16 - i8 - u8 - Clamped u8 These will be used in ArrayBuffer::numeric_to_raw_bytes later.
This commit is contained in:
parent
93996eb48e
commit
7ff144d533
2 changed files with 120 additions and 0 deletions
|
@ -548,6 +548,24 @@ BigInt* Value::to_bigint(GlobalObject& global_object) const
|
|||
}
|
||||
}
|
||||
|
||||
// 7.1.15 ToBigInt64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobigint64
|
||||
i64 Value::to_bigint_int64(GlobalObject& global_object) const
|
||||
{
|
||||
auto* bigint = to_bigint(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
return static_cast<i64>(bigint->big_integer().to_u64());
|
||||
}
|
||||
|
||||
// 7.1.16 ToBigUint64 ( argument ), https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tobiguint64
|
||||
u64 Value::to_bigint_uint64(GlobalObject& global_object) const
|
||||
{
|
||||
auto* bigint = to_bigint(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
return bigint->big_integer().to_u64();
|
||||
}
|
||||
|
||||
// FIXME: These two conversions are wrong for JS, and seem likely to be footguns
|
||||
i32 Value::as_i32() const
|
||||
{
|
||||
|
@ -615,6 +633,101 @@ u32 Value::to_u32(GlobalObject& global_object) const
|
|||
return static_cast<u32>(int32bit);
|
||||
}
|
||||
|
||||
// 7.1.8 ToInt16 ( argument ), https://tc39.es/ecma262/#sec-toint16
|
||||
i16 Value::to_i16(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
double value = number.as_double();
|
||||
if (!isfinite(value) || value == 0)
|
||||
return 0;
|
||||
auto abs = fabs(value);
|
||||
auto int_val = floor(abs);
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto remainder = fmod(int_val, 65536.0);
|
||||
auto int16bit = remainder >= 0.0 ? remainder : remainder + 65536.0; // The notation “x modulo y” computes a value k of the same sign as y
|
||||
if (int16bit >= 32768.0)
|
||||
int16bit -= 65536.0;
|
||||
return static_cast<i16>(int16bit);
|
||||
}
|
||||
|
||||
// 7.1.9 ToUint16 ( argument ), https://tc39.es/ecma262/#sec-touint16
|
||||
u16 Value::to_u16(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
double value = number.as_double();
|
||||
if (!isfinite(value) || value == 0)
|
||||
return 0;
|
||||
auto int_val = floor(fabs(value));
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto int16bit = fmod(int_val, NumericLimits<u16>::max() + 1.0);
|
||||
return static_cast<u16>(int16bit);
|
||||
}
|
||||
|
||||
// 7.1.10 ToInt8 ( argument ), https://tc39.es/ecma262/#sec-toint8
|
||||
i8 Value::to_i8(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
double value = number.as_double();
|
||||
if (!isfinite(value) || value == 0)
|
||||
return 0;
|
||||
auto abs = fabs(value);
|
||||
auto int_val = floor(abs);
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto remainder = fmod(int_val, 256.0);
|
||||
auto int8bit = remainder >= 0.0 ? remainder : remainder + 256.0; // The notation “x modulo y” computes a value k of the same sign as y
|
||||
if (int8bit >= 128.0)
|
||||
int8bit -= 256.0;
|
||||
return static_cast<i8>(int8bit);
|
||||
}
|
||||
|
||||
// 7.1.11 ToUint8 ( argument ), https://tc39.es/ecma262/#sec-touint8
|
||||
u8 Value::to_u8(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
double value = number.as_double();
|
||||
if (!isfinite(value) || value == 0)
|
||||
return 0;
|
||||
auto int_val = floor(fabs(value));
|
||||
if (signbit(value))
|
||||
int_val = -int_val;
|
||||
auto int8bit = fmod(int_val, NumericLimits<u8>::max() + 1.0);
|
||||
return static_cast<u8>(int8bit);
|
||||
}
|
||||
|
||||
// 7.1.12 ToUint8Clamp ( argument ), https://tc39.es/ecma262/#sec-touint8clamp
|
||||
u8 Value::to_u8_clamp(GlobalObject& global_object) const
|
||||
{
|
||||
auto number = to_number(global_object);
|
||||
if (global_object.vm().exception())
|
||||
return INVALID;
|
||||
if (number.is_nan())
|
||||
return 0;
|
||||
double value = number.as_double();
|
||||
if (value <= 0.0)
|
||||
return 0;
|
||||
if (value >= 255.0)
|
||||
return 255;
|
||||
auto int_val = floor(value);
|
||||
if (int_val + 0.5 < value)
|
||||
return static_cast<u8>(int_val + 1.0);
|
||||
if (value < int_val + 0.5)
|
||||
return static_cast<u8>(int_val);
|
||||
if (fmod(int_val, 2.0) == 1.0)
|
||||
return static_cast<u8>(int_val + 1.0);
|
||||
return static_cast<u8>(int_val);
|
||||
}
|
||||
|
||||
// 7.1.20 ToLength ( argument ), https://tc39.es/ecma262/#sec-tolength
|
||||
size_t Value::to_length(GlobalObject& global_object) const
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue