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

LibJS: Convert StringPrototype functions to ThrowCompletionOr

This commit is contained in:
Idan Horowitz 2021-10-23 03:09:34 +03:00 committed by Andreas Kling
parent 38c4693c70
commit 18c2d537c7
2 changed files with 297 additions and 364 deletions

View file

@ -29,16 +29,16 @@
namespace JS {
static Optional<String> ak_string_from(VM& vm, GlobalObject& global_object)
static ThrowCompletionOr<String> ak_string_from(VM& vm, GlobalObject& global_object)
{
auto this_value = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
return TRY_OR_DISCARD(this_value.to_string(global_object));
auto this_value = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
return TRY(this_value.to_string(global_object));
}
static Utf16String utf16_string_from(VM& vm, GlobalObject& global_object)
static ThrowCompletionOr<Utf16String> utf16_string_from(VM& vm, GlobalObject& global_object)
{
auto this_value = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
return TRY_OR_DISCARD(this_value.to_utf16_string(global_object));
auto this_value = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
return TRY(this_value.to_utf16_string(global_object));
}
// 22.1.3.21.1 SplitMatch ( S, q, R ), https://tc39.es/ecma262/#sec-splitmatch
@ -110,54 +110,54 @@ void StringPrototype::initialize(GlobalObject& global_object)
StringObject::initialize(global_object);
u8 attr = Attribute::Writable | Attribute::Configurable;
define_old_native_function(vm.names.charAt, char_at, 1, attr);
define_old_native_function(vm.names.charCodeAt, char_code_at, 1, attr);
define_old_native_function(vm.names.codePointAt, code_point_at, 1, attr);
define_old_native_function(vm.names.repeat, repeat, 1, attr);
define_old_native_function(vm.names.startsWith, starts_with, 1, attr);
define_old_native_function(vm.names.endsWith, ends_with, 1, attr);
define_old_native_function(vm.names.indexOf, index_of, 1, attr);
define_old_native_function(vm.names.toLocaleLowerCase, to_locale_lowercase, 0, attr);
define_old_native_function(vm.names.toLocaleUpperCase, to_locale_uppercase, 0, attr);
define_old_native_function(vm.names.toLowerCase, to_lowercase, 0, attr);
define_old_native_function(vm.names.toUpperCase, to_uppercase, 0, attr);
define_old_native_function(vm.names.toString, to_string, 0, attr);
define_old_native_function(vm.names.valueOf, value_of, 0, attr);
define_old_native_function(vm.names.padStart, pad_start, 1, attr);
define_old_native_function(vm.names.padEnd, pad_end, 1, attr);
define_old_native_function(vm.names.trim, trim, 0, attr);
define_old_native_function(vm.names.trimStart, trim_start, 0, attr);
define_native_function(vm.names.charAt, char_at, 1, attr);
define_native_function(vm.names.charCodeAt, char_code_at, 1, attr);
define_native_function(vm.names.codePointAt, code_point_at, 1, attr);
define_native_function(vm.names.repeat, repeat, 1, attr);
define_native_function(vm.names.startsWith, starts_with, 1, attr);
define_native_function(vm.names.endsWith, ends_with, 1, attr);
define_native_function(vm.names.indexOf, index_of, 1, attr);
define_native_function(vm.names.toLocaleLowerCase, to_locale_lowercase, 0, attr);
define_native_function(vm.names.toLocaleUpperCase, to_locale_uppercase, 0, attr);
define_native_function(vm.names.toLowerCase, to_lowercase, 0, attr);
define_native_function(vm.names.toUpperCase, to_uppercase, 0, attr);
define_native_function(vm.names.toString, to_string, 0, attr);
define_native_function(vm.names.valueOf, value_of, 0, attr);
define_native_function(vm.names.padStart, pad_start, 1, attr);
define_native_function(vm.names.padEnd, pad_end, 1, attr);
define_native_function(vm.names.trim, trim, 0, attr);
define_native_function(vm.names.trimStart, trim_start, 0, attr);
define_direct_property(vm.names.trimLeft, get_without_side_effects(vm.names.trimStart), attr);
define_old_native_function(vm.names.trimEnd, trim_end, 0, attr);
define_native_function(vm.names.trimEnd, trim_end, 0, attr);
define_direct_property(vm.names.trimRight, get_without_side_effects(vm.names.trimEnd), attr);
define_old_native_function(vm.names.concat, concat, 1, attr);
define_old_native_function(vm.names.substr, substr, 2, attr);
define_old_native_function(vm.names.substring, substring, 2, attr);
define_old_native_function(vm.names.includes, includes, 1, attr);
define_old_native_function(vm.names.slice, slice, 2, attr);
define_old_native_function(vm.names.split, split, 2, attr);
define_old_native_function(vm.names.lastIndexOf, last_index_of, 1, attr);
define_old_native_function(vm.names.at, at, 1, attr);
define_old_native_function(vm.names.match, match, 1, attr);
define_old_native_function(vm.names.matchAll, match_all, 1, attr);
define_old_native_function(vm.names.replace, replace, 2, attr);
define_old_native_function(vm.names.replaceAll, replace_all, 2, attr);
define_old_native_function(vm.names.search, search, 1, attr);
define_old_native_function(vm.names.anchor, anchor, 1, attr);
define_old_native_function(vm.names.big, big, 0, attr);
define_old_native_function(vm.names.blink, blink, 0, attr);
define_old_native_function(vm.names.bold, bold, 0, attr);
define_old_native_function(vm.names.fixed, fixed, 0, attr);
define_old_native_function(vm.names.fontcolor, fontcolor, 1, attr);
define_old_native_function(vm.names.fontsize, fontsize, 1, attr);
define_old_native_function(vm.names.italics, italics, 0, attr);
define_old_native_function(vm.names.link, link, 1, attr);
define_old_native_function(vm.names.small, small, 0, attr);
define_old_native_function(vm.names.strike, strike, 0, attr);
define_old_native_function(vm.names.sub, sub, 0, attr);
define_old_native_function(vm.names.sup, sup, 0, attr);
define_old_native_function(vm.names.localeCompare, locale_compare, 1, attr);
define_old_native_function(*vm.well_known_symbol_iterator(), symbol_iterator, 0, attr);
define_native_function(vm.names.concat, concat, 1, attr);
define_native_function(vm.names.substr, substr, 2, attr);
define_native_function(vm.names.substring, substring, 2, attr);
define_native_function(vm.names.includes, includes, 1, attr);
define_native_function(vm.names.slice, slice, 2, attr);
define_native_function(vm.names.split, split, 2, attr);
define_native_function(vm.names.lastIndexOf, last_index_of, 1, attr);
define_native_function(vm.names.at, at, 1, attr);
define_native_function(vm.names.match, match, 1, attr);
define_native_function(vm.names.matchAll, match_all, 1, attr);
define_native_function(vm.names.replace, replace, 2, attr);
define_native_function(vm.names.replaceAll, replace_all, 2, attr);
define_native_function(vm.names.search, search, 1, attr);
define_native_function(vm.names.anchor, anchor, 1, attr);
define_native_function(vm.names.big, big, 0, attr);
define_native_function(vm.names.blink, blink, 0, attr);
define_native_function(vm.names.bold, bold, 0, attr);
define_native_function(vm.names.fixed, fixed, 0, attr);
define_native_function(vm.names.fontcolor, fontcolor, 1, attr);
define_native_function(vm.names.fontsize, fontsize, 1, attr);
define_native_function(vm.names.italics, italics, 0, attr);
define_native_function(vm.names.link, link, 1, attr);
define_native_function(vm.names.small, small, 0, attr);
define_native_function(vm.names.strike, strike, 0, attr);
define_native_function(vm.names.sub, sub, 0, attr);
define_native_function(vm.names.sup, sup, 0, attr);
define_native_function(vm.names.localeCompare, locale_compare, 1, attr);
define_native_function(*vm.well_known_symbol_iterator(), symbol_iterator, 0, attr);
}
StringPrototype::~StringPrototype()
@ -176,12 +176,10 @@ static ThrowCompletionOr<PrimitiveString*> this_string_value(GlobalObject& globa
}
// 22.1.3.2 String.prototype.charAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charat
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::char_at)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto position = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto string = TRY(utf16_string_from(vm, global_object));
auto position = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (position < 0 || position >= string.length_in_code_units())
return js_string(vm, String::empty());
@ -189,12 +187,10 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::char_at)
}
// 22.1.3.3 String.prototype.charCodeAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charcodeat
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::char_code_at)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto position = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto string = TRY(utf16_string_from(vm, global_object));
auto position = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (position < 0 || position >= string.length_in_code_units())
return js_nan();
@ -202,12 +198,10 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::char_code_at)
}
// 22.1.3.4 String.prototype.codePointAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.codepointat
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::code_point_at)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::code_point_at)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto position = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto string = TRY(utf16_string_from(vm, global_object));
auto position = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (position < 0 || position >= string.length_in_code_units())
return js_undefined();
@ -216,59 +210,49 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::code_point_at)
}
// 22.1.3.17 String.prototype.repeat ( count ), https://tc39.es/ecma262/#sec-string.prototype.repeat
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::repeat)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto string = TRY(ak_string_from(vm, global_object));
auto n = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto n = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (n < 0) {
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
return {};
}
if (n < 0)
return vm.throw_completion<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "positive");
if (Value(n).is_positive_infinity()) {
vm.throw_exception<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
return {};
}
if (Value(n).is_positive_infinity())
return vm.throw_completion<RangeError>(global_object, ErrorType::StringRepeatCountMustBe, "finite");
if (n == 0)
return js_string(vm, String::empty());
// NOTE: This is an optimization, it is not required by the specification but it produces equivalent behavior
if (string->is_empty())
if (string.is_empty())
return js_string(vm, String::empty());
StringBuilder builder;
for (size_t i = 0; i < n; ++i)
builder.append(*string);
builder.append(string);
return js_string(vm, builder.to_string());
}
// 22.1.3.23 String.prototype.startsWith ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.startswith
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::starts_with)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::starts_with)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto search_string_value = vm.argument(0);
bool search_is_regexp = TRY_OR_DISCARD(search_string_value.is_regexp(global_object));
if (search_is_regexp) {
vm.throw_exception<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
return {};
}
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
if (search_is_regexp)
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
auto search_string = TRY_OR_DISCARD(search_string_value.to_utf16_string(global_object));
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
auto string_length = string.length_in_code_units();
auto search_length = search_string.length_in_code_units();
size_t start = 0;
if (!vm.argument(1).is_undefined()) {
auto position = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
auto position = TRY(vm.argument(1).to_integer_or_infinity(global_object));
start = clamp(position, static_cast<double>(0), static_cast<double>(string_length));
}
@ -284,27 +268,23 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::starts_with)
}
// 22.1.3.7 String.prototype.endsWith ( searchString [ , endPosition ] ), https://tc39.es/ecma262/#sec-string.prototype.endswith
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::ends_with)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::ends_with)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto search_string_value = vm.argument(0);
bool search_is_regexp = TRY_OR_DISCARD(search_string_value.is_regexp(global_object));
if (search_is_regexp) {
vm.throw_exception<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
return {};
}
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
if (search_is_regexp)
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
auto search_string = TRY_OR_DISCARD(search_string_value.to_utf16_string(global_object));
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
auto string_length = string.length_in_code_units();
auto search_length = search_string.length_in_code_units();
size_t end = string_length;
if (!vm.argument(1).is_undefined()) {
auto position = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
auto position = TRY(vm.argument(1).to_integer_or_infinity(global_object));
end = clamp(position, static_cast<double>(0), static_cast<double>(string_length));
}
@ -320,19 +300,17 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::ends_with)
}
// 22.1.3.9 String.prototype.indexOf ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.indexof
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::index_of)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::index_of)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto search_string = TRY_OR_DISCARD(vm.argument(0).to_utf16_string(global_object));
auto search_string = TRY(vm.argument(0).to_utf16_string(global_object));
auto utf16_string_view = string.view();
auto utf16_search_view = search_string.view();
size_t start = 0;
if (vm.argument_count() > 1) {
auto position = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
auto position = TRY(vm.argument(1).to_integer_or_infinity(global_object));
start = clamp(position, static_cast<double>(0), static_cast<double>(utf16_string_view.length_in_code_units()));
}
@ -377,63 +355,49 @@ static ThrowCompletionOr<String> resolve_best_locale(GlobalObject& global_object
}
// 18.1.2 String.prototype.toLocaleLowerCase ( [ locales ] ), https://tc39.es/ecma402/#sup-string.prototype.tolocalelowercase
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::to_locale_lowercase)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_locale_lowercase)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto locale = TRY_OR_DISCARD(resolve_best_locale(global_object, vm.argument(0)));
auto lowercase = Unicode::to_unicode_lowercase_full(*string, locale);
auto string = TRY(ak_string_from(vm, global_object));
auto locale = TRY(resolve_best_locale(global_object, vm.argument(0)));
auto lowercase = Unicode::to_unicode_lowercase_full(string, locale);
return js_string(vm, move(lowercase));
}
// 18.1.3 String.prototype.toLocaleUpperCase ( [ locales ] ), https://tc39.es/ecma402/#sup-string.prototype.tolocaleuppercase
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::to_locale_uppercase)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_locale_uppercase)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto locale = TRY_OR_DISCARD(resolve_best_locale(global_object, vm.argument(0)));
auto uppercase = Unicode::to_unicode_uppercase_full(*string, locale);
auto string = TRY(ak_string_from(vm, global_object));
auto locale = TRY(resolve_best_locale(global_object, vm.argument(0)));
auto uppercase = Unicode::to_unicode_uppercase_full(string, locale);
return js_string(vm, move(uppercase));
}
// 22.1.3.27 String.prototype.toLowerCase ( ), https://tc39.es/ecma262/#sec-string.prototype.tolowercase
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::to_lowercase)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_lowercase)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto lowercase = Unicode::to_unicode_lowercase_full(*string);
auto string = TRY(ak_string_from(vm, global_object));
auto lowercase = Unicode::to_unicode_lowercase_full(string);
return js_string(vm, move(lowercase));
}
// 22.1.3.29 String.prototype.toUpperCase ( ), https://tc39.es/ecma262/#sec-string.prototype.touppercase
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::to_uppercase)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_uppercase)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto uppercase = Unicode::to_unicode_uppercase_full(*string);
auto string = TRY(ak_string_from(vm, global_object));
auto uppercase = Unicode::to_unicode_uppercase_full(string);
return js_string(vm, move(uppercase));
}
// 22.1.3.28 String.prototype.toString ( ), https://tc39.es/ecma262/#sec-string.prototype.tostring
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::to_string)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_string)
{
return TRY_OR_DISCARD(this_string_value(global_object, vm.this_value(global_object)));
return TRY(this_string_value(global_object, vm.this_value(global_object)));
}
// 22.1.3.33 String.prototype.valueOf ( ), https://tc39.es/ecma262/#sec-string.prototype.valueof
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::value_of)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::value_of)
{
return TRY_OR_DISCARD(this_string_value(global_object, vm.this_value(global_object)));
return TRY(this_string_value(global_object, vm.this_value(global_object)));
}
enum class PadPlacement {
@ -475,75 +439,65 @@ static ThrowCompletionOr<Value> pad_string(GlobalObject& global_object, Utf16Str
}
// 22.1.3.16 String.prototype.padStart ( maxLength [ , fillString ] ), https://tc39.es/ecma262/#sec-string.prototype.padstart
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::pad_start)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_start)
{
auto string = utf16_string_from(vm, global_object);
return TRY_OR_DISCARD(pad_string(global_object, move(string), PadPlacement::Start));
auto string = TRY(utf16_string_from(vm, global_object));
return pad_string(global_object, move(string), PadPlacement::Start);
}
// 22.1.3.15 String.prototype.padEnd ( maxLength [ , fillString ] ), https://tc39.es/ecma262/#sec-string.prototype.padend
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::pad_end)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::pad_end)
{
auto string = utf16_string_from(vm, global_object);
return TRY_OR_DISCARD(pad_string(global_object, move(string), PadPlacement::End));
auto string = TRY(utf16_string_from(vm, global_object));
return pad_string(global_object, move(string), PadPlacement::End);
}
static Utf8View const whitespace_characters = Utf8View("\x09\x0A\x0B\x0C\x0D\x20\xC2\xA0\xE1\x9A\x80\xE2\x80\x80\xE2\x80\x81\xE2\x80\x82\xE2\x80\x83\xE2\x80\x84\xE2\x80\x85\xE2\x80\x86\xE2\x80\x87\xE2\x80\x88\xE2\x80\x89\xE2\x80\x8A\xE2\x80\xAF\xE2\x81\x9F\xE3\x80\x80\xE2\x80\xA8\xE2\x80\xA9\xEF\xBB\xBF"sv);
// 22.1.3.30 String.prototype.trim ( ), https://tc39.es/ecma262/#sec-string.prototype.trim
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::trim)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
return js_string(vm, Utf8View(*string).trim(whitespace_characters, TrimMode::Both).as_string());
auto string = TRY(ak_string_from(vm, global_object));
return js_string(vm, Utf8View(string).trim(whitespace_characters, TrimMode::Both).as_string());
}
// 22.1.3.32 String.prototype.trimStart ( ), https://tc39.es/ecma262/#sec-string.prototype.trimstart
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::trim_start)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_start)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
return js_string(vm, Utf8View(*string).trim(whitespace_characters, TrimMode::Left).as_string());
auto string = TRY(ak_string_from(vm, global_object));
return js_string(vm, Utf8View(string).trim(whitespace_characters, TrimMode::Left).as_string());
}
// 22.1.3.31 String.prototype.trimEnd ( ), https://tc39.es/ecma262/#sec-string.prototype.trimend
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::trim_end)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::trim_end)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
return js_string(vm, Utf8View(*string).trim(whitespace_characters, TrimMode::Right).as_string());
auto string = TRY(ak_string_from(vm, global_object));
return js_string(vm, Utf8View(string).trim(whitespace_characters, TrimMode::Right).as_string());
}
// 22.1.3.5 String.prototype.concat ( ...args ), https://tc39.es/ecma262/#sec-string.prototype.concat
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::concat)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::concat)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto string = TRY(ak_string_from(vm, global_object));
StringBuilder builder;
builder.append(*string);
builder.append(string);
for (size_t i = 0; i < vm.argument_count(); ++i) {
auto string_argument = TRY_OR_DISCARD(vm.argument(i).to_string(global_object));
auto string_argument = TRY(vm.argument(i).to_string(global_object));
builder.append(string_argument);
}
return js_string(vm, builder.to_string());
}
// 22.1.3.24 String.prototype.substring ( start, end ), https://tc39.es/ecma262/#sec-string.prototype.substring
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::substring)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto string_length = static_cast<double>(string.length_in_code_units());
auto start = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto start = TRY(vm.argument(0).to_integer_or_infinity(global_object));
auto end = string_length;
if (!vm.argument(1).is_undefined())
end = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
end = TRY(vm.argument(1).to_integer_or_infinity(global_object));
size_t final_start = clamp(start, static_cast<double>(0), string_length);
size_t final_end = clamp(end, static_cast<double>(0), string_length);
@ -555,14 +509,12 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::substring)
}
// B.2.2.1 String.prototype.substr ( start, length ), https://tc39.es/ecma262/#sec-string.prototype.substr
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::substr)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto size = string.length_in_code_units();
auto int_start = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto int_start = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (Value(int_start).is_negative_infinity())
int_start = 0;
if (int_start < 0)
@ -570,7 +522,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::substr)
auto length = vm.argument(1);
auto int_length = length.is_undefined() ? size : TRY_OR_DISCARD(length.to_integer_or_infinity(global_object));
auto int_length = length.is_undefined() ? size : TRY(length.to_integer_or_infinity(global_object));
if (Value(int_start).is_positive_infinity() || (int_length <= 0) || Value(int_length).is_positive_infinity())
return js_string(vm, String::empty());
@ -583,25 +535,21 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::substr)
}
// 22.1.3.8 String.prototype.includes ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.includes
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::includes)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::includes)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto search_string_value = vm.argument(0);
bool search_is_regexp = TRY_OR_DISCARD(search_string_value.is_regexp(global_object));
if (search_is_regexp) {
vm.throw_exception<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
return {};
}
bool search_is_regexp = TRY(search_string_value.is_regexp(global_object));
if (search_is_regexp)
return vm.throw_completion<TypeError>(global_object, ErrorType::IsNotA, "searchString", "string, but a regular expression");
auto search_string = TRY_OR_DISCARD(search_string_value.to_utf16_string(global_object));
auto search_string = TRY(search_string_value.to_utf16_string(global_object));
size_t start = 0;
if (!vm.argument(1).is_undefined()) {
auto position = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
auto position = TRY(vm.argument(1).to_integer_or_infinity(global_object));
start = clamp(position, static_cast<double>(0), static_cast<double>(string.length_in_code_units()));
}
@ -610,14 +558,12 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::includes)
}
// 22.1.3.21 String.prototype.slice ( start, end ), https://tc39.es/ecma262/#sec-string.prototype.slice
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::slice)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto string_length = static_cast<double>(string.length_in_code_units());
auto int_start = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto int_start = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (Value(int_start).is_negative_infinity())
int_start = 0;
else if (int_start < 0)
@ -627,7 +573,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::slice)
auto int_end = string_length;
if (!vm.argument(1).is_undefined()) {
int_end = TRY_OR_DISCARD(vm.argument(1).to_integer_or_infinity(global_object));
int_end = TRY(vm.argument(1).to_integer_or_infinity(global_object));
if (Value(int_end).is_negative_infinity())
int_end = 0;
else if (int_end < 0)
@ -643,29 +589,29 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::slice)
}
// 22.1.3.22 String.prototype.split ( separator, limit ), https://tc39.es/ecma262/#sec-string.prototype.split
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::split)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
{
auto object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto separator_argument = vm.argument(0);
auto limit_argument = vm.argument(1);
if (!separator_argument.is_nullish()) {
auto splitter = TRY_OR_DISCARD(separator_argument.get_method(global_object, *vm.well_known_symbol_split()));
auto splitter = TRY(separator_argument.get_method(global_object, *vm.well_known_symbol_split()));
if (splitter)
return TRY_OR_DISCARD(vm.call(*splitter, separator_argument, object, limit_argument));
return TRY(vm.call(*splitter, separator_argument, object, limit_argument));
}
auto string = TRY_OR_DISCARD(object.to_utf16_string(global_object));
auto string = TRY(object.to_utf16_string(global_object));
auto* array = MUST(Array::create(global_object, 0));
size_t array_length = 0;
auto limit = NumericLimits<u32>::max();
if (!limit_argument.is_undefined())
limit = TRY_OR_DISCARD(limit_argument.to_u32(global_object));
limit = TRY(limit_argument.to_u32(global_object));
auto separator = TRY_OR_DISCARD(separator_argument.to_utf16_string(global_object));
auto separator = TRY(separator_argument.to_utf16_string(global_object));
if (limit == 0)
return array;
@ -709,18 +655,16 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::split)
}
// 22.1.3.10 String.prototype.lastIndexOf ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.lastindexof
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::last_index_of)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto search_string = TRY_OR_DISCARD(vm.argument(0).to_utf16_string(global_object));
auto search_string = TRY(vm.argument(0).to_utf16_string(global_object));
auto string_length = string.length_in_code_units();
auto search_length = search_string.length_in_code_units();
auto position = TRY_OR_DISCARD(vm.argument(1).to_number(global_object));
double pos = position.is_nan() ? static_cast<double>(INFINITY) : TRY_OR_DISCARD(position.to_integer_or_infinity(global_object));
auto position = TRY(vm.argument(1).to_number(global_object));
double pos = position.is_nan() ? static_cast<double>(INFINITY) : TRY(position.to_integer_or_infinity(global_object));
size_t start = clamp(pos, static_cast<double>(0), static_cast<double>(string_length));
Optional<size_t> last_index;
@ -743,14 +687,12 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::last_index_of)
}
// 22.1.3.1 String.prototype.at ( index ), https://tc39.es/ecma262/#sec-string.prototype.at
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::at)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
{
auto string = utf16_string_from(vm, global_object);
if (vm.exception())
return {};
auto string = TRY(utf16_string_from(vm, global_object));
auto length = string.length_in_code_units();
auto relative_index = TRY_OR_DISCARD(vm.argument(0).to_integer_or_infinity(global_object));
auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(global_object));
if (Value(relative_index).is_infinity())
return js_undefined();
@ -768,76 +710,74 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::at)
}
// 22.1.3.34 String.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-string.prototype-@@iterator
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto string = TRY_OR_DISCARD(this_object.to_string(global_object));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto string = TRY(this_object.to_string(global_object));
return StringIterator::create(global_object, string);
}
// 22.1.3.12 String.prototype.match ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.match
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::match)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* matcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_match())))
return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object));
if (auto* matcher = TRY(regexp.get_method(global_object, *vm.well_known_symbol_match())))
return TRY(vm.call(*matcher, regexp, this_object));
}
auto string = TRY_OR_DISCARD(this_object.to_utf16_string(global_object));
auto string = TRY(this_object.to_utf16_string(global_object));
auto rx = regexp_create(global_object, regexp, js_undefined());
if (!rx)
return {};
return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_match(), js_string(vm, move(string))));
auto* rx = regexp_create(global_object, regexp, js_undefined());
if (auto* exception = vm.exception())
return throw_completion(exception->value());
return TRY(Value(rx).invoke(global_object, *vm.well_known_symbol_match(), js_string(vm, move(string))));
}
// 22.1.3.13 String.prototype.matchAll ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.matchall
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::match_all)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
auto is_regexp = TRY_OR_DISCARD(regexp.is_regexp(global_object));
auto is_regexp = TRY(regexp.is_regexp(global_object));
if (is_regexp) {
auto flags = TRY_OR_DISCARD(regexp.as_object().get("flags"));
auto flags_object = TRY_OR_DISCARD(require_object_coercible(global_object, flags));
auto flags_string = TRY_OR_DISCARD(flags_object.to_string(global_object));
if (!flags_string.contains("g")) {
vm.throw_exception<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
return {};
}
auto flags = TRY(regexp.as_object().get("flags"));
auto flags_object = TRY(require_object_coercible(global_object, flags));
auto flags_string = TRY(flags_object.to_string(global_object));
if (!flags_string.contains("g"))
return vm.throw_completion<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
}
if (auto* matcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_match_all())))
return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object));
if (auto* matcher = TRY(regexp.get_method(global_object, *vm.well_known_symbol_match_all())))
return TRY(vm.call(*matcher, regexp, this_object));
}
auto string = TRY_OR_DISCARD(this_object.to_utf16_string(global_object));
auto string = TRY(this_object.to_utf16_string(global_object));
auto rx = regexp_create(global_object, regexp, js_string(vm, "g"));
if (!rx)
return {};
return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_match_all(), js_string(vm, move(string))));
auto* rx = regexp_create(global_object, regexp, js_string(vm, "g"));
if (auto* exception = vm.exception())
return throw_completion(exception->value());
return TRY(Value(rx).invoke(global_object, *vm.well_known_symbol_match_all(), js_string(vm, move(string))));
}
// 22.1.3.18 String.prototype.replace ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replace
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto search_value = vm.argument(0);
auto replace_value = vm.argument(1);
if (!search_value.is_nullish()) {
if (auto* replacer = TRY_OR_DISCARD(search_value.get_method(global_object, *vm.well_known_symbol_replace())))
return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value));
if (auto* replacer = TRY(search_value.get_method(global_object, *vm.well_known_symbol_replace())))
return TRY(vm.call(*replacer, search_value, this_object, replace_value));
}
auto string = TRY_OR_DISCARD(this_object.to_utf16_string(global_object));
auto search_string = TRY_OR_DISCARD(search_value.to_utf16_string(global_object));
auto string = TRY(this_object.to_utf16_string(global_object));
auto search_string = TRY(search_value.to_utf16_string(global_object));
if (!replace_value.is_function()) {
auto replace_string = TRY_OR_DISCARD(replace_value.to_utf16_string(global_object));
auto replace_string = TRY(replace_value.to_utf16_string(global_object));
replace_value = js_string(vm, move(replace_string));
}
@ -849,10 +789,10 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace)
String replacement;
if (replace_value.is_function()) {
auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string)));
replacement = TRY_OR_DISCARD(result.to_string(global_object));
auto result = TRY(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position.value()), js_string(vm, string)));
replacement = TRY(result.to_string(global_object));
} else {
replacement = TRY_OR_DISCARD(get_substitution(global_object, search_string.view(), string.view(), *position, {}, js_undefined(), replace_value));
replacement = TRY(get_substitution(global_object, search_string.view(), string.view(), *position, {}, js_undefined(), replace_value));
}
StringBuilder builder;
@ -864,38 +804,34 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace)
}
// 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue ), https://tc39.es/ecma262/#sec-string.prototype.replaceall
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace_all)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto search_value = vm.argument(0);
auto replace_value = vm.argument(1);
if (!search_value.is_nullish()) {
bool is_regexp = TRY_OR_DISCARD(search_value.is_regexp(global_object));
bool is_regexp = TRY(search_value.is_regexp(global_object));
if (is_regexp) {
auto flags = TRY_OR_DISCARD(search_value.as_object().get(vm.names.flags));
auto flags_object = TRY_OR_DISCARD(require_object_coercible(global_object, flags));
auto flags_string = TRY_OR_DISCARD(flags_object.to_string(global_object));
if (!flags_string.contains("g")) {
vm.throw_exception<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
return {};
}
auto flags = TRY(search_value.as_object().get(vm.names.flags));
auto flags_object = TRY(require_object_coercible(global_object, flags));
auto flags_string = TRY(flags_object.to_string(global_object));
if (!flags_string.contains("g"))
return vm.throw_completion<TypeError>(global_object, ErrorType::StringNonGlobalRegExp);
}
auto* replacer = TRY_OR_DISCARD(search_value.get_method(global_object, *vm.well_known_symbol_replace()));
auto* replacer = TRY(search_value.get_method(global_object, *vm.well_known_symbol_replace()));
if (replacer)
return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value));
return TRY(vm.call(*replacer, search_value, this_object, replace_value));
}
auto string = TRY_OR_DISCARD(this_object.to_utf16_string(global_object));
auto search_string = TRY_OR_DISCARD(search_value.to_utf16_string(global_object));
auto string = TRY(this_object.to_utf16_string(global_object));
auto search_string = TRY(search_value.to_utf16_string(global_object));
if (!replace_value.is_function()) {
auto replace_string = TRY_OR_DISCARD(replace_value.to_utf16_string(global_object));
auto replace_string = TRY(replace_value.to_utf16_string(global_object));
replace_value = js_string(vm, move(replace_string));
if (vm.exception())
return {};
}
auto string_length = string.length_in_code_units();
@ -918,10 +854,10 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace_all)
String replacement;
if (replace_value.is_function()) {
auto result = TRY_OR_DISCARD(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string)));
replacement = TRY_OR_DISCARD(result.to_string(global_object));
auto result = TRY(vm.call(replace_value.as_function(), js_undefined(), js_string(vm, search_string), Value(position), js_string(vm, string)));
replacement = TRY(result.to_string(global_object));
} else {
replacement = TRY_OR_DISCARD(get_substitution(global_object, search_string.view(), string.view(), position, {}, js_undefined(), replace_value));
replacement = TRY(get_substitution(global_object, search_string.view(), string.view(), position, {}, js_undefined(), replace_value));
}
result.append(preserved);
@ -937,21 +873,21 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::replace_all)
}
// 22.1.3.20 String.prototype.search ( regexp ), https://tc39.es/ecma262/#sec-string.prototype.search
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::search)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search)
{
auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object)));
auto this_object = TRY(require_object_coercible(global_object, vm.this_value(global_object)));
auto regexp = vm.argument(0);
if (!regexp.is_nullish()) {
if (auto* searcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_search())))
return TRY_OR_DISCARD(vm.call(*searcher, regexp, this_object));
if (auto* searcher = TRY(regexp.get_method(global_object, *vm.well_known_symbol_search())))
return TRY(vm.call(*searcher, regexp, this_object));
}
auto string = TRY_OR_DISCARD(this_object.to_utf16_string(global_object));
auto string = TRY(this_object.to_utf16_string(global_object));
auto rx = regexp_create(global_object, regexp, js_undefined());
if (!rx)
return {};
return TRY_OR_DISCARD(Value(rx).invoke(global_object, *vm.well_known_symbol_search(), js_string(vm, move(string))));
auto* rx = regexp_create(global_object, regexp, js_undefined());
if (auto* exception = vm.exception())
return throw_completion(exception->value());
return TRY(Value(rx).invoke(global_object, *vm.well_known_symbol_search(), js_string(vm, move(string))));
}
// B.2.2.2.1 CreateHTML ( string, tag, attribute, value ), https://tc39.es/ecma262/#sec-createhtml
@ -980,97 +916,94 @@ static ThrowCompletionOr<Value> create_html(GlobalObject& global_object, Value s
}
// B.2.2.2 String.prototype.anchor ( name ), https://tc39.es/ecma262/#sec-string.prototype.anchor
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::anchor)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::anchor)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "a", "name", vm.argument(0)));
return create_html(global_object, vm.this_value(global_object), "a", "name", vm.argument(0));
}
// B.2.2.3 String.prototype.big ( ), https://tc39.es/ecma262/#sec-string.prototype.big
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::big)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::big)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "big", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "big", String::empty(), Value());
}
// B.2.2.4 String.prototype.blink ( ), https://tc39.es/ecma262/#sec-string.prototype.blink
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::blink)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::blink)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "blink", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "blink", String::empty(), Value());
}
// B.2.2.5 String.prototype.bold ( ), https://tc39.es/ecma262/#sec-string.prototype.bold
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::bold)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::bold)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "b", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "b", String::empty(), Value());
}
// B.2.2.6 String.prototype.fixed ( ), https://tc39.es/ecma262/#sec-string.prototype.fixed
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::fixed)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::fixed)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "tt", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "tt", String::empty(), Value());
}
// B.2.2.7 String.prototype.fontcolor ( color ), https://tc39.es/ecma262/#sec-string.prototype.fontcolor
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::fontcolor)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::fontcolor)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "font", "color", vm.argument(0)));
return create_html(global_object, vm.this_value(global_object), "font", "color", vm.argument(0));
}
// B.2.2.8 String.prototype.fontsize ( size ), https://tc39.es/ecma262/#sec-string.prototype.fontsize
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::fontsize)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::fontsize)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "font", "size", vm.argument(0)));
return create_html(global_object, vm.this_value(global_object), "font", "size", vm.argument(0));
}
// B.2.2.9 String.prototype.italics ( ), https://tc39.es/ecma262/#sec-string.prototype.italics
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::italics)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::italics)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "i", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "i", String::empty(), Value());
}
// B.2.2.10 String.prototype.link ( url ), https://tc39.es/ecma262/#sec-string.prototype.link
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::link)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::link)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "a", "href", vm.argument(0)));
return create_html(global_object, vm.this_value(global_object), "a", "href", vm.argument(0));
}
// B.2.2.11 String.prototype.small ( ), https://tc39.es/ecma262/#sec-string.prototype.small
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::small)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::small)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "small", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "small", String::empty(), Value());
}
// B.2.2.12 String.prototype.strike ( ), https://tc39.es/ecma262/#sec-string.prototype.strike
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::strike)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::strike)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "strike", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "strike", String::empty(), Value());
}
// B.2.2.13 String.prototype.sub ( ), https://tc39.es/ecma262/#sec-string.prototype.sub
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::sub)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::sub)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "sub", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "sub", String::empty(), Value());
}
// B.2.2.14 String.prototype.sup ( ), https://tc39.es/ecma262/#sec-string.prototype.sup
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::sup)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::sup)
{
return TRY_OR_DISCARD(create_html(global_object, vm.this_value(global_object), "sup", String::empty(), Value()));
return create_html(global_object, vm.this_value(global_object), "sup", String::empty(), Value());
}
// 22.1.3.11 String.prototype.localeCompare ( that [ , reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-string.prototype.localecompare
// NOTE: This is the minimum localeCompare implementation for engines without ECMA-402.
JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::locale_compare)
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::locale_compare)
{
auto string = ak_string_from(vm, global_object);
if (!string.has_value())
return {};
auto that_string = TRY_OR_DISCARD(vm.argument(0).to_string(global_object));
auto string = TRY(ak_string_from(vm, global_object));
auto that_string = TRY(vm.argument(0).to_string(global_object));
// FIXME: Actually compare the string not just according to their bits.
if (string == that_string)
return Value(0);
if (string.value() < that_string)
if (string < that_string)
return Value(-1);
return Value(1);

View file

@ -27,53 +27,53 @@ public:
virtual ~StringPrototype() override;
private:
JS_DECLARE_OLD_NATIVE_FUNCTION(char_at);
JS_DECLARE_OLD_NATIVE_FUNCTION(char_code_at);
JS_DECLARE_OLD_NATIVE_FUNCTION(code_point_at);
JS_DECLARE_OLD_NATIVE_FUNCTION(repeat);
JS_DECLARE_OLD_NATIVE_FUNCTION(starts_with);
JS_DECLARE_OLD_NATIVE_FUNCTION(ends_with);
JS_DECLARE_OLD_NATIVE_FUNCTION(index_of);
JS_DECLARE_OLD_NATIVE_FUNCTION(to_locale_lowercase);
JS_DECLARE_OLD_NATIVE_FUNCTION(to_locale_uppercase);
JS_DECLARE_OLD_NATIVE_FUNCTION(to_lowercase);
JS_DECLARE_OLD_NATIVE_FUNCTION(to_uppercase);
JS_DECLARE_OLD_NATIVE_FUNCTION(to_string);
JS_DECLARE_OLD_NATIVE_FUNCTION(value_of);
JS_DECLARE_OLD_NATIVE_FUNCTION(pad_start);
JS_DECLARE_OLD_NATIVE_FUNCTION(pad_end);
JS_DECLARE_OLD_NATIVE_FUNCTION(substring);
JS_DECLARE_OLD_NATIVE_FUNCTION(substr);
JS_DECLARE_OLD_NATIVE_FUNCTION(trim);
JS_DECLARE_OLD_NATIVE_FUNCTION(trim_start);
JS_DECLARE_OLD_NATIVE_FUNCTION(trim_end);
JS_DECLARE_OLD_NATIVE_FUNCTION(concat);
JS_DECLARE_OLD_NATIVE_FUNCTION(includes);
JS_DECLARE_OLD_NATIVE_FUNCTION(slice);
JS_DECLARE_OLD_NATIVE_FUNCTION(split);
JS_DECLARE_OLD_NATIVE_FUNCTION(last_index_of);
JS_DECLARE_OLD_NATIVE_FUNCTION(at);
JS_DECLARE_OLD_NATIVE_FUNCTION(match);
JS_DECLARE_OLD_NATIVE_FUNCTION(match_all);
JS_DECLARE_OLD_NATIVE_FUNCTION(replace);
JS_DECLARE_OLD_NATIVE_FUNCTION(replace_all);
JS_DECLARE_OLD_NATIVE_FUNCTION(search);
JS_DECLARE_OLD_NATIVE_FUNCTION(anchor);
JS_DECLARE_OLD_NATIVE_FUNCTION(big);
JS_DECLARE_OLD_NATIVE_FUNCTION(blink);
JS_DECLARE_OLD_NATIVE_FUNCTION(bold);
JS_DECLARE_OLD_NATIVE_FUNCTION(fixed);
JS_DECLARE_OLD_NATIVE_FUNCTION(fontcolor);
JS_DECLARE_OLD_NATIVE_FUNCTION(fontsize);
JS_DECLARE_OLD_NATIVE_FUNCTION(italics);
JS_DECLARE_OLD_NATIVE_FUNCTION(link);
JS_DECLARE_OLD_NATIVE_FUNCTION(small);
JS_DECLARE_OLD_NATIVE_FUNCTION(strike);
JS_DECLARE_OLD_NATIVE_FUNCTION(sub);
JS_DECLARE_OLD_NATIVE_FUNCTION(sup);
JS_DECLARE_OLD_NATIVE_FUNCTION(locale_compare);
JS_DECLARE_NATIVE_FUNCTION(char_at);
JS_DECLARE_NATIVE_FUNCTION(char_code_at);
JS_DECLARE_NATIVE_FUNCTION(code_point_at);
JS_DECLARE_NATIVE_FUNCTION(repeat);
JS_DECLARE_NATIVE_FUNCTION(starts_with);
JS_DECLARE_NATIVE_FUNCTION(ends_with);
JS_DECLARE_NATIVE_FUNCTION(index_of);
JS_DECLARE_NATIVE_FUNCTION(to_locale_lowercase);
JS_DECLARE_NATIVE_FUNCTION(to_locale_uppercase);
JS_DECLARE_NATIVE_FUNCTION(to_lowercase);
JS_DECLARE_NATIVE_FUNCTION(to_uppercase);
JS_DECLARE_NATIVE_FUNCTION(to_string);
JS_DECLARE_NATIVE_FUNCTION(value_of);
JS_DECLARE_NATIVE_FUNCTION(pad_start);
JS_DECLARE_NATIVE_FUNCTION(pad_end);
JS_DECLARE_NATIVE_FUNCTION(substring);
JS_DECLARE_NATIVE_FUNCTION(substr);
JS_DECLARE_NATIVE_FUNCTION(trim);
JS_DECLARE_NATIVE_FUNCTION(trim_start);
JS_DECLARE_NATIVE_FUNCTION(trim_end);
JS_DECLARE_NATIVE_FUNCTION(concat);
JS_DECLARE_NATIVE_FUNCTION(includes);
JS_DECLARE_NATIVE_FUNCTION(slice);
JS_DECLARE_NATIVE_FUNCTION(split);
JS_DECLARE_NATIVE_FUNCTION(last_index_of);
JS_DECLARE_NATIVE_FUNCTION(at);
JS_DECLARE_NATIVE_FUNCTION(match);
JS_DECLARE_NATIVE_FUNCTION(match_all);
JS_DECLARE_NATIVE_FUNCTION(replace);
JS_DECLARE_NATIVE_FUNCTION(replace_all);
JS_DECLARE_NATIVE_FUNCTION(search);
JS_DECLARE_NATIVE_FUNCTION(anchor);
JS_DECLARE_NATIVE_FUNCTION(big);
JS_DECLARE_NATIVE_FUNCTION(blink);
JS_DECLARE_NATIVE_FUNCTION(bold);
JS_DECLARE_NATIVE_FUNCTION(fixed);
JS_DECLARE_NATIVE_FUNCTION(fontcolor);
JS_DECLARE_NATIVE_FUNCTION(fontsize);
JS_DECLARE_NATIVE_FUNCTION(italics);
JS_DECLARE_NATIVE_FUNCTION(link);
JS_DECLARE_NATIVE_FUNCTION(small);
JS_DECLARE_NATIVE_FUNCTION(strike);
JS_DECLARE_NATIVE_FUNCTION(sub);
JS_DECLARE_NATIVE_FUNCTION(sup);
JS_DECLARE_NATIVE_FUNCTION(locale_compare);
JS_DECLARE_OLD_NATIVE_FUNCTION(symbol_iterator);
JS_DECLARE_NATIVE_FUNCTION(symbol_iterator);
};
}