1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:47:46 +00:00

LibJS: Convert array_merge_sort to ThrowCompletionOr

This commit is contained in:
Idan Horowitz 2021-10-23 02:07:10 +03:00
parent ad318ec123
commit 953265805e

View file

@ -882,12 +882,12 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayPrototype::reverse)
return this_object; return this_object;
} }
static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject* compare_func, MarkedValueList& arr_to_sort) static ThrowCompletionOr<void> array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject* compare_func, MarkedValueList& arr_to_sort)
{ {
// FIXME: it would probably be better to switch to insertion sort for small arrays for // FIXME: it would probably be better to switch to insertion sort for small arrays for
// better performance // better performance
if (arr_to_sort.size() <= 1) if (arr_to_sort.size() <= 1)
return; return {};
MarkedValueList left(vm.heap()); MarkedValueList left(vm.heap());
MarkedValueList right(vm.heap()); MarkedValueList right(vm.heap());
@ -903,12 +903,8 @@ static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject
} }
} }
array_merge_sort(vm, global_object, compare_func, left); TRY(array_merge_sort(vm, global_object, compare_func, left));
if (vm.exception()) TRY(array_merge_sort(vm, global_object, compare_func, right));
return;
array_merge_sort(vm, global_object, compare_func, right);
if (vm.exception())
return;
arr_to_sort.clear(); arr_to_sort.clear();
@ -927,16 +923,8 @@ static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject
} else if (y.is_undefined()) { } else if (y.is_undefined()) {
comparison_result = -1; comparison_result = -1;
} else if (compare_func) { } else if (compare_func) {
auto call_result_or_error = vm.call(*compare_func, js_undefined(), left[left_index], right[right_index]); auto call_result = TRY(vm.call(*compare_func, js_undefined(), left[left_index], right[right_index]));
if (call_result_or_error.is_error()) auto number = TRY(call_result.to_number(global_object));
return;
auto call_result = call_result_or_error.release_value();
auto number_or_error = call_result.to_number(global_object);
if (number_or_error.is_error())
return;
auto number = number_or_error.release_value();
if (number.is_nan()) if (number.is_nan())
comparison_result = 0; comparison_result = 0;
else else
@ -946,15 +934,9 @@ static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject
// the Abstract Relational Comparison in line once iterating over code points, rather // the Abstract Relational Comparison in line once iterating over code points, rather
// than calling it twice after creating two primitive strings. // than calling it twice after creating two primitive strings.
auto x_string_or_error = x.to_primitive_string(global_object); auto x_string = TRY(x.to_primitive_string(global_object));
if (x_string_or_error.is_error())
return;
auto x_string = x_string_or_error.release_value();
auto y_string_or_error = y.to_primitive_string(global_object); auto y_string = TRY(y.to_primitive_string(global_object));
if (y_string_or_error.is_error())
return;
auto y_string = y_string_or_error.release_value();
auto x_string_value = Value(x_string); auto x_string_value = Value(x_string);
auto y_string_value = Value(y_string); auto y_string_value = Value(y_string);
@ -993,6 +975,8 @@ static void array_merge_sort(VM& vm, GlobalObject& global_object, FunctionObject
arr_to_sort.append(right[right_index]); arr_to_sort.append(right[right_index]);
right_index++; right_index++;
} }
return {};
} }
// 23.1.3.27 Array.prototype.sort ( comparefn ), https://tc39.es/ecma262/#sec-array.prototype.sort // 23.1.3.27 Array.prototype.sort ( comparefn ), https://tc39.es/ecma262/#sec-array.prototype.sort
@ -1023,9 +1007,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayPrototype::sort)
// to be stable. FIXME: when initially scanning through the array, maintain a flag // to be stable. FIXME: when initially scanning through the array, maintain a flag
// for if an unstable sort would be indistinguishable from a stable sort (such as just // for if an unstable sort would be indistinguishable from a stable sort (such as just
// just strings or numbers), and in that case use quick sort instead for better performance. // just strings or numbers), and in that case use quick sort instead for better performance.
array_merge_sort(vm, global_object, callback.is_undefined() ? nullptr : &callback.as_function(), items); TRY_OR_DISCARD(array_merge_sort(vm, global_object, callback.is_undefined() ? nullptr : &callback.as_function(), items));
if (vm.exception())
return {};
for (size_t j = 0; j < items.size(); ++j) for (size_t j = 0; j < items.size(); ++j)
TRY_OR_DISCARD(object->set(j, items[j], Object::ShouldThrowExceptions::Yes)); TRY_OR_DISCARD(object->set(j, items[j], Object::ShouldThrowExceptions::Yes));