1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 22:37:35 +00:00

LibJS: Bring String.prototype.split closer to the specification

Specifically, add a couple of missing exception checks and use the
CreateDataPropertyOrThrow abstract operation.
This commit is contained in:
Idan Horowitz 2021-07-06 00:05:44 +03:00 committed by Linus Groh
parent 28172fde10
commit 6da7f43580

View file

@ -576,25 +576,27 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
// 22.1.3.21 String.prototype.split ( separator, limit ), https://tc39.es/ecma262/#sec-string.prototype.split // 22.1.3.21 String.prototype.split ( separator, limit ), https://tc39.es/ecma262/#sec-string.prototype.split
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
{ {
auto separator_argument = vm.argument(0); auto object = require_object_coercible(global_object, vm.this_value(global_object));
auto limit_argument = vm.argument(1);
auto this_value = require_object_coercible(global_object, vm.this_value(global_object));
if (vm.exception()) if (vm.exception())
return {}; return {};
auto separator_argument = vm.argument(0);
auto limit_argument = vm.argument(1);
if (!separator_argument.is_nullish()) { if (!separator_argument.is_nullish()) {
auto splitter = separator_argument.get_method(global_object, *vm.well_known_symbol_split()); auto splitter = separator_argument.get_method(global_object, *vm.well_known_symbol_split());
if (vm.exception()) if (vm.exception())
return {}; return {};
if (splitter) if (splitter)
return vm.call(*splitter, separator_argument, this_value, limit_argument); return vm.call(*splitter, separator_argument, object, limit_argument);
} }
auto string = this_value.to_string(global_object); auto string = object.to_string(global_object);
if (vm.exception())
return {};
auto* result = Array::create(global_object, 0); auto* array = Array::create(global_object, 0);
size_t result_len = 0; size_t array_length = 0;
auto limit = NumericLimits<u32>::max(); auto limit = NumericLimits<u32>::max();
if (!limit_argument.is_undefined()) { if (!limit_argument.is_undefined()) {
@ -608,49 +610,41 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
return {}; return {};
if (limit == 0) if (limit == 0)
return result; return array;
if (separator_argument.is_undefined()) { if (separator_argument.is_undefined()) {
result->create_data_property_or_throw(0, js_string(vm, string)); array->create_data_property_or_throw(0, js_string(vm, string));
return result; return array;
} }
auto len = string.length(); if (string.length() == 0) {
auto separator_len = separator.length(); if (!separator.is_empty())
if (len == 0) { array->create_data_property_or_throw(0, js_string(vm, string));
if (separator_len > 0) return array;
result->create_data_property_or_throw(0, js_string(vm, string));
return result;
} }
size_t start = 0; size_t start = 0;
auto pos = start; auto position = start;
if (separator_len == 0) { while (position != string.length()) {
for (pos = 0; pos < len; pos++) auto match = split_match(string, position, separator);
result->define_property(pos, js_string(vm, string.substring(pos, 1))); if (!match.has_value() || match.value() == start) {
return result; ++position;
}
while (pos != len) {
auto e = split_match(string, pos, separator);
if (!e.has_value()) {
pos += 1;
continue; continue;
} }
auto segment = string.substring_view(start, pos - start); auto segment = string.substring_view(start, position - start);
result->create_data_property_or_throw(result_len, js_string(vm, segment)); array->create_data_property_or_throw(array_length, js_string(vm, segment));
result_len++; ++array_length;
if (result_len == limit) if (array_length == limit)
return result; return array;
start = e.value(); start = match.value();
pos = start; position = start;
} }
auto rest = string.substring(start, len - start); auto rest = string.substring(start);
result->create_data_property_or_throw(result_len, js_string(vm, rest)); array->create_data_property_or_throw(array_length, js_string(vm, rest));
return result; return array;
} }
// 22.1.3.9 String.prototype.lastIndexOf ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.lastindexof // 22.1.3.9 String.prototype.lastIndexOf ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.lastindexof