LibJS: Replace all uses of to_size_t() and remove it :^)

Yay for more spec compliance! This is pretty easy as everything using
to_size_t() should just be using one of the other abstract operations we
already have implemented.
This allows us to get rid of get_length() in ArrayPrototype, which is
basically a slightly incorrect implementation of length_of_array_like(),
and then finally remove to_size_t()!
Also fixes a couple of "argument is undefined" vs "argument isn't given"
issues along the way.
This commit is contained in:
Linus Groh 2021-01-10 21:13:58 +01:00 committed by Andreas Kling
parent 9be0b664e3
commit f369229770
Notes: sideshowbarker 2024-07-18 23:57:11 +09:00
6 changed files with 47 additions and 83 deletions

View file

@ -107,21 +107,13 @@ static Function* callback_from_args(GlobalObject& global_object, const String& n
return &callback.as_function();
}
static size_t get_length(VM& vm, Object& object)
{
auto length_property = object.get(vm.names.length);
if (vm.exception())
return 0;
return length_property.to_size_t(object.global_object());
}
static void for_each_item(VM& vm, GlobalObject& global_object, const String& name, AK::Function<IterationDecision(size_t index, Value value, Value callback_result)> callback, bool skip_empty = true)
{
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return;
auto initial_length = get_length(vm, *this_object);
auto initial_length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return;
@ -174,7 +166,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::map)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
auto initial_length = get_length(vm, *this_object);
auto initial_length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
auto* new_array = Array::create(global_object);
@ -199,7 +191,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
array->indexed_properties().append(vm.argument(i));
return Value(static_cast<i32>(array->indexed_properties().array_like_size()));
}
auto length = get_length(vm, *this_object);
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
auto argument_count = vm.argument_count();
@ -241,7 +233,9 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
return js_undefined();
return array->indexed_properties().take_last(array).value.value_or(js_undefined());
}
auto length = get_length(vm, *this_object);
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
if (length == 0) {
this_object->put(vm.names.length, Value(0));
return js_undefined();
@ -298,7 +292,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string)
s_array_join_seen_objects.remove(this_object);
};
auto length = get_length(vm, *this_object);
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
@ -342,7 +336,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join)
s_array_join_seen_objects.remove(this_object);
};
auto length = get_length(vm, *this_object);
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
String separator = ",";
@ -445,7 +439,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::index_of)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
i32 length = get_length(vm, *this_object);
i32 length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
if (length == 0)
@ -477,7 +471,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
if (!this_object)
return {};
auto initial_length = get_length(vm, *this_object);
auto initial_length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
@ -530,7 +524,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
if (!this_object)
return {};
auto initial_length = get_length(vm, *this_object);
auto initial_length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
@ -720,7 +714,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::sort)
return {};
}
auto original_length = get_length(vm, *array);
auto original_length = length_of_array_like(global_object, *array);
if (vm.exception())
return {};
@ -767,7 +761,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::last_index_of)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
i32 length = get_length(vm, *this_object);
i32 length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
if (length == 0)
@ -798,7 +792,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::includes)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
i32 length = get_length(vm, *this_object);
i32 length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
if (length == 0)
@ -886,7 +880,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
if (!this_object)
return {};
auto initial_length = get_length(vm, *this_object);
auto initial_length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
@ -991,7 +985,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::fill)
if (!this_object)
return {};
ssize_t length = get_length(vm, *this_object);
ssize_t length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};

View file

@ -80,10 +80,7 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
vm.throw_exception<TypeError>(global_object, ErrorType::FunctionArgsNotObject);
return {};
}
auto length_property = arg_array.as_object().get(vm.names.length);
if (vm.exception())
return {};
auto length = length_property.to_size_t(global_object);
auto length = length_of_array_like(global_object, arg_array.as_object());
if (vm.exception())
return {};
MarkedValueList arguments(vm.heap());

View file

@ -63,10 +63,7 @@ static void prepare_arguments_list(GlobalObject& global_object, Value value, Mar
return;
}
auto& arguments_list = value.as_object();
auto length_property = arguments_list.get(vm.names.length);
if (vm.exception())
return;
auto length = length_property.to_size_t(global_object);
auto length = length_of_array_like(global_object, arguments_list);
if (vm.exception())
return;
for (size_t i = 0; i < length; ++i) {

View file

@ -152,20 +152,17 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
return {};
if (!vm.argument_count())
return js_string(vm, String::empty());
auto count_value = vm.argument(0).to_number(global_object);
auto count = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
if (count_value.as_double() < 0) {
if (count < 0) {
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
return {};
}
if (count_value.is_infinity()) {
if (Value(count).is_infinity()) {
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
return {};
}
auto count = count_value.to_size_t(global_object);
if (vm.exception())
return {};
StringBuilder builder;
for (size_t i = 0; i < count; ++i)
builder.append(string);
@ -185,12 +182,11 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
auto string_length = string.length();
auto search_string_length = search_string.length();
size_t start = 0;
if (vm.argument_count() > 1) {
auto number = vm.argument(1).to_number(global_object);
if (!vm.argument(1).is_undefined()) {
auto position = vm.argument(1).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
if (!number.is_nan())
start = min(number.to_size_t(global_object), string_length);
start = clamp(position, static_cast<double>(0), static_cast<double>(string_length));
}
if (start + search_string_length > string_length)
return Value(false);
@ -226,10 +222,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
auto end_position_value = vm.argument(1);
if (!end_position_value.is_undefined()) {
auto number = end_position_value.to_number(global_object);
if (vm.exception())
return {};
double pos_as_double = number.to_integer_or_infinity(global_object);
double pos_as_double = end_position_value.to_integer_or_infinity(global_object);
if (vm.exception())
return {};
pos = clamp(pos_as_double, static_cast<double>(0), static_cast<double>(string_length));
@ -295,7 +288,7 @@ enum class PadPlacement {
static Value pad_string(GlobalObject& global_object, const String& string, PadPlacement placement)
{
auto& vm = global_object.vm();
auto max_length = vm.argument(0).to_size_t(global_object);
auto max_length = vm.argument(0).to_length(global_object);
if (vm.exception())
return {};
if (max_length <= string.length())
@ -389,15 +382,17 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
// FIXME: index_start and index_end should index a UTF-16 code_point view of the string.
auto string_length = string.length();
auto index_start = min(vm.argument(0).to_size_t(global_object), string_length);
auto start = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
auto index_end = string_length;
if (vm.argument_count() >= 2) {
index_end = min(vm.argument(1).to_size_t(global_object), string_length);
auto end = (double)string_length;
if (!vm.argument(1).is_undefined()) {
end = vm.argument(1).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
}
size_t index_start = clamp(start, static_cast<double>(0), static_cast<double>(string_length));
size_t index_end = clamp(end, static_cast<double>(0), static_cast<double>(string_length));
if (index_start == index_end)
return js_string(vm, String(""));
@ -457,22 +452,19 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
auto search_string = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
// FIXME: position should index a UTF-16 code_point view of the string.
size_t position = 0;
if (vm.argument_count() >= 2) {
position = vm.argument(1).to_size_t(global_object);
auto string_length = string.length();
// FIXME: start should index a UTF-16 code_point view of the string.
size_t start = 0;
if (!vm.argument(1).is_undefined()) {
auto position = vm.argument(1).to_integer_or_infinity(global_object);
if (vm.exception())
return {};
if (position >= string.length())
return Value(false);
start = clamp(position, static_cast<double>(0), static_cast<double>(string_length));
}
if (position == 0)
if (start == 0)
return Value(string.contains(search_string));
auto substring_length = string.length() - position;
auto substring_search = string.substring(position, substring_length);
auto substring_length = string_length - start;
auto substring_search = string.substring(start, substring_length);
return Value(substring_search.contains(search_string));
}
@ -593,22 +585,22 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
auto string = ak_string_from(vm, global_object);
if (string.is_null())
return {};
if (vm.argument_count() == 0)
return Value(-1);
auto search_string = vm.argument(0).to_string(global_object);
if (vm.exception())
return {};
auto position = vm.argument(1).to_number(global_object);
if (vm.exception())
return {};
if (search_string.length() > string.length())
return Value(-1);
auto max_index = string.length() - search_string.length();
auto from_index = max_index;
if (vm.argument_count() >= 2) {
if (!position.is_nan()) {
// FIXME: from_index should index a UTF-16 code_point view of the string.
from_index = min(vm.argument(1).to_size_t(global_object), max_index);
auto p = position.to_integer_or_infinity(global_object);
if (vm.exception())
return {};
from_index = clamp(p, static_cast<double>(0), static_cast<double>(max_index));
}
for (i32 i = from_index; i >= 0; --i) {

View file

@ -513,21 +513,6 @@ u32 Value::to_u32(GlobalObject& global_object) const
return number.as_u32();
}
size_t Value::to_size_t(GlobalObject& global_object) const
{
// FIXME: Replace uses of this function with to_length/to_index for correct behaviour and remove this eventually.
if (is_empty())
return 0;
auto number = to_number(global_object);
if (global_object.vm().exception())
return INVALID;
if (number.is_nan())
return 0;
if (number.as_double() <= 0)
return 0;
return number.as_size_t();
}
size_t Value::to_length(GlobalObject& global_object) const
{
// 7.1.20 ToLength, https://tc39.es/ecma262/#sec-tolength

View file

@ -256,7 +256,6 @@ public:
double to_double(GlobalObject&) const;
i32 to_i32(GlobalObject&) const;
u32 to_u32(GlobalObject&) const;
size_t to_size_t(GlobalObject&) const;
size_t to_length(GlobalObject&) const;
size_t to_index(GlobalObject&) const;
double to_integer_or_infinity(GlobalObject&) const;