mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
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:
parent
9be0b664e3
commit
f369229770
Notes:
sideshowbarker
2024-07-18 23:57:11 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/f3692297702 Pull-request: https://github.com/SerenityOS/serenity/pull/4892
6 changed files with 47 additions and 83 deletions
|
@ -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 {};
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue