mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-13 09:50:36 +00:00
LibJS+Everywhere: Make PrimitiveString and Utf16String fallible
This makes construction of Utf16String fallible in OOM conditions. The immediate impact is that PrimitiveString must then be fallible as well, as it may either transcode UTF-8 to UTF-16, or create a UTF-16 string from ropes. There are a couple of places where it is very non-trivial to propagate the error further. A FIXME has been added to those locations.
This commit is contained in:
parent
d793262beb
commit
115baa7e32
Notes:
sideshowbarker
2024-07-17 07:35:03 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/115baa7e32 Pull-request: https://github.com/SerenityOS/serenity/pull/16895 Reviewed-by: https://github.com/linusg
57 changed files with 306 additions and 295 deletions
|
@ -62,14 +62,14 @@ TESTJS_GLOBAL_FUNCTION(mark_as_garbage, markAsGarbage)
|
|||
return execution_context->lexical_environment != nullptr;
|
||||
});
|
||||
if (!outer_environment.has_value())
|
||||
return vm.throw_completion<JS::ReferenceError>(JS::ErrorType::UnknownIdentifier, variable_name.deprecated_string());
|
||||
return vm.throw_completion<JS::ReferenceError>(JS::ErrorType::UnknownIdentifier, TRY(variable_name.deprecated_string()));
|
||||
|
||||
auto reference = TRY(vm.resolve_binding(variable_name.deprecated_string(), outer_environment.value()->lexical_environment));
|
||||
auto reference = TRY(vm.resolve_binding(TRY(variable_name.deprecated_string()), outer_environment.value()->lexical_environment));
|
||||
|
||||
auto value = TRY(reference.get_value(vm));
|
||||
|
||||
if (!can_be_held_weakly(value))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::CannotBeHeldWeakly, DeprecatedString::formatted("Variable with name {}", variable_name.deprecated_string()));
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::CannotBeHeldWeakly, DeprecatedString::formatted("Variable with name {}", TRY(variable_name.deprecated_string())));
|
||||
|
||||
vm.heap().uproot_cell(&value.as_cell());
|
||||
TRY(reference.delete_(vm));
|
||||
|
|
|
@ -196,7 +196,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_real_cell_contents)
|
|||
auto name_value = vm.argument(0);
|
||||
if (!name_value.is_string())
|
||||
return vm.throw_completion<JS::TypeError>("Expected a String argument to get_real_cell_contents()");
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
|
||||
if (!position.has_value())
|
||||
return vm.throw_completion<JS::TypeError>("Invalid cell name");
|
||||
|
||||
|
@ -225,7 +225,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
|
|||
auto name_value = vm.argument(0);
|
||||
if (!name_value.is_string())
|
||||
return vm.throw_completion<JS::TypeError>("Expected the first argument of set_real_cell_contents() to be a String");
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
|
||||
if (!position.has_value())
|
||||
return vm.throw_completion<JS::TypeError>("Invalid cell name");
|
||||
|
||||
|
@ -234,7 +234,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::set_real_cell_contents)
|
|||
return vm.throw_completion<JS::TypeError>("Expected the second argument of set_real_cell_contents() to be a String");
|
||||
|
||||
auto& cell = sheet_object->m_sheet.ensure(position.value());
|
||||
auto& new_contents = new_contents_value.as_string().deprecated_string();
|
||||
auto const& new_contents = TRY(new_contents_value.as_string().deprecated_string());
|
||||
cell.set_data(new_contents);
|
||||
return JS::js_null();
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::parse_cell_name)
|
|||
auto name_value = vm.argument(0);
|
||||
if (!name_value.is_string())
|
||||
return vm.throw_completion<JS::TypeError>("Expected a String argument to parse_cell_name()");
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(name_value.as_string().deprecated_string());
|
||||
auto position = sheet_object->m_sheet.parse_cell_name(TRY(name_value.as_string().deprecated_string()));
|
||||
if (!position.has_value())
|
||||
return JS::js_undefined();
|
||||
|
||||
|
@ -301,7 +301,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_index)
|
|||
if (!column_name.is_string())
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||
|
||||
auto& column_name_str = column_name.as_string().deprecated_string();
|
||||
auto const& column_name_str = TRY(column_name.as_string().deprecated_string());
|
||||
|
||||
auto* this_object = TRY(vm.this_value().to_object(vm));
|
||||
|
||||
|
@ -326,7 +326,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::column_arithmetic)
|
|||
if (!column_name.is_string())
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||
|
||||
auto& column_name_str = column_name.as_string().deprecated_string();
|
||||
auto const& column_name_str = TRY(column_name.as_string().deprecated_string());
|
||||
|
||||
auto offset = TRY(vm.argument(1).to_number(vm));
|
||||
auto offset_number = static_cast<i32>(offset.as_double());
|
||||
|
@ -354,7 +354,7 @@ JS_DEFINE_NATIVE_FUNCTION(SheetGlobalObject::get_column_bound)
|
|||
if (!column_name.is_string())
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "String");
|
||||
|
||||
auto& column_name_str = column_name.as_string().deprecated_string();
|
||||
auto const& column_name_str = TRY(column_name.as_string().deprecated_string());
|
||||
auto* this_object = TRY(vm.this_value().to_object(vm));
|
||||
|
||||
if (!is<SheetGlobalObject>(this_object))
|
||||
|
@ -405,7 +405,7 @@ JS_DEFINE_NATIVE_FUNCTION(WorkbookObject::sheet)
|
|||
auto& workbook = static_cast<WorkbookObject*>(this_object)->m_workbook;
|
||||
|
||||
if (name_value.is_string()) {
|
||||
auto& name = name_value.as_string().deprecated_string();
|
||||
auto const& name = TRY(name_value.as_string().deprecated_string());
|
||||
for (auto& sheet : workbook.sheets()) {
|
||||
if (sheet.name() == name)
|
||||
return JS::Value(&sheet.global_object());
|
||||
|
|
|
@ -3446,7 +3446,7 @@ Completion ImportCall::execute(Interpreter& interpreter) const
|
|||
// 4. If supportedAssertions contains key, then
|
||||
if (supported_assertions.contains_slow(property_key.to_string())) {
|
||||
// a. Append { [[Key]]: key, [[Value]]: value } to assertions.
|
||||
assertions.empend(property_key.to_string(), value.as_string().deprecated_string());
|
||||
assertions.empend(property_key.to_string(), TRY(value.as_string().deprecated_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ ThrowCompletionOr<Value> Console::assert_()
|
|||
// 3. Otherwise:
|
||||
else {
|
||||
// 1. Let concat be the concatenation of message, U+003A (:), U+0020 SPACE, and first.
|
||||
auto concat = PrimitiveString::create(vm, DeprecatedString::formatted("{}: {}", message->deprecated_string(), first.to_string(vm).value()));
|
||||
auto concat = PrimitiveString::create(vm, DeprecatedString::formatted("{}: {}", TRY(message->deprecated_string()), first.to_string(vm).value()));
|
||||
// 2. Set data[0] to concat.
|
||||
data[0] = concat;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ ThrowCompletionOr<Value> IsHTMLDDA::call()
|
|||
auto& vm = this->vm();
|
||||
if (vm.argument_count() == 0)
|
||||
return js_null();
|
||||
if (vm.argument(0).is_string() && vm.argument(0).as_string().deprecated_string().is_empty())
|
||||
if (vm.argument(0).is_string() && TRY(vm.argument(0).as_string().deprecated_string()).is_empty())
|
||||
return js_null();
|
||||
// Not sure if this really matters, INTERPRETING.md simply says:
|
||||
// * IsHTMLDDA - (present only in implementations that can provide it) an object that:
|
||||
|
|
|
@ -777,9 +777,13 @@ ErrorOr<void> print_intl_segmenter(JS::PrintContext& print_context, JS::Intl::Se
|
|||
|
||||
ErrorOr<void> print_intl_segments(JS::PrintContext& print_context, JS::Intl::Segments const& segments, HashTable<JS::Object*>& seen_objects)
|
||||
{
|
||||
auto segments_string = JS::Utf16String::create(segments.vm(), segments.segments_string());
|
||||
if (segments_string.is_error())
|
||||
return Error::from_errno(ENOMEM);
|
||||
|
||||
TRY(print_type(print_context, "Segments"));
|
||||
out("\n string: ");
|
||||
TRY(print_value(print_context, JS::PrimitiveString::create(segments.vm(), segments.segments_string()), seen_objects));
|
||||
TRY(print_value(print_context, JS::PrimitiveString::create(segments.vm(), segments_string.release_value()), seen_objects));
|
||||
out("\n segmenter: ");
|
||||
TRY(print_value(print_context, &segments.segments_segmenter(), seen_objects));
|
||||
return {};
|
||||
|
|
|
@ -594,7 +594,7 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
|
|||
.in_class_field_initializer = in_class_field_initializer,
|
||||
};
|
||||
|
||||
Parser parser { Lexer { code_string.deprecated_string() }, Program::Type::Script, move(initial_state) };
|
||||
Parser parser { Lexer { TRY(code_string.deprecated_string()) }, Program::Type::Script, move(initial_state) };
|
||||
auto program = parser.parse_program(strict_caller == CallerMode::Strict);
|
||||
|
||||
// b. If script is a List of errors, throw a SyntaxError exception.
|
||||
|
|
|
@ -241,7 +241,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DateConstructor::construct(FunctionObjec
|
|||
if (primitive.is_string()) {
|
||||
// 1. Assert: The next step never returns an abrupt completion because Type(v) is String.
|
||||
// 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
|
||||
time_value = parse_date_string(primitive.as_string().deprecated_string());
|
||||
time_value = parse_date_string(TRY(primitive.as_string().deprecated_string()));
|
||||
}
|
||||
// iii. Else,
|
||||
else {
|
||||
|
|
|
@ -1257,7 +1257,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive)
|
|||
auto hint_value = vm.argument(0);
|
||||
if (!hint_value.is_string())
|
||||
return vm.throw_completion<TypeError>(ErrorType::InvalidHint, hint_value.to_string_without_side_effects());
|
||||
auto& hint = hint_value.as_string().deprecated_string();
|
||||
auto const& hint = TRY(hint_value.as_string().deprecated_string());
|
||||
Value::PreferredType try_first;
|
||||
if (hint == "string" || hint == "default")
|
||||
try_first = Value::PreferredType::String;
|
||||
|
|
|
@ -343,7 +343,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval)
|
|||
// 19.2.6.1.1 Encode ( string, unescapedSet ), https://tc39.es/ecma262/#sec-encode
|
||||
static ThrowCompletionOr<DeprecatedString> encode(VM& vm, DeprecatedString const& string, StringView unescaped_set)
|
||||
{
|
||||
auto utf16_string = Utf16String(string);
|
||||
auto utf16_string = TRY(Utf16String::create(vm, string));
|
||||
|
||||
// 1. Let strLen be the length of string.
|
||||
auto string_length = utf16_string.length_in_code_units();
|
||||
|
|
|
@ -376,14 +376,14 @@ static auto& find_key_in_value(T& value, StringView key)
|
|||
}
|
||||
|
||||
// 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ), https://tc39.es/ecma402/#sec-resolvelocale
|
||||
LocaleResult resolve_locale(Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys)
|
||||
{
|
||||
// 1. Let matcher be options.[[localeMatcher]].
|
||||
auto const& matcher = options.locale_matcher;
|
||||
MatcherResult matcher_result;
|
||||
|
||||
// 2. If matcher is "lookup", then
|
||||
if (matcher.is_string() && (matcher.as_string().deprecated_string() == "lookup"sv)) {
|
||||
if (matcher.is_string() && (TRY(matcher.as_string().deprecated_string()) == "lookup"sv)) {
|
||||
// a. Let r be ! LookupMatcher(availableLocales, requestedLocales).
|
||||
matcher_result = lookup_matcher(requested_locales);
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ ThrowCompletionOr<Array*> supported_locales(VM& vm, Vector<DeprecatedString> con
|
|||
Vector<DeprecatedString> supported_locales;
|
||||
|
||||
// 3. If matcher is "best fit", then
|
||||
if (matcher.as_string().deprecated_string() == "best fit"sv) {
|
||||
if (TRY(matcher.as_string().deprecated_string()) == "best fit"sv) {
|
||||
// a. Let supportedLocales be BestFitSupportedLocales(availableLocales, requestedLocales).
|
||||
supported_locales = best_fit_supported_locales(requested_locales);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ bool is_well_formed_unit_identifier(StringView unit_identifier);
|
|||
ThrowCompletionOr<Vector<DeprecatedString>> canonicalize_locale_list(VM&, Value locales);
|
||||
Optional<DeprecatedString> best_available_locale(StringView locale);
|
||||
DeprecatedString insert_unicode_extension_and_canonicalize(::Locale::LocaleID locale_id, ::Locale::LocaleExtension extension);
|
||||
LocaleResult resolve_locale(Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||
ThrowCompletionOr<LocaleResult> resolve_locale(Vector<DeprecatedString> const& requested_locales, LocaleOptions const& options, Span<StringView const> relevant_extension_keys);
|
||||
Vector<DeprecatedString> lookup_supported_locales(Vector<DeprecatedString> const& requested_locales);
|
||||
Vector<DeprecatedString> best_fit_supported_locales(Vector<DeprecatedString> const& requested_locales);
|
||||
ThrowCompletionOr<Array*> supported_locales(VM&, Vector<DeprecatedString> const& requested_locales, Value options);
|
||||
|
|
|
@ -27,7 +27,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
auto usage = TRY(get_option(vm, *options, vm.names.usage, OptionType::String, { "sort"sv, "search"sv }, "sort"sv));
|
||||
|
||||
// 4. Set collator.[[Usage]] to usage.
|
||||
collator.set_usage(usage.as_string().deprecated_string());
|
||||
collator.set_usage(TRY(usage.as_string().deprecated_string()));
|
||||
|
||||
// 5. If usage is "sort", then
|
||||
// a. Let localeData be %Collator%.[[SortLocaleData]].
|
||||
|
@ -49,11 +49,11 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
// 11. If collation is not undefined, then
|
||||
if (!collation.is_undefined()) {
|
||||
// a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(collation.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(collation.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, collation, "collation"sv);
|
||||
|
||||
// 12. Set opt.[[co]] to collation.
|
||||
opt.co = collation.as_string().deprecated_string();
|
||||
opt.co = TRY(collation.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13. Let numeric be ? GetOption(options, "numeric", "boolean", undefined, undefined).
|
||||
|
@ -69,13 +69,13 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
// 17. Set opt.[[kf]] to caseFirst.
|
||||
auto case_first = TRY(get_option(vm, *options, vm.names.caseFirst, OptionType::String, { "upper"sv, "lower"sv, "false"sv }, Empty {}));
|
||||
if (!case_first.is_undefined())
|
||||
opt.kf = case_first.as_string().deprecated_string();
|
||||
opt.kf = TRY(case_first.as_string().deprecated_string());
|
||||
|
||||
// 18. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]].
|
||||
auto relevant_extension_keys = Collator::relevant_extension_keys();
|
||||
|
||||
// 19. Let r be ResolveLocale(%Collator%.[[AvailableLocales]], requestedLocales, opt, relevantExtensionKeys, localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, relevant_extension_keys);
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, relevant_extension_keys));
|
||||
|
||||
// 20. Set collator.[[Locale]] to r.[[locale]].
|
||||
collator.set_locale(move(result.locale));
|
||||
|
@ -117,7 +117,7 @@ static ThrowCompletionOr<Collator*> initialize_collator(VM& vm, Collator& collat
|
|||
}
|
||||
|
||||
// 28. Set collator.[[Sensitivity]] to sensitivity.
|
||||
collator.set_sensitivity(sensitivity.as_string().deprecated_string());
|
||||
collator.set_sensitivity(TRY(sensitivity.as_string().deprecated_string()));
|
||||
|
||||
// 29. Let ignorePunctuation be ? GetOption(options, "ignorePunctuation", "boolean", undefined, false).
|
||||
auto ignore_punctuation = TRY(get_option(vm, *options, vm.names.ignorePunctuation, OptionType::Boolean, {}, false));
|
||||
|
|
|
@ -716,7 +716,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
|
|||
// 2. If the "length" property of fv is greater than 2, let fv be the substring of fv containing the last two characters.
|
||||
// NOTE: The first length check here isn't enough, but lets us avoid UTF-16 transcoding when the formatted value is ASCII.
|
||||
if (formatted_value.length() > 2) {
|
||||
Utf16String utf16_formatted_value { formatted_value };
|
||||
auto utf16_formatted_value = TRY(Utf16String::create(vm, formatted_value));
|
||||
if (utf16_formatted_value.length_in_code_units() > 2)
|
||||
formatted_value = TRY_OR_THROW_OOM(vm, utf16_formatted_value.substring_view(utf16_formatted_value.length_in_code_units() - 2).to_utf8());
|
||||
}
|
||||
|
|
|
@ -106,11 +106,11 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
// 7. If calendar is not undefined, then
|
||||
if (!calendar.is_undefined()) {
|
||||
// a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(calendar.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(calendar.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, calendar, "calendar"sv);
|
||||
|
||||
// 8. Set opt.[[ca]] to calendar.
|
||||
opt.ca = calendar.as_string().deprecated_string();
|
||||
opt.ca = TRY(calendar.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 9. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
|
||||
|
@ -119,11 +119,11 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
// 10. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(numbering_system.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(numbering_system.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 11. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = numbering_system.as_string().deprecated_string();
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 12. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, undefined).
|
||||
|
@ -140,11 +140,11 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
|
||||
// 15. Set opt.[[hc]] to hourCycle.
|
||||
if (!hour_cycle.is_nullish())
|
||||
opt.hc = hour_cycle.as_string().deprecated_string();
|
||||
opt.hc = TRY(hour_cycle.as_string().deprecated_string());
|
||||
|
||||
// 16. Let localeData be %DateTimeFormat%.[[LocaleData]].
|
||||
// 17. Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, DateTimeFormat::relevant_extension_keys());
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, DateTimeFormat::relevant_extension_keys()));
|
||||
|
||||
// 18. Set dateTimeFormat.[[Locale]] to r.[[locale]].
|
||||
date_time_format.set_locale(move(result.locale));
|
||||
|
@ -277,7 +277,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
|
||||
// d. Set formatOptions.[[<prop>]] to value.
|
||||
if (!value.is_undefined()) {
|
||||
option = ::Locale::calendar_pattern_style_from_string(value.as_string().deprecated_string());
|
||||
option = ::Locale::calendar_pattern_style_from_string(TRY(value.as_string().deprecated_string()));
|
||||
|
||||
// e. If value is not undefined, then
|
||||
// i. Set hasExplicitFormatComponents to true.
|
||||
|
@ -296,14 +296,14 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
|
||||
// 39. Set dateTimeFormat.[[DateStyle]] to dateStyle.
|
||||
if (!date_style.is_undefined())
|
||||
date_time_format.set_date_style(date_style.as_string().deprecated_string());
|
||||
date_time_format.set_date_style(TRY(date_style.as_string().deprecated_string()));
|
||||
|
||||
// 40. Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined).
|
||||
auto time_style = TRY(get_option(vm, *options, vm.names.timeStyle, OptionType::String, AK::Array { "full"sv, "long"sv, "medium"sv, "short"sv }, Empty {}));
|
||||
|
||||
// 41. Set dateTimeFormat.[[TimeStyle]] to timeStyle.
|
||||
if (!time_style.is_undefined())
|
||||
date_time_format.set_time_style(time_style.as_string().deprecated_string());
|
||||
date_time_format.set_time_style(TRY(time_style.as_string().deprecated_string()));
|
||||
|
||||
Optional<::Locale::CalendarPattern> best_format {};
|
||||
|
||||
|
@ -325,7 +325,7 @@ ThrowCompletionOr<DateTimeFormat*> initialize_date_time_format(VM& vm, DateTimeF
|
|||
auto formats = ::Locale::get_calendar_available_formats(data_locale, date_time_format.calendar());
|
||||
|
||||
// b. If matcher is "basic", then
|
||||
if (matcher.as_string().deprecated_string() == "basic"sv) {
|
||||
if (TRY(matcher.as_string().deprecated_string()) == "basic"sv) {
|
||||
// i. Let bestFormat be BasicFormatMatcher(formatOptions, formats).
|
||||
best_format = basic_format_matcher(format_options, move(formats));
|
||||
}
|
||||
|
|
|
@ -76,13 +76,13 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DisplayNamesConstructor::construct(Funct
|
|||
opt.locale_matcher = matcher;
|
||||
|
||||
// 10. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]], requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]).
|
||||
auto result = resolve_locale(requested_locales, opt, {});
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, {}));
|
||||
|
||||
// 11. Let style be ? GetOption(options, "style", "string", « "narrow", "short", "long" », "long").
|
||||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "narrow"sv, "short"sv, "long"sv }, "long"sv));
|
||||
|
||||
// 12. Set displayNames.[[Style]] to style.
|
||||
display_names->set_style(style.as_string().deprecated_string());
|
||||
display_names->set_style(TRY(style.as_string().deprecated_string()));
|
||||
|
||||
// 13. Let type be ? GetOption(options, "type", "string", « "language", "region", "script", "currency", "calendar", "dateTimeField" », undefined).
|
||||
auto type = TRY(get_option(vm, *options, vm.names.type, OptionType::String, { "language"sv, "region"sv, "script"sv, "currency"sv, "calendar"sv, "dateTimeField"sv }, Empty {}));
|
||||
|
@ -92,13 +92,13 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DisplayNamesConstructor::construct(Funct
|
|||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "options.type"sv);
|
||||
|
||||
// 15. Set displayNames.[[Type]] to type.
|
||||
display_names->set_type(type.as_string().deprecated_string());
|
||||
display_names->set_type(TRY(type.as_string().deprecated_string()));
|
||||
|
||||
// 16. Let fallback be ? GetOption(options, "fallback", "string", « "code", "none" », "code").
|
||||
auto fallback = TRY(get_option(vm, *options, vm.names.fallback, OptionType::String, { "code"sv, "none"sv }, "code"sv));
|
||||
|
||||
// 17. Set displayNames.[[Fallback]] to fallback.
|
||||
display_names->set_fallback(fallback.as_string().deprecated_string());
|
||||
display_names->set_fallback(TRY(fallback.as_string().deprecated_string()));
|
||||
|
||||
// 18. Set displayNames.[[Locale]] to r.[[locale]].
|
||||
display_names->set_locale(move(result.locale));
|
||||
|
@ -119,7 +119,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DisplayNamesConstructor::construct(Funct
|
|||
// 26. If type is "language", then
|
||||
if (display_names->type() == DisplayNames::Type::Language) {
|
||||
// a. Set displayNames.[[LanguageDisplay]] to languageDisplay.
|
||||
display_names->set_language_display(language_display.as_string().deprecated_string());
|
||||
display_names->set_language_display(TRY(language_display.as_string().deprecated_string()));
|
||||
|
||||
// b. Let typeFields be typeFields.[[<languageDisplay>]].
|
||||
// c. Assert: typeFields is a Record (see 12.4.3).
|
||||
|
|
|
@ -47,7 +47,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
|
|||
code = PrimitiveString::create(vm, move(code_string));
|
||||
|
||||
// 4. Let code be ? CanonicalCodeForDisplayNames(displayNames.[[Type]], code).
|
||||
code = TRY(canonical_code_for_display_names(vm, display_names->type(), code.as_string().deprecated_string()));
|
||||
code = TRY(canonical_code_for_display_names(vm, display_names->type(), TRY(code.as_string().deprecated_string())));
|
||||
|
||||
// 5. Let fields be displayNames.[[Fields]].
|
||||
// 6. If fields has a field [[<code>]], return fields.[[<code>]].
|
||||
|
@ -57,48 +57,48 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
|
|||
switch (display_names->type()) {
|
||||
case DisplayNames::Type::Language:
|
||||
if (display_names->language_display() == DisplayNames::LanguageDisplay::Dialect) {
|
||||
result = ::Locale::get_locale_language_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_language_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
if (result.has_value())
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto locale = is_structurally_valid_language_tag(code.as_string().deprecated_string()); locale.has_value())
|
||||
if (auto locale = is_structurally_valid_language_tag(TRY(code.as_string().deprecated_string())); locale.has_value())
|
||||
formatted_result = ::Locale::format_locale_for_display(display_names->locale(), locale.release_value());
|
||||
break;
|
||||
case DisplayNames::Type::Region:
|
||||
result = ::Locale::get_locale_territory_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_territory_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case DisplayNames::Type::Script:
|
||||
result = ::Locale::get_locale_script_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_script_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case DisplayNames::Type::Currency:
|
||||
switch (display_names->style()) {
|
||||
case ::Locale::Style::Long:
|
||||
result = ::Locale::get_locale_long_currency_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_long_currency_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case ::Locale::Style::Short:
|
||||
result = ::Locale::get_locale_short_currency_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_short_currency_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case ::Locale::Style::Narrow:
|
||||
result = ::Locale::get_locale_narrow_currency_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_narrow_currency_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
case DisplayNames::Type::Calendar:
|
||||
result = ::Locale::get_locale_calendar_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_calendar_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case DisplayNames::Type::DateTimeField:
|
||||
switch (display_names->style()) {
|
||||
case ::Locale::Style::Long:
|
||||
result = ::Locale::get_locale_long_date_field_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_long_date_field_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case ::Locale::Style::Short:
|
||||
result = ::Locale::get_locale_short_date_field_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_short_date_field_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
case ::Locale::Style::Narrow:
|
||||
result = ::Locale::get_locale_narrow_date_field_mapping(display_names->locale(), code.as_string().deprecated_string());
|
||||
result = ::Locale::get_locale_narrow_date_field_mapping(display_names->locale(), TRY(code.as_string().deprecated_string()));
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
|
|
|
@ -308,7 +308,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, Depreca
|
|||
}
|
||||
}
|
||||
} else {
|
||||
style = style_value.as_string().deprecated_string();
|
||||
style = TRY(style_value.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 4. Let displayField be the string-concatenation of unit and "Display".
|
||||
|
@ -332,7 +332,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, Depreca
|
|||
}
|
||||
|
||||
// 7. Return the Record { [[Style]]: style, [[Display]]: display }.
|
||||
return DurationUnitOptions { .style = move(style), .display = display.as_string().deprecated_string() };
|
||||
return DurationUnitOptions { .style = move(style), .display = TRY(display.as_string().deprecated_string()) };
|
||||
}
|
||||
|
||||
// 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern
|
||||
|
|
|
@ -67,17 +67,17 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
|
|||
// 7. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(numbering_system.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(numbering_system.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
}
|
||||
|
||||
// 8. Let opt be the Record { [[localeMatcher]]: matcher, [[nu]]: numberingSystem }.
|
||||
LocaleOptions opt {};
|
||||
opt.locale_matcher = matcher;
|
||||
opt.nu = numbering_system.is_undefined() ? Optional<DeprecatedString>() : numbering_system.as_string().deprecated_string();
|
||||
opt.nu = numbering_system.is_undefined() ? Optional<DeprecatedString>() : TRY(numbering_system.as_string().deprecated_string());
|
||||
|
||||
// 9. Let r be ResolveLocale(%DurationFormat%.[[AvailableLocales]], requestedLocales, opt, %DurationFormat%.[[RelevantExtensionKeys]], %DurationFormat%.[[LocaleData]]).
|
||||
auto result = resolve_locale(requested_locales, opt, DurationFormat::relevant_extension_keys());
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, DurationFormat::relevant_extension_keys()));
|
||||
|
||||
// 10. Let locale be r.[[locale]].
|
||||
auto locale = move(result.locale);
|
||||
|
@ -93,7 +93,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
|
|||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv, "digital"sv }, "short"sv));
|
||||
|
||||
// 14. Set durationFormat.[[Style]] to style.
|
||||
duration_format->set_style(style.as_string().deprecated_string());
|
||||
duration_format->set_style(TRY(style.as_string().deprecated_string()));
|
||||
|
||||
// 15. Set durationFormat.[[DataLocale]] to r.[[dataLocale]].
|
||||
duration_format->set_data_locale(move(result.data_locale));
|
||||
|
@ -119,7 +119,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DurationFormatConstructor::construct(Fun
|
|||
auto digital_base = duration_instances_component.digital_default;
|
||||
|
||||
// f. Let unitOptions be ? GetDurationUnitOptions(unit, options, style, valueList, digitalBase, prevStyle).
|
||||
auto unit_options = TRY(get_duration_unit_options(vm, unit, *options, style.as_string().deprecated_string(), value_list, digital_base, previous_style));
|
||||
auto unit_options = TRY(get_duration_unit_options(vm, unit, *options, TRY(style.as_string().deprecated_string()), value_list, digital_base, previous_style));
|
||||
|
||||
// g. Set the value of the styleSlot slot of durationFormat to unitOptions.[[Style]].
|
||||
(duration_format->*style_slot)(unit_options.style);
|
||||
|
|
|
@ -274,7 +274,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> string_list_from_iterable(VM& vm, Va
|
|||
}
|
||||
|
||||
// iii. Append nextValue to the end of the List list.
|
||||
list.append(next_value.as_string().deprecated_string());
|
||||
list.append(TRY(next_value.as_string().deprecated_string()));
|
||||
}
|
||||
} while (next != nullptr);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ListFormatConstructor::construct(Functio
|
|||
// 8. Let localeData be %ListFormat%.[[LocaleData]].
|
||||
|
||||
// 9. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]], requestedLocales, opt, %ListFormat%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, {});
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, {}));
|
||||
|
||||
// 10. Set listFormat.[[Locale]] to r.[[locale]].
|
||||
list_format->set_locale(move(result.locale));
|
||||
|
@ -80,13 +80,13 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ListFormatConstructor::construct(Functio
|
|||
auto type = TRY(get_option(vm, *options, vm.names.type, OptionType::String, { "conjunction"sv, "disjunction"sv, "unit"sv }, "conjunction"sv));
|
||||
|
||||
// 12. Set listFormat.[[Type]] to type.
|
||||
list_format->set_type(type.as_string().deprecated_string());
|
||||
list_format->set_type(TRY(type.as_string().deprecated_string()));
|
||||
|
||||
// 13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow" », "long").
|
||||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv }, "long"sv));
|
||||
|
||||
// 14. Set listFormat.[[Style]] to style.
|
||||
list_format->set_style(style.as_string().deprecated_string());
|
||||
list_format->set_style(TRY(style.as_string().deprecated_string()));
|
||||
|
||||
// Note: The remaining steps are skipped in favor of deferring to LibUnicode.
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ static ThrowCompletionOr<Optional<DeprecatedString>> get_string_option(VM& vm, O
|
|||
if (option.is_undefined())
|
||||
return Optional<DeprecatedString> {};
|
||||
|
||||
if (validator && !validator(option.as_string().deprecated_string()))
|
||||
if (validator && !validator(TRY(option.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, option, property);
|
||||
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 14.1.2 ApplyOptionsToTag ( tag, options ), https://tc39.es/ecma402/#sec-apply-options-to-tag
|
||||
|
|
|
@ -1604,7 +1604,7 @@ ThrowCompletionOr<MathematicalValue> to_intl_mathematical_value(VM& vm, Value va
|
|||
|
||||
// 3. If Type(primValue) is String,
|
||||
// a. Let str be primValue.
|
||||
auto const& string = primitive_value.as_string().deprecated_string();
|
||||
auto const& string = TRY(primitive_value.as_string().deprecated_string());
|
||||
|
||||
// Step 4 handled separately by the FIXME above.
|
||||
|
||||
|
|
|
@ -103,16 +103,16 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
// 7. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(numbering_system.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(numbering_system.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 8. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = numbering_system.as_string().deprecated_string();
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 9. Let localeData be %NumberFormat%.[[LocaleData]].
|
||||
// 10. Let r be ResolveLocale(%NumberFormat%.[[AvailableLocales]], requestedLocales, opt, %NumberFormat%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, NumberFormat::relevant_extension_keys());
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, NumberFormat::relevant_extension_keys()));
|
||||
|
||||
// 11. Set numberFormat.[[Locale]] to r.[[locale]].
|
||||
number_format.set_locale(move(result.locale));
|
||||
|
@ -176,7 +176,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
auto notation = TRY(get_option(vm, *options, vm.names.notation, OptionType::String, { "standard"sv, "scientific"sv, "engineering"sv, "compact"sv }, "standard"sv));
|
||||
|
||||
// 22. Set numberFormat.[[Notation]] to notation.
|
||||
number_format.set_notation(notation.as_string().deprecated_string());
|
||||
number_format.set_notation(TRY(notation.as_string().deprecated_string()));
|
||||
|
||||
// 23. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation).
|
||||
TRY(set_number_format_digit_options(vm, number_format, *options, default_min_fraction_digits, default_max_fraction_digits, number_format.notation()));
|
||||
|
@ -199,7 +199,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
auto trailing_zero_display = TRY(get_option(vm, *options, vm.names.trailingZeroDisplay, OptionType::String, { "auto"sv, "stripIfInteger"sv }, "auto"sv));
|
||||
|
||||
// 27. Set numberFormat.[[TrailingZeroDisplay]] to trailingZeroDisplay.
|
||||
number_format.set_trailing_zero_display(trailing_zero_display.as_string().deprecated_string());
|
||||
number_format.set_trailing_zero_display(TRY(trailing_zero_display.as_string().deprecated_string()));
|
||||
|
||||
// 28. Let compactDisplay be ? GetOption(options, "compactDisplay", "string", « "short", "long" », "short").
|
||||
auto compact_display = TRY(get_option(vm, *options, vm.names.compactDisplay, OptionType::String, { "short"sv, "long"sv }, "short"sv));
|
||||
|
@ -210,7 +210,7 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
// 30. If notation is "compact", then
|
||||
if (number_format.notation() == NumberFormat::Notation::Compact) {
|
||||
// a. Set numberFormat.[[CompactDisplay]] to compactDisplay.
|
||||
number_format.set_compact_display(compact_display.as_string().deprecated_string());
|
||||
number_format.set_compact_display(TRY(compact_display.as_string().deprecated_string()));
|
||||
|
||||
// b. Set defaultUseGrouping to "min2".
|
||||
default_use_grouping = "min2"sv;
|
||||
|
@ -226,13 +226,13 @@ ThrowCompletionOr<NumberFormat*> initialize_number_format(VM& vm, NumberFormat&
|
|||
auto sign_display = TRY(get_option(vm, *options, vm.names.signDisplay, OptionType::String, { "auto"sv, "never"sv, "always"sv, "exceptZero"sv, "negative"sv }, "auto"sv));
|
||||
|
||||
// 34. Set numberFormat.[[SignDisplay]] to signDisplay.
|
||||
number_format.set_sign_display(sign_display.as_string().deprecated_string());
|
||||
number_format.set_sign_display(TRY(sign_display.as_string().deprecated_string()));
|
||||
|
||||
// 35. Let roundingMode be ? GetOption(options, "roundingMode", "string", « "ceil", "floor", "expand", "trunc", "halfCeil", "halfFloor", "halfExpand", "halfTrunc", "halfEven" », "halfExpand").
|
||||
auto rounding_mode = TRY(get_option(vm, *options, vm.names.roundingMode, OptionType::String, { "ceil"sv, "floor"sv, "expand"sv, "trunc"sv, "halfCeil"sv, "halfFloor"sv, "halfExpand"sv, "halfTrunc"sv, "halfEven"sv }, "halfExpand"sv));
|
||||
|
||||
// 36. Set numberFormat.[[RoundingMode]] to roundingMode.
|
||||
number_format.set_rounding_mode(rounding_mode.as_string().deprecated_string());
|
||||
number_format.set_rounding_mode(TRY(rounding_mode.as_string().deprecated_string()));
|
||||
|
||||
// 37. Return numberFormat.
|
||||
return &number_format;
|
||||
|
@ -282,7 +282,7 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase
|
|||
bool need_fraction_digits = true;
|
||||
|
||||
// 14. If roundingPriority is "auto", then
|
||||
if (rounding_priority.as_string().deprecated_string() == "auto"sv) {
|
||||
if (TRY(rounding_priority.as_string().deprecated_string()) == "auto"sv) {
|
||||
// a. Set needSd to hasSd.
|
||||
need_significant_digits = has_significant_digits;
|
||||
|
||||
|
@ -358,12 +358,12 @@ ThrowCompletionOr<void> set_number_format_digit_options(VM& vm, NumberFormatBase
|
|||
// 17. If needSd is true or needFd is true, then
|
||||
if (need_significant_digits || need_fraction_digits) {
|
||||
// a. If roundingPriority is "morePrecision", then
|
||||
if (rounding_priority.as_string().deprecated_string() == "morePrecision"sv) {
|
||||
if (TRY(rounding_priority.as_string().deprecated_string()) == "morePrecision"sv) {
|
||||
// i. Set intlObj.[[RoundingType]] to morePrecision.
|
||||
intl_object.set_rounding_type(NumberFormatBase::RoundingType::MorePrecision);
|
||||
}
|
||||
// b. Else if roundingPriority is "lessPrecision", then
|
||||
else if (rounding_priority.as_string().deprecated_string() == "lessPrecision"sv) {
|
||||
else if (TRY(rounding_priority.as_string().deprecated_string()) == "lessPrecision"sv) {
|
||||
// i. Set intlObj.[[RoundingType]] to lessPrecision.
|
||||
intl_object.set_rounding_type(NumberFormatBase::RoundingType::LessPrecision);
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
auto style = TRY(get_option(vm, options, vm.names.style, OptionType::String, { "decimal"sv, "percent"sv, "currency"sv, "unit"sv }, "decimal"sv));
|
||||
|
||||
// 4. Set intlObj.[[Style]] to style.
|
||||
intl_object.set_style(style.as_string().deprecated_string());
|
||||
intl_object.set_style(TRY(style.as_string().deprecated_string()));
|
||||
|
||||
// 5. Let currency be ? GetOption(options, "currency", "string", undefined, undefined).
|
||||
auto currency = TRY(get_option(vm, options, vm.names.currency, OptionType::String, {}, Empty {}));
|
||||
|
@ -423,7 +423,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
}
|
||||
// 7. Else,
|
||||
// a. If ! IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception.
|
||||
else if (!is_well_formed_currency_code(currency.as_string().deprecated_string()))
|
||||
else if (!is_well_formed_currency_code(TRY(currency.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, currency, "currency"sv);
|
||||
|
||||
// 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay", "string", « "code", "symbol", "narrowSymbol", "name" », "symbol").
|
||||
|
@ -443,7 +443,7 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
}
|
||||
// 12. Else,
|
||||
// a. If ! IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception.
|
||||
else if (!is_well_formed_unit_identifier(unit.as_string().deprecated_string()))
|
||||
else if (!is_well_formed_unit_identifier(TRY(unit.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, unit, "unit"sv);
|
||||
|
||||
// 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short").
|
||||
|
@ -452,22 +452,22 @@ ThrowCompletionOr<void> set_number_format_unit_options(VM& vm, NumberFormat& int
|
|||
// 14. If style is "currency", then
|
||||
if (intl_object.style() == NumberFormat::Style::Currency) {
|
||||
// a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency.
|
||||
intl_object.set_currency(currency.as_string().deprecated_string().to_uppercase());
|
||||
intl_object.set_currency(TRY(currency.as_string().deprecated_string()).to_uppercase());
|
||||
|
||||
// c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay.
|
||||
intl_object.set_currency_display(currency_display.as_string().deprecated_string());
|
||||
intl_object.set_currency_display(TRY(currency_display.as_string().deprecated_string()));
|
||||
|
||||
// d. Set intlObj.[[CurrencySign]] to currencySign.
|
||||
intl_object.set_currency_sign(currency_sign.as_string().deprecated_string());
|
||||
intl_object.set_currency_sign(TRY(currency_sign.as_string().deprecated_string()));
|
||||
}
|
||||
|
||||
// 15. If style is "unit", then
|
||||
if (intl_object.style() == NumberFormat::Style::Unit) {
|
||||
// a. Set intlObj.[[Unit]] to unit.
|
||||
intl_object.set_unit(unit.as_string().deprecated_string());
|
||||
intl_object.set_unit(TRY(unit.as_string().deprecated_string()));
|
||||
|
||||
// b. Set intlObj.[[UnitDisplay]] to unitDisplay.
|
||||
intl_object.set_unit_display(unit_display.as_string().deprecated_string());
|
||||
intl_object.set_unit_display(TRY(unit_display.as_string().deprecated_string()));
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
@ -94,14 +94,14 @@ ThrowCompletionOr<PluralRules*> initialize_plural_rules(VM& vm, PluralRules& plu
|
|||
auto type = TRY(get_option(vm, *options, vm.names.type, OptionType::String, AK::Array { "cardinal"sv, "ordinal"sv }, "cardinal"sv));
|
||||
|
||||
// 7. Set pluralRules.[[Type]] to t.
|
||||
plural_rules.set_type(type.as_string().deprecated_string());
|
||||
plural_rules.set_type(TRY(type.as_string().deprecated_string()));
|
||||
|
||||
// 8. Perform ? SetNumberFormatDigitOptions(pluralRules, options, +0𝔽, 3𝔽, "standard").
|
||||
TRY(set_number_format_digit_options(vm, plural_rules, *options, 0, 3, NumberFormat::Notation::Standard));
|
||||
|
||||
// 9. Let localeData be %PluralRules%.[[LocaleData]].
|
||||
// 10. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, {});
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, {}));
|
||||
|
||||
// 11. Set pluralRules.[[Locale]] to r.[[locale]].
|
||||
plural_rules.set_locale(move(result.locale));
|
||||
|
|
|
@ -101,16 +101,16 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
|||
// 7. If numberingSystem is not undefined, then
|
||||
if (!numbering_system.is_undefined()) {
|
||||
// a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
|
||||
if (!::Locale::is_type_identifier(numbering_system.as_string().deprecated_string()))
|
||||
if (!::Locale::is_type_identifier(TRY(numbering_system.as_string().deprecated_string())))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, numbering_system, "numberingSystem"sv);
|
||||
|
||||
// 8. Set opt.[[nu]] to numberingSystem.
|
||||
opt.nu = numbering_system.as_string().deprecated_string();
|
||||
opt.nu = TRY(numbering_system.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 9. Let localeData be %RelativeTimeFormat%.[[LocaleData]].
|
||||
// 10. Let r be ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, RelativeTimeFormat::relevant_extension_keys());
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, RelativeTimeFormat::relevant_extension_keys()));
|
||||
|
||||
// 11. Let locale be r.[[locale]].
|
||||
auto locale = move(result.locale);
|
||||
|
@ -129,13 +129,13 @@ ThrowCompletionOr<RelativeTimeFormat*> initialize_relative_time_format(VM& vm, R
|
|||
auto style = TRY(get_option(vm, *options, vm.names.style, OptionType::String, { "long"sv, "short"sv, "narrow"sv }, "long"sv));
|
||||
|
||||
// 16. Set relativeTimeFormat.[[Style]] to style.
|
||||
relative_time_format.set_style(style.as_string().deprecated_string());
|
||||
relative_time_format.set_style(TRY(style.as_string().deprecated_string()));
|
||||
|
||||
// 17. Let numeric be ? GetOption(options, "numeric", "string", « "always", "auto" », "always").
|
||||
auto numeric = TRY(get_option(vm, *options, vm.names.numeric, OptionType::String, { "always"sv, "auto"sv }, "always"sv));
|
||||
|
||||
// 18. Set relativeTimeFormat.[[Numeric]] to numeric.
|
||||
relative_time_format.set_numeric(numeric.as_string().deprecated_string());
|
||||
relative_time_format.set_numeric(TRY(numeric.as_string().deprecated_string()));
|
||||
|
||||
// 19. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%NumberFormat%, « locale »).
|
||||
auto number_format = MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, locale)));
|
||||
|
|
|
@ -60,7 +60,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
|
|||
iterator->set_iterated_string_next_segment_code_unit_index(end_index);
|
||||
|
||||
// 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex).
|
||||
auto* segment_data = create_segment_data_object(vm, segmenter, string, start_index, end_index);
|
||||
auto segment_data = TRY(create_segment_data_object(vm, segmenter, string, start_index, end_index));
|
||||
|
||||
// 10. Return CreateIterResultObject(segmentData, false).
|
||||
return create_iterator_result_object(vm, segment_data, false);
|
||||
|
|
|
@ -45,7 +45,7 @@ StringView Segmenter::segmenter_granularity_string() const
|
|||
}
|
||||
|
||||
// 18.7.1 CreateSegmentDataObject ( segmenter, string, startIndex, endIndex ), https://tc39.es/ecma402/#sec-createsegmentdataobject
|
||||
Object* create_segment_data_object(VM& vm, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index)
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> create_segment_data_object(VM& vm, Segmenter const& segmenter, Utf16View const& string, double start_index, double end_index)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
|
@ -68,13 +68,13 @@ Object* create_segment_data_object(VM& vm, Segmenter const& segmenter, Utf16View
|
|||
auto segment = string.substring_view(start_index, end_index - start_index);
|
||||
|
||||
// 7. Perform ! CreateDataPropertyOrThrow(result, "segment", segment).
|
||||
MUST(result->create_data_property_or_throw(vm.names.segment, PrimitiveString::create(vm, segment)));
|
||||
MUST(result->create_data_property_or_throw(vm.names.segment, PrimitiveString::create(vm, TRY(Utf16String::create(vm, segment)))));
|
||||
|
||||
// 8. Perform ! CreateDataPropertyOrThrow(result, "index", 𝔽(startIndex)).
|
||||
MUST(result->create_data_property_or_throw(vm.names.index, Value(start_index)));
|
||||
|
||||
// 9. Perform ! CreateDataPropertyOrThrow(result, "input", string).
|
||||
MUST(result->create_data_property_or_throw(vm.names.input, PrimitiveString::create(vm, string)));
|
||||
MUST(result->create_data_property_or_throw(vm.names.input, PrimitiveString::create(vm, TRY(Utf16String::create(vm, string)))));
|
||||
|
||||
// 10. Let granularity be segmenter.[[SegmenterGranularity]].
|
||||
auto granularity = segmenter.segmenter_granularity();
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
SegmenterGranularity m_segmenter_granularity { SegmenterGranularity::Grapheme }; // [[SegmenterGranularity]]
|
||||
};
|
||||
|
||||
Object* create_segment_data_object(VM&, Segmenter const&, Utf16View const&, double start_index, double end_index);
|
||||
ThrowCompletionOr<NonnullGCPtr<Object>> create_segment_data_object(VM&, Segmenter const&, Utf16View const&, double start_index, double end_index);
|
||||
enum class Direction {
|
||||
Before,
|
||||
After,
|
||||
|
|
|
@ -71,7 +71,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> SegmenterConstructor::construct(Function
|
|||
// 9. Let localeData be %Segmenter%.[[LocaleData]].
|
||||
|
||||
// 10. Let r be ResolveLocale(%Segmenter%.[[AvailableLocales]], requestedLocales, opt, %Segmenter%.[[RelevantExtensionKeys]], localeData).
|
||||
auto result = resolve_locale(requested_locales, opt, {});
|
||||
auto result = TRY(resolve_locale(requested_locales, opt, {}));
|
||||
|
||||
// 11. Set segmenter.[[Locale]] to r.[[locale]].
|
||||
segmenter->set_locale(move(result.locale));
|
||||
|
@ -80,7 +80,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> SegmenterConstructor::construct(Function
|
|||
auto granularity = TRY(get_option(vm, *options, vm.names.granularity, OptionType::String, { "grapheme"sv, "word"sv, "sentence"sv }, "grapheme"sv));
|
||||
|
||||
// 13. Set segmenter.[[SegmenterGranularity]] to granularity.
|
||||
segmenter->set_segmenter_granularity(granularity.as_string().deprecated_string());
|
||||
segmenter->set_segmenter_granularity(TRY(granularity.as_string().deprecated_string()));
|
||||
|
||||
// 14. Return segmenter.
|
||||
return segmenter;
|
||||
|
|
|
@ -58,7 +58,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing)
|
|||
auto end_index = find_boundary(segmenter, string, n, Direction::After, segments->boundaries_cache());
|
||||
|
||||
// 10. Return ! CreateSegmentDataObject(segmenter, string, startIndex, endIndex).
|
||||
return create_segment_data_object(vm, segmenter, string, start_index, end_index);
|
||||
return TRY(create_segment_data_object(vm, segmenter, string, start_index, end_index));
|
||||
}
|
||||
|
||||
// 18.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator
|
||||
|
|
|
@ -63,7 +63,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
|
|||
auto replacer_value = TRY(replacer_object.get(i));
|
||||
DeprecatedString item;
|
||||
if (replacer_value.is_string()) {
|
||||
item = replacer_value.as_string().deprecated_string();
|
||||
item = TRY(replacer_value.as_string().deprecated_string());
|
||||
} else if (replacer_value.is_number()) {
|
||||
item = MUST(replacer_value.to_string(vm));
|
||||
} else if (replacer_value.is_object()) {
|
||||
|
@ -93,7 +93,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::stringify_impl(VM& vm, Value val
|
|||
space_mv = min(10, space_mv);
|
||||
state.gap = space_mv < 1 ? DeprecatedString::empty() : DeprecatedString::repeated(' ', space_mv);
|
||||
} else if (space.is_string()) {
|
||||
auto string = space.as_string().deprecated_string();
|
||||
auto string = TRY(space.as_string().deprecated_string());
|
||||
if (string.length() <= 10)
|
||||
state.gap = string;
|
||||
else
|
||||
|
@ -185,7 +185,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_property(VM& vm,
|
|||
|
||||
// 8. If Type(value) is String, return QuoteJSONString(value).
|
||||
if (value.is_string())
|
||||
return quote_json_string(value.as_string().deprecated_string());
|
||||
return quote_json_string(TRY(value.as_string().deprecated_string()));
|
||||
|
||||
// 9. If Type(value) is Number, then
|
||||
if (value.is_number()) {
|
||||
|
@ -250,7 +250,7 @@ ThrowCompletionOr<DeprecatedString> JSONObject::serialize_json_object(VM& vm, St
|
|||
} else {
|
||||
auto property_list = TRY(object.enumerable_own_property_names(PropertyKind::Key));
|
||||
for (auto& property : property_list)
|
||||
TRY(process_property(property.as_string().deprecated_string()));
|
||||
TRY(process_property(TRY(property.as_string().deprecated_string())));
|
||||
}
|
||||
StringBuilder builder;
|
||||
if (property_strings.is_empty()) {
|
||||
|
@ -473,7 +473,7 @@ ThrowCompletionOr<Value> JSONObject::internalize_json_property(VM& vm, Object* h
|
|||
} else {
|
||||
auto property_list = TRY(value_object.enumerable_own_property_names(Object::PropertyKind::Key));
|
||||
for (auto& property_key : property_list)
|
||||
TRY(process_property(property_key.as_string().deprecated_string()));
|
||||
TRY(process_property(TRY(property_key.as_string().deprecated_string())));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1267,7 +1267,7 @@ Optional<Completion> Object::enumerate_object_properties(Function<Optional<Compl
|
|||
for (auto& key : own_keys) {
|
||||
if (!key.is_string())
|
||||
continue;
|
||||
FlyString property_key = key.as_string().deprecated_string();
|
||||
FlyString property_key = TRY(key.as_string().deprecated_string());
|
||||
if (visited.contains(property_key))
|
||||
continue;
|
||||
auto descriptor = TRY(target->internal_get_own_property(property_key));
|
||||
|
|
|
@ -125,7 +125,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string)
|
|||
if (!to_string_tag.is_string())
|
||||
tag = move(builtin_tag);
|
||||
else
|
||||
tag = to_string_tag.as_string().deprecated_string();
|
||||
tag = TRY(to_string_tag.as_string().deprecated_string());
|
||||
|
||||
// 17. Return the string-concatenation of "[object ", tag, and "]".
|
||||
return PrimitiveString::create(vm, DeprecatedString::formatted("[object {}]", tag));
|
||||
|
|
|
@ -25,20 +25,19 @@ PrimitiveString::PrimitiveString(PrimitiveString& lhs, PrimitiveString& rhs)
|
|||
}
|
||||
|
||||
PrimitiveString::PrimitiveString(DeprecatedString string)
|
||||
: m_has_utf8_string(true)
|
||||
, m_utf8_string(move(string))
|
||||
: m_utf8_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveString::PrimitiveString(Utf16String string)
|
||||
: m_has_utf16_string(true)
|
||||
, m_utf16_string(move(string))
|
||||
: m_utf16_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveString::~PrimitiveString()
|
||||
{
|
||||
vm().string_cache().remove(m_utf8_string);
|
||||
if (has_utf8_string())
|
||||
vm().string_cache().remove(*m_utf8_string);
|
||||
}
|
||||
|
||||
void PrimitiveString::visit_edges(Cell::Visitor& visitor)
|
||||
|
@ -57,62 +56,60 @@ bool PrimitiveString::is_empty() const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (m_has_utf16_string)
|
||||
return m_utf16_string.is_empty();
|
||||
if (m_has_utf8_string)
|
||||
return m_utf8_string.is_empty();
|
||||
if (has_utf16_string())
|
||||
return m_utf16_string->is_empty();
|
||||
if (has_utf8_string())
|
||||
return m_utf8_string->is_empty();
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
DeprecatedString const& PrimitiveString::deprecated_string() const
|
||||
ThrowCompletionOr<DeprecatedString const&> PrimitiveString::deprecated_string() const
|
||||
{
|
||||
resolve_rope_if_needed();
|
||||
if (!m_has_utf8_string) {
|
||||
// FIXME: Propagate this error.
|
||||
m_utf8_string = MUST(m_utf16_string.to_utf8(vm()));
|
||||
m_has_utf8_string = true;
|
||||
TRY(resolve_rope_if_needed());
|
||||
|
||||
if (!has_utf8_string()) {
|
||||
VERIFY(has_utf16_string());
|
||||
m_utf8_string = TRY(m_utf16_string->to_utf8(vm()));
|
||||
}
|
||||
return m_utf8_string;
|
||||
|
||||
return *m_utf8_string;
|
||||
}
|
||||
|
||||
Utf16String const& PrimitiveString::utf16_string() const
|
||||
ThrowCompletionOr<Utf16String const&> PrimitiveString::utf16_string() const
|
||||
{
|
||||
resolve_rope_if_needed();
|
||||
if (!m_has_utf16_string) {
|
||||
m_utf16_string = Utf16String(m_utf8_string);
|
||||
m_has_utf16_string = true;
|
||||
TRY(resolve_rope_if_needed());
|
||||
|
||||
if (!has_utf16_string()) {
|
||||
VERIFY(has_utf8_string());
|
||||
m_utf16_string = TRY(Utf16String::create(vm(), *m_utf8_string));
|
||||
}
|
||||
return m_utf16_string;
|
||||
|
||||
return *m_utf16_string;
|
||||
}
|
||||
|
||||
Utf16View PrimitiveString::utf16_string_view() const
|
||||
ThrowCompletionOr<Utf16View> PrimitiveString::utf16_string_view() const
|
||||
{
|
||||
return utf16_string().view();
|
||||
return TRY(utf16_string()).view();
|
||||
}
|
||||
|
||||
Optional<Value> PrimitiveString::get(VM& vm, PropertyKey const& property_key) const
|
||||
ThrowCompletionOr<Optional<Value>> PrimitiveString::get(VM& vm, PropertyKey const& property_key) const
|
||||
{
|
||||
if (property_key.is_symbol())
|
||||
return {};
|
||||
return Optional<Value> {};
|
||||
if (property_key.is_string()) {
|
||||
if (property_key.as_string() == vm.names.length.as_string()) {
|
||||
auto length = utf16_string().length_in_code_units();
|
||||
auto length = TRY(utf16_string()).length_in_code_units();
|
||||
return Value(static_cast<double>(length));
|
||||
}
|
||||
}
|
||||
auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
|
||||
if (!index.is_index())
|
||||
return {};
|
||||
auto str = utf16_string_view();
|
||||
return Optional<Value> {};
|
||||
auto str = TRY(utf16_string_view());
|
||||
auto length = str.length_in_code_units();
|
||||
if (length <= index.as_index())
|
||||
return {};
|
||||
return create(vm, str.substring_view(index.as_index(), 1));
|
||||
}
|
||||
|
||||
NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, Utf16View const& view)
|
||||
{
|
||||
return create(vm, Utf16String(view));
|
||||
return Optional<Value> {};
|
||||
return create(vm, TRY(Utf16String::create(vm, str.substring_view(index.as_index(), 1))));
|
||||
}
|
||||
|
||||
NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, Utf16String string)
|
||||
|
@ -170,28 +167,29 @@ NonnullGCPtr<PrimitiveString> PrimitiveString::create(VM& vm, PrimitiveString& l
|
|||
return vm.heap().allocate_without_realm<PrimitiveString>(lhs, rhs);
|
||||
}
|
||||
|
||||
void PrimitiveString::resolve_rope_if_needed() const
|
||||
ThrowCompletionOr<void> PrimitiveString::resolve_rope_if_needed() const
|
||||
{
|
||||
if (!m_is_rope)
|
||||
return;
|
||||
return {};
|
||||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// NOTE: Special case for two concatenated UTF-16 strings.
|
||||
// This is here as an optimization, although I'm unsure how valuable it is.
|
||||
if (m_lhs->has_utf16_string() && m_rhs->has_utf16_string()) {
|
||||
auto const& lhs_string = m_lhs->utf16_string();
|
||||
auto const& rhs_string = m_rhs->utf16_string();
|
||||
auto const& lhs_string = TRY(m_lhs->utf16_string());
|
||||
auto const& rhs_string = TRY(m_rhs->utf16_string());
|
||||
|
||||
Utf16Data combined;
|
||||
combined.ensure_capacity(lhs_string.length_in_code_units() + rhs_string.length_in_code_units());
|
||||
combined.extend(lhs_string.string());
|
||||
combined.extend(rhs_string.string());
|
||||
|
||||
m_utf16_string = Utf16String(move(combined));
|
||||
m_has_utf16_string = true;
|
||||
m_utf16_string = TRY(Utf16String::create(vm, move(combined)));
|
||||
m_is_rope = false;
|
||||
m_lhs = nullptr;
|
||||
m_rhs = nullptr;
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
// This vector will hold all the pieces of the rope that need to be assembled
|
||||
|
@ -221,21 +219,21 @@ void PrimitiveString::resolve_rope_if_needed() const
|
|||
for (auto const* current : pieces) {
|
||||
if (!previous) {
|
||||
// This is the very first piece, just append it and continue.
|
||||
builder.append(current->deprecated_string());
|
||||
builder.append(TRY(current->deprecated_string()));
|
||||
previous = current;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the UTF-8 representations for both strings.
|
||||
auto const& previous_string_as_utf8 = previous->deprecated_string();
|
||||
auto const& current_string_as_utf8 = current->deprecated_string();
|
||||
auto const& previous_string_as_utf8 = TRY(previous->deprecated_string());
|
||||
auto const& current_string_as_utf8 = TRY(current->deprecated_string());
|
||||
|
||||
// NOTE: Now we need to look at the end of the previous string and the start
|
||||
// of the current string, to see if they should be combined into a surrogate.
|
||||
|
||||
// Surrogates encoded as UTF-8 are 3 bytes.
|
||||
if ((previous_string_as_utf8.length() < 3) || (current_string_as_utf8.length() < 3)) {
|
||||
builder.append(current->deprecated_string());
|
||||
builder.append(TRY(current->deprecated_string()));
|
||||
previous = current;
|
||||
continue;
|
||||
}
|
||||
|
@ -243,7 +241,7 @@ void PrimitiveString::resolve_rope_if_needed() const
|
|||
// Might the previous string end with a UTF-8 encoded surrogate?
|
||||
if ((static_cast<u8>(previous_string_as_utf8[previous_string_as_utf8.length() - 3]) & 0xf0) != 0xe0) {
|
||||
// If not, just append the current string and continue.
|
||||
builder.append(current->deprecated_string());
|
||||
builder.append(TRY(current->deprecated_string()));
|
||||
previous = current;
|
||||
continue;
|
||||
}
|
||||
|
@ -251,7 +249,7 @@ void PrimitiveString::resolve_rope_if_needed() const
|
|||
// Might the current string begin with a UTF-8 encoded surrogate?
|
||||
if ((static_cast<u8>(current_string_as_utf8[0]) & 0xf0) != 0xe0) {
|
||||
// If not, just append the current string and continue.
|
||||
builder.append(current->deprecated_string());
|
||||
builder.append(TRY(current->deprecated_string()));
|
||||
previous = current;
|
||||
continue;
|
||||
}
|
||||
|
@ -260,7 +258,7 @@ void PrimitiveString::resolve_rope_if_needed() const
|
|||
auto low_surrogate = *Utf8View(current_string_as_utf8).begin();
|
||||
|
||||
if (!Utf16View::is_high_surrogate(high_surrogate) || !Utf16View::is_low_surrogate(low_surrogate)) {
|
||||
builder.append(current->deprecated_string());
|
||||
builder.append(TRY(current->deprecated_string()));
|
||||
previous = current;
|
||||
continue;
|
||||
}
|
||||
|
@ -275,10 +273,10 @@ void PrimitiveString::resolve_rope_if_needed() const
|
|||
}
|
||||
|
||||
m_utf8_string = builder.to_deprecated_string();
|
||||
m_has_utf8_string = true;
|
||||
m_is_rope = false;
|
||||
m_lhs = nullptr;
|
||||
m_rhs = nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/Utf16String.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
||||
|
@ -20,7 +22,6 @@ class PrimitiveString final : public Cell {
|
|||
JS_CELL(PrimitiveString, Cell);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static NonnullGCPtr<PrimitiveString> create(VM&, Utf16View const&);
|
||||
[[nodiscard]] static NonnullGCPtr<PrimitiveString> create(VM&, Utf16String);
|
||||
[[nodiscard]] static NonnullGCPtr<PrimitiveString> create(VM&, DeprecatedString);
|
||||
[[nodiscard]] static NonnullGCPtr<PrimitiveString> create(VM&, PrimitiveString&, PrimitiveString&);
|
||||
|
@ -31,15 +32,16 @@ public:
|
|||
PrimitiveString& operator=(PrimitiveString const&) = delete;
|
||||
|
||||
bool is_empty() const;
|
||||
u32 hash() const;
|
||||
|
||||
DeprecatedString const& deprecated_string() const;
|
||||
bool has_utf8_string() const { return m_has_utf8_string; }
|
||||
ThrowCompletionOr<DeprecatedString const&> deprecated_string() const;
|
||||
bool has_utf8_string() const { return m_utf8_string.has_value(); }
|
||||
|
||||
Utf16String const& utf16_string() const;
|
||||
Utf16View utf16_string_view() const;
|
||||
bool has_utf16_string() const { return m_has_utf16_string; }
|
||||
ThrowCompletionOr<Utf16String const&> utf16_string() const;
|
||||
ThrowCompletionOr<Utf16View> utf16_string_view() const;
|
||||
bool has_utf16_string() const { return m_utf16_string.has_value(); }
|
||||
|
||||
Optional<Value> get(VM&, PropertyKey const&) const;
|
||||
ThrowCompletionOr<Optional<Value>> get(VM&, PropertyKey const&) const;
|
||||
|
||||
private:
|
||||
explicit PrimitiveString(PrimitiveString&, PrimitiveString&);
|
||||
|
@ -48,18 +50,15 @@ private:
|
|||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
void resolve_rope_if_needed() const;
|
||||
ThrowCompletionOr<void> resolve_rope_if_needed() const;
|
||||
|
||||
mutable bool m_is_rope { false };
|
||||
mutable bool m_has_utf8_string { false };
|
||||
mutable bool m_has_utf16_string { false };
|
||||
|
||||
mutable PrimitiveString* m_lhs { nullptr };
|
||||
mutable PrimitiveString* m_rhs { nullptr };
|
||||
|
||||
mutable DeprecatedString m_utf8_string;
|
||||
|
||||
mutable Utf16String m_utf16_string;
|
||||
mutable Optional<DeprecatedString> m_utf8_string;
|
||||
mutable Optional<Utf16String> m_utf16_string;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ ThrowCompletionOr<Value> Reference::get_value(VM& vm) const
|
|||
// OPTIMIZATION: For various primitives we can avoid actually creating a new object for them.
|
||||
Object* base_obj = nullptr;
|
||||
if (m_base_value.is_string()) {
|
||||
auto string_value = m_base_value.as_string().get(vm, m_name);
|
||||
auto string_value = TRY(m_base_value.as_string().get(vm, m_name));
|
||||
if (string_value.has_value())
|
||||
return *string_value;
|
||||
base_obj = realm.intrinsics().string_prototype();
|
||||
|
|
|
@ -68,7 +68,7 @@ ThrowCompletionOr<void> set_legacy_regexp_static_property(VM& vm, RegExpConstruc
|
|||
}
|
||||
|
||||
// UpdateLegacyRegExpStaticProperties ( C, S, startIndex, endIndex, capturedValues ), https://github.com/tc39/proposal-regexp-legacy-features#updatelegacyregexpstaticproperties--c-s-startindex-endindex-capturedvalues-
|
||||
void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf16String const& string, size_t start_index, size_t end_index, Vector<Utf16String> const& captured_values)
|
||||
ThrowCompletionOr<void> update_legacy_regexp_static_properties(VM& vm, RegExpConstructor& constructor, Utf16String const& string, size_t start_index, size_t end_index, Vector<Utf16String> const& captured_values)
|
||||
{
|
||||
auto& legacy_static_properties = constructor.legacy_static_properties();
|
||||
|
||||
|
@ -92,7 +92,7 @@ void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf1
|
|||
|
||||
// 8. Set the value of C’s [[RegExpLastMatch]] internal slot to a String whose length is endIndex - startIndex and containing the code units from S with indices startIndex through endIndex - 1, in ascending order.
|
||||
auto last_match = string.view().substring_view(start_index, end_index - start_index);
|
||||
legacy_static_properties.set_last_match(Utf16String(last_match));
|
||||
legacy_static_properties.set_last_match(TRY(Utf16String::create(vm, last_match)));
|
||||
|
||||
// 9. If n > 0, set the value of C’s [[RegExpLastParen]] internal slot to the last element of capturedValues.
|
||||
if (group_count > 0) {
|
||||
|
@ -101,49 +101,45 @@ void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf1
|
|||
}
|
||||
// 10. Else, set the value of C’s [[RegExpLastParen]] internal slot to the empty String.
|
||||
else {
|
||||
legacy_static_properties.set_last_paren(Utf16String(""sv));
|
||||
legacy_static_properties.set_last_paren(TRY(Utf16String::create(vm)));
|
||||
}
|
||||
|
||||
// 11. Set the value of C’s [[RegExpLeftContext]] internal slot to a String whose length is startIndex and containing the code units from S with indices 0 through startIndex - 1, in ascending order.
|
||||
auto left_context = string.view().substring_view(0, start_index);
|
||||
legacy_static_properties.set_left_context(Utf16String(left_context));
|
||||
legacy_static_properties.set_left_context(TRY(Utf16String::create(vm, left_context)));
|
||||
|
||||
// 12. Set the value of C’s [[RegExpRightContext]] internal slot to a String whose length is len - endIndex and containing the code units from S with indices endIndex through len - 1, in ascending order.
|
||||
auto right_context = string.view().substring_view(end_index, len - end_index);
|
||||
legacy_static_properties.set_right_context(Utf16String(right_context));
|
||||
legacy_static_properties.set_right_context(TRY(Utf16String::create(vm, right_context)));
|
||||
|
||||
// 13. For each integer i such that 1 ≤ i ≤ 9
|
||||
for (size_t i = 1; i <= 9; i++) {
|
||||
auto value = Utf16String(""sv);
|
||||
// If i ≤ n, set the value of C’s [[RegExpPareni]] internal slot to the ith element of capturedValues.
|
||||
if (i <= group_count) {
|
||||
value = captured_values[i - 1];
|
||||
}
|
||||
// Else, set the value of C’s [[RegExpPareni]] internal slot to the empty String.
|
||||
else {
|
||||
// It's already an empty string
|
||||
}
|
||||
// i. If i ≤ n, set the value of C’s [[RegExpPareni]] internal slot to the ith element of capturedValues.
|
||||
// ii. Else, set the value of C’s [[RegExpPareni]] internal slot to the empty String.
|
||||
auto value = (i <= group_count) ? captured_values[i - 1] : TRY(Utf16String::create(vm));
|
||||
|
||||
if (i == 1) {
|
||||
legacy_static_properties.set_$1(Utf16String(value));
|
||||
legacy_static_properties.set_$1(move(value));
|
||||
} else if (i == 2) {
|
||||
legacy_static_properties.set_$2(Utf16String(value));
|
||||
legacy_static_properties.set_$2(move(value));
|
||||
} else if (i == 3) {
|
||||
legacy_static_properties.set_$3(Utf16String(value));
|
||||
legacy_static_properties.set_$3(move(value));
|
||||
} else if (i == 4) {
|
||||
legacy_static_properties.set_$4(Utf16String(value));
|
||||
legacy_static_properties.set_$4(move(value));
|
||||
} else if (i == 5) {
|
||||
legacy_static_properties.set_$5(Utf16String(value));
|
||||
legacy_static_properties.set_$5(move(value));
|
||||
} else if (i == 6) {
|
||||
legacy_static_properties.set_$6(Utf16String(value));
|
||||
legacy_static_properties.set_$6(move(value));
|
||||
} else if (i == 7) {
|
||||
legacy_static_properties.set_$7(Utf16String(value));
|
||||
legacy_static_properties.set_$7(move(value));
|
||||
} else if (i == 8) {
|
||||
legacy_static_properties.set_$8(Utf16String(value));
|
||||
legacy_static_properties.set_$8(move(value));
|
||||
} else if (i == 9) {
|
||||
legacy_static_properties.set_$9(Utf16String(value));
|
||||
legacy_static_properties.set_$9(move(value));
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// InvalidateLegacyRegExpStaticProperties ( C ), https://github.com/tc39/proposal-regexp-legacy-features#invalidatelegacyregexpstaticproperties--c
|
||||
|
|
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
ThrowCompletionOr<void> set_legacy_regexp_static_property(VM& vm, RegExpConstructor& constructor, Value this_value, void (RegExpLegacyStaticProperties::*property_setter)(Utf16String), Value value);
|
||||
ThrowCompletionOr<Value> get_legacy_regexp_static_property(VM& vm, RegExpConstructor& constructor, Value this_value, Optional<Utf16String> const& (RegExpLegacyStaticProperties::*property_getter)() const);
|
||||
void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf16String const& string, size_t start_index, size_t end_index, Vector<Utf16String> const& captured_values);
|
||||
ThrowCompletionOr<void> update_legacy_regexp_static_properties(VM& vm, RegExpConstructor& constructor, Utf16String const& string, size_t start_index, size_t end_index, Vector<Utf16String> const& captured_values);
|
||||
void invalidate_legacy_regexp_static_properties(RegExpConstructor& constructor);
|
||||
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
|
|||
|
||||
// 27. Let matchedValue be ! GetMatchString(S, match).
|
||||
// 28. Perform ! CreateDataPropertyOrThrow(A, "0", matchedValue).
|
||||
MUST(array->create_data_property_or_throw(0, PrimitiveString::create(vm, match.view.u16_view())));
|
||||
MUST(array->create_data_property_or_throw(0, PrimitiveString::create(vm, TRY(Utf16String::create(vm, match.view.u16_view())))));
|
||||
|
||||
// 29. If R contains any GroupName, then
|
||||
// a. Let groups be OrdinaryObjectCreate(null).
|
||||
|
@ -300,7 +300,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
|
|||
// ii. Append undefined to indices.
|
||||
indices.append({});
|
||||
// iii. Append capture to indices.
|
||||
captured_values.append(Utf16String(""sv));
|
||||
captured_values.append(TRY(Utf16String::create(vm)));
|
||||
}
|
||||
// c. Else,
|
||||
else {
|
||||
|
@ -311,7 +311,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
|
|||
// 2. Set captureEnd to ! GetStringIndex(S, Input, captureEnd).
|
||||
// iv. Let capture be the Match { [[StartIndex]]: captureStart, [[EndIndex]: captureEnd }.
|
||||
// v. Let capturedValue be ! GetMatchString(S, capture).
|
||||
auto capture_as_utf16_string = Utf16String(capture.view.u16_view());
|
||||
auto capture_as_utf16_string = TRY(Utf16String::create(vm, capture.view.u16_view()));
|
||||
captured_value = PrimitiveString::create(vm, capture_as_utf16_string);
|
||||
// vi. Append capture to indices.
|
||||
indices.append(Match::create(capture));
|
||||
|
@ -351,7 +351,7 @@ static ThrowCompletionOr<Value> regexp_builtin_exec(VM& vm, RegExpObject& regexp
|
|||
if (regexp_object.legacy_features_enabled()) {
|
||||
// a. Perform UpdateLegacyRegExpStaticProperties(%RegExp%, S, lastIndex, e, capturedValues).
|
||||
auto* regexp_constructor = realm.intrinsics().regexp_constructor();
|
||||
update_legacy_regexp_static_properties(*regexp_constructor, string, match_indices.start_index, match_indices.end_index, captured_values);
|
||||
TRY(update_legacy_regexp_static_properties(vm, *regexp_constructor, string, match_indices.start_index, match_indices.end_index, captured_values));
|
||||
}
|
||||
// ii. Else,
|
||||
else {
|
||||
|
@ -998,7 +998,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
auto substring = string.substring_view(last_match_end, next_search_from - last_match_end);
|
||||
|
||||
// 2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, substring)));
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, TRY(Utf16String::create(vm, substring)))));
|
||||
|
||||
// 3. Set lengthA to lengthA + 1.
|
||||
++array_length;
|
||||
|
@ -1045,7 +1045,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
auto substring = string.substring_view(last_match_end);
|
||||
|
||||
// 21. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, substring)));
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, TRY(Utf16String::create(vm, substring)))));
|
||||
|
||||
// 22. Return A.
|
||||
return array;
|
||||
|
|
|
@ -86,7 +86,7 @@ ThrowCompletionOr<void> copy_name_and_length(VM& vm, FunctionObject& function, F
|
|||
target_name = PrimitiveString::create(vm, DeprecatedString::empty());
|
||||
|
||||
// 8. Perform SetFunctionName(F, targetName, prefix).
|
||||
function.set_function_name({ target_name.as_string().deprecated_string() }, move(prefix));
|
||||
function.set_function_name({ TRY(target_name.as_string().deprecated_string()) }, move(prefix));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, DeprecatedString spec
|
|||
// NOTE: Even though the spec tells us to use %ThrowTypeError%, it's not observable if we actually do.
|
||||
// Throw a nicer TypeError forwarding the import error message instead (we know the argument is an Error object).
|
||||
auto throw_type_error = NativeFunction::create(realm, {}, [](auto& vm) -> ThrowCompletionOr<Value> {
|
||||
return vm.template throw_completion<TypeError>(vm.argument(0).as_object().get_without_side_effects(vm.names.message).as_string().deprecated_string());
|
||||
return vm.template throw_completion<TypeError>(TRY(vm.argument(0).as_object().get_without_side_effects(vm.names.message).as_string().deprecated_string()));
|
||||
});
|
||||
|
||||
// 13. Return PerformPromiseThen(innerCapability.[[Promise]], onFulfilled, callerRealm.[[Intrinsics]].[[%ThrowTypeError%]], promiseCapability).
|
||||
|
|
|
@ -49,7 +49,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::evaluate)
|
|||
auto& eval_realm = object->shadow_realm();
|
||||
|
||||
// 6. Return ? PerformShadowRealmEval(sourceText, callerRealm, evalRealm).
|
||||
return perform_shadow_realm_eval(vm, source_text.as_string().deprecated_string(), *caller_realm, eval_realm);
|
||||
return perform_shadow_realm_eval(vm, TRY(source_text.as_string().deprecated_string()), *caller_realm, eval_realm);
|
||||
}
|
||||
|
||||
// 3.4.2 ShadowRealm.prototype.importValue ( specifier, exportName ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype.importvalue
|
||||
|
@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(ShadowRealmPrototype::import_value)
|
|||
auto& eval_context = object->execution_context();
|
||||
|
||||
// 8. Return ? ShadowRealmImportValue(specifierString, exportNameString, callerRealm, evalRealm, evalContext).
|
||||
return shadow_realm_import_value(vm, move(specifier_string), export_name.as_string().deprecated_string(), *caller_realm, eval_realm, eval_context);
|
||||
return shadow_realm_import_value(vm, move(specifier_string), TRY(export_name.as_string().deprecated_string()), *caller_realm, eval_realm, eval_context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::from_char_code)
|
|||
for (size_t i = 0; i < vm.argument_count(); ++i)
|
||||
string.append(TRY(vm.argument(i).to_u16(vm)));
|
||||
|
||||
return PrimitiveString::create(vm, Utf16String(move(string)));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, move(string))));
|
||||
}
|
||||
|
||||
// 22.1.2.2 String.fromCodePoint ( ...codePoints ), https://tc39.es/ecma262/#sec-string.fromcodepoint
|
||||
|
@ -126,7 +126,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringConstructor::from_code_point)
|
|||
TRY_OR_THROW_OOM(vm, code_point_to_utf16(string, static_cast<u32>(code_point)));
|
||||
}
|
||||
|
||||
return PrimitiveString::create(vm, Utf16String(move(string)));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, move(string))));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,9 @@ void StringObject::initialize(Realm& realm)
|
|||
{
|
||||
auto& vm = this->vm();
|
||||
Object::initialize(realm);
|
||||
define_direct_property(vm.names.length, Value(m_string.utf16_string_view().length_in_code_units()), 0);
|
||||
|
||||
// FIXME: Propagate this error.
|
||||
define_direct_property(vm.names.length, Value(MUST(m_string.utf16_string_view()).length_in_code_units()), 0);
|
||||
}
|
||||
|
||||
void StringObject::visit_edges(Cell::Visitor& visitor)
|
||||
|
@ -40,7 +42,7 @@ void StringObject::visit_edges(Cell::Visitor& visitor)
|
|||
}
|
||||
|
||||
// 10.4.3.5 StringGetOwnProperty ( S, P ), https://tc39.es/ecma262/#sec-stringgetownproperty
|
||||
static Optional<PropertyDescriptor> string_get_own_property(StringObject const& string, PropertyKey const& property_key)
|
||||
static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(StringObject const& string, PropertyKey const& property_key)
|
||||
{
|
||||
VERIFY(property_key.is_valid());
|
||||
|
||||
|
@ -48,7 +50,7 @@ static Optional<PropertyDescriptor> string_get_own_property(StringObject const&
|
|||
// NOTE: The spec only uses string and symbol keys, and later coerces to numbers -
|
||||
// this is not the case for PropertyKey, so '!property_key.is_string()' would be wrong.
|
||||
if (property_key.is_symbol())
|
||||
return {};
|
||||
return Optional<PropertyDescriptor> {};
|
||||
|
||||
// 2. Let index be CanonicalNumericIndexString(P).
|
||||
auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
|
||||
|
@ -57,21 +59,21 @@ static Optional<PropertyDescriptor> string_get_own_property(StringObject const&
|
|||
// 4. If IsIntegralNumber(index) is false, return undefined.
|
||||
// 5. If index is -0𝔽, return undefined.
|
||||
if (!index.is_index())
|
||||
return {};
|
||||
return Optional<PropertyDescriptor> {};
|
||||
|
||||
// 6. Let str be S.[[StringData]].
|
||||
// 7. Assert: Type(str) is String.
|
||||
auto str = string.primitive_string().utf16_string_view();
|
||||
auto str = TRY(string.primitive_string().utf16_string_view());
|
||||
|
||||
// 8. Let len be the length of str.
|
||||
auto length = str.length_in_code_units();
|
||||
|
||||
// 9. If ℝ(index) < 0 or len ≤ ℝ(index), return undefined.
|
||||
if (length <= index.as_index())
|
||||
return {};
|
||||
return Optional<PropertyDescriptor> {};
|
||||
|
||||
// 10. Let resultStr be the String value of length 1, containing one code unit from str, specifically the code unit at index ℝ(index).
|
||||
auto result_str = PrimitiveString::create(string.vm(), str.substring_view(index.as_index(), 1));
|
||||
auto result_str = PrimitiveString::create(string.vm(), TRY(Utf16String::create(string.vm(), str.substring_view(index.as_index(), 1))));
|
||||
|
||||
// 11. Return the PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }.
|
||||
return PropertyDescriptor {
|
||||
|
@ -104,7 +106,7 @@ ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey c
|
|||
VERIFY(property_key.is_valid());
|
||||
|
||||
// 1. Let stringDesc be StringGetOwnProperty(S, P).
|
||||
auto string_descriptor = string_get_own_property(*this, property_key);
|
||||
auto string_descriptor = TRY(string_get_own_property(*this, property_key));
|
||||
|
||||
// 2. If stringDesc is not undefined, then
|
||||
if (string_descriptor.has_value()) {
|
||||
|
@ -128,7 +130,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
|
|||
auto keys = MarkedVector<Value> { heap() };
|
||||
|
||||
// 2. Let str be O.[[StringData]].
|
||||
auto str = m_string.utf16_string_view();
|
||||
auto str = TRY(m_string.utf16_string_view());
|
||||
|
||||
// 3. Assert: Type(str) is String.
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
|
|||
return js_undefined();
|
||||
|
||||
// 7. Return ? Get(O, ! ToString(𝔽(k))).
|
||||
return PrimitiveString::create(vm, string.substring_view(index.value(), 1));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, string.substring_view(index.value(), 1))));
|
||||
}
|
||||
|
||||
// 22.1.3.2 String.prototype.charAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charat
|
||||
|
@ -248,7 +248,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at)
|
|||
if (position < 0 || position >= string.length_in_code_units())
|
||||
return PrimitiveString::create(vm, DeprecatedString::empty());
|
||||
|
||||
return PrimitiveString::create(vm, string.substring_view(position, 1));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, string.substring_view(position, 1))));
|
||||
}
|
||||
|
||||
// 22.1.3.3 String.prototype.charCodeAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charcodeat
|
||||
|
@ -518,7 +518,7 @@ static ThrowCompletionOr<Value> pad_string(VM& vm, Utf16String string, PadPlacem
|
|||
if (max_length <= string_length)
|
||||
return PrimitiveString::create(vm, move(string));
|
||||
|
||||
Utf16String fill_string(Utf16Data { 0x20 });
|
||||
auto fill_string = TRY(Utf16String::create(vm, Utf16Data { 0x20 }));
|
||||
if (!vm.argument(1).is_undefined()) {
|
||||
fill_string = TRY(vm.argument(1).to_utf16_string(vm));
|
||||
if (fill_string.is_empty())
|
||||
|
@ -736,7 +736,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::slice)
|
|||
if (int_start >= int_end)
|
||||
return PrimitiveString::create(vm, DeprecatedString::empty());
|
||||
|
||||
return PrimitiveString::create(vm, string.substring_view(int_start, int_end - int_start));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, string.substring_view(int_start, int_end - int_start))));
|
||||
}
|
||||
|
||||
// 22.1.3.22 String.prototype.split ( separator, limit ), https://tc39.es/ecma262/#sec-string.prototype.split
|
||||
|
@ -793,7 +793,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
|
|||
}
|
||||
|
||||
auto segment = string.substring_view(start, position - start);
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, segment)));
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, TRY(Utf16String::create(vm, segment)))));
|
||||
++array_length;
|
||||
if (array_length == limit)
|
||||
return array;
|
||||
|
@ -802,7 +802,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split)
|
|||
}
|
||||
|
||||
auto rest = string.substring_view(start);
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, rest)));
|
||||
MUST(array->create_data_property_or_throw(array_length, PrimitiveString::create(vm, TRY(Utf16String::create(vm, rest)))));
|
||||
|
||||
return array;
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring)
|
|||
size_t to = max(final_start, final_end);
|
||||
|
||||
// 10. Return the substring of S from from to to.
|
||||
return PrimitiveString::create(vm, string.substring_view(from, to - from));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, string.substring_view(from, to - from))));
|
||||
}
|
||||
|
||||
enum class TargetCase {
|
||||
|
@ -1111,7 +1111,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr)
|
|||
return PrimitiveString::create(vm, DeprecatedString::empty());
|
||||
|
||||
// 11. Return the substring of S from intStart to intEnd.
|
||||
return PrimitiveString::create(vm, string.substring_view(int_start, int_end - int_start));
|
||||
return PrimitiveString::create(vm, TRY(Utf16String::create(vm, string.substring_view(int_start, int_end - int_start))));
|
||||
}
|
||||
|
||||
// B.2.2.2.1 CreateHTML ( string, tag, attribute, value ), https://tc39.es/ecma262/#sec-createhtml
|
||||
|
|
|
@ -146,8 +146,8 @@ ThrowCompletionOr<Value> get_option(VM& vm, Object const& options, PropertyKey c
|
|||
if (!values.is_empty()) {
|
||||
// NOTE: Every location in the spec that invokes GetOption with type=boolean also has values=undefined.
|
||||
VERIFY(value.is_string());
|
||||
if (!values.contains_slow(value.as_string().deprecated_string()))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value.as_string().deprecated_string(), property.as_string());
|
||||
if (auto const& value_string = TRY(value.as_string().deprecated_string()); !values.contains_slow(value_string))
|
||||
return vm.throw_completion<RangeError>(ErrorType::OptionIsNotValidValue, value_string, property.as_string());
|
||||
}
|
||||
|
||||
// 9. Return value.
|
||||
|
@ -165,7 +165,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_overflow(VM& vm, Object const* o
|
|||
auto option = TRY(get_option(vm, *options, vm.names.overflow, OptionType::String, { "constrain"sv, "reject"sv }, "constrain"sv));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.5 ToTemporalDisambiguation ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation
|
||||
|
@ -179,7 +179,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_disambiguation(VM& vm, Object co
|
|||
auto option = TRY(get_option(vm, *options, vm.names.disambiguation, OptionType::String, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, "compatible"sv));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.6 ToTemporalRoundingMode ( normalizedOptions, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingmode
|
||||
|
@ -202,7 +202,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_rounding_mode(VM& vm, Object con
|
|||
fallback.view()));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.7 NegateTemporalRoundingMode ( roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-negatetemporalroundingmode
|
||||
|
@ -239,7 +239,7 @@ ThrowCompletionOr<DeprecatedString> to_temporal_offset(VM& vm, Object const* opt
|
|||
auto option = TRY(get_option(vm, *options, vm.names.offset, OptionType::String, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, fallback.view()));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.9 ToCalendarNameOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-tocalendarnameoption
|
||||
|
@ -249,7 +249,7 @@ ThrowCompletionOr<DeprecatedString> to_calendar_name_option(VM& vm, Object const
|
|||
auto option = TRY(get_option(vm, normalized_options, vm.names.calendarName, OptionType::String, { "auto"sv, "always"sv, "never"sv, "critical"sv }, "auto"sv));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.10 ToTimeZoneNameOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totimezonenameoption
|
||||
|
@ -259,7 +259,7 @@ ThrowCompletionOr<DeprecatedString> to_time_zone_name_option(VM& vm, Object cons
|
|||
auto option = TRY(get_option(vm, normalized_options, vm.names.timeZoneName, OptionType::String, { "auto"sv, "never"sv, "critical"sv }, "auto"sv));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.11 ToShowOffsetOption ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-toshowoffsetoption
|
||||
|
@ -269,7 +269,7 @@ ThrowCompletionOr<DeprecatedString> to_show_offset_option(VM& vm, Object const&
|
|||
auto option = TRY(get_option(vm, normalized_options, vm.names.offset, OptionType::String, { "auto"sv, "never"sv }, "auto"sv));
|
||||
|
||||
VERIFY(option.is_string());
|
||||
return option.as_string().deprecated_string();
|
||||
return TRY(option.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 13.12 ToTemporalRoundingIncrement ( normalizedOptions, dividend, inclusive ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalroundingincrement
|
||||
|
@ -530,7 +530,7 @@ ThrowCompletionOr<Optional<DeprecatedString>> get_temporal_unit(VM& vm, Object c
|
|||
|
||||
Optional<DeprecatedString> value = option_value.is_undefined()
|
||||
? Optional<DeprecatedString> {}
|
||||
: option_value.as_string().deprecated_string();
|
||||
: TRY(option_value.as_string().deprecated_string());
|
||||
|
||||
// 11. If value is listed in the Plural column of Table 13, then
|
||||
for (auto const& row : temporal_units) {
|
||||
|
|
|
@ -126,7 +126,7 @@ ThrowCompletionOr<Vector<DeprecatedString>> calendar_fields(VM& vm, Object& cale
|
|||
|
||||
Vector<DeprecatedString> result;
|
||||
for (auto& value : list)
|
||||
result.append(value.as_string().deprecated_string());
|
||||
result.append(TRY(value.as_string().deprecated_string()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -781,7 +781,7 @@ ThrowCompletionOr<double> resolve_iso_month(VM& vm, Object const& fields)
|
|||
|
||||
// 6. Assert: Type(monthCode) is String.
|
||||
VERIFY(month_code.is_string());
|
||||
auto& month_code_string = month_code.as_string().deprecated_string();
|
||||
auto const& month_code_string = TRY(month_code.as_string().deprecated_string());
|
||||
|
||||
// 7. If the length of monthCode is not 3, throw a RangeError exception.
|
||||
auto month_length = month_code_string.length();
|
||||
|
@ -943,7 +943,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
|
|||
// 3. For each element key of fieldsKeys, do
|
||||
for (auto& key : fields_keys) {
|
||||
// a. If key is not "month" or "monthCode", then
|
||||
if (key.as_string().deprecated_string() != vm.names.month.as_string() && key.as_string().deprecated_string() != vm.names.monthCode.as_string()) {
|
||||
if (!TRY(key.as_string().deprecated_string()).is_one_of(vm.names.month.as_string(), vm.names.monthCode.as_string())) {
|
||||
auto property_key = MUST(PropertyKey::from_value(vm, key));
|
||||
|
||||
// i. Let propValue be ? Get(fields, key).
|
||||
|
@ -977,7 +977,7 @@ ThrowCompletionOr<Object*> default_merge_calendar_fields(VM& vm, Object const& f
|
|||
}
|
||||
|
||||
// See comment above.
|
||||
additional_fields_keys_contains_month_or_month_code_property |= key.as_string().deprecated_string() == vm.names.month.as_string() || key.as_string().deprecated_string() == vm.names.monthCode.as_string();
|
||||
additional_fields_keys_contains_month_or_month_code_property |= TRY(key.as_string().deprecated_string()) == vm.names.month.as_string() || TRY(key.as_string().deprecated_string()) == vm.names.monthCode.as_string();
|
||||
}
|
||||
|
||||
// 6. If additionalFieldsKeys does not contain either "month" or "monthCode", then
|
||||
|
|
|
@ -559,19 +559,21 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields)
|
|||
return TRY(iterator_close(vm, iterator_record, move(completion)));
|
||||
}
|
||||
|
||||
auto const& next_value_string = TRY(next_value.as_string().deprecated_string());
|
||||
|
||||
// iii. If fieldNames contains nextValue, then
|
||||
if (field_names.contains_slow(next_value)) {
|
||||
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
||||
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value.as_string().deprecated_string());
|
||||
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalDuplicateCalendarField, next_value_string);
|
||||
|
||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||
return TRY(iterator_close(vm, iterator_record, move(completion)));
|
||||
}
|
||||
|
||||
// iv. If nextValue is not one of "year", "month", "monthCode", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond", then
|
||||
if (!next_value.as_string().deprecated_string().is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
||||
if (!next_value_string.is_one_of("year"sv, "month"sv, "monthCode"sv, "day"sv, "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv)) {
|
||||
// 1. Let completion be ThrowCompletion(a newly created RangeError object).
|
||||
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value.as_string().deprecated_string());
|
||||
auto completion = vm.throw_completion<RangeError>(ErrorType::TemporalInvalidCalendarFieldName, next_value_string);
|
||||
|
||||
// 2. Return ? IteratorClose(iteratorRecord, completion).
|
||||
return TRY(iterator_close(vm, iterator_record, move(completion)));
|
||||
|
|
|
@ -801,7 +801,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
|
|||
|
||||
// 18. Assert: Type(offsetString) is String.
|
||||
VERIFY(offset_string_value.is_string());
|
||||
auto const& offset_string = offset_string_value.as_string().deprecated_string();
|
||||
auto const& offset_string = TRY(offset_string_value.as_string().deprecated_string());
|
||||
|
||||
// 19. Let dateTimeResult be ? InterpretTemporalDateTimeFields(calendar, fields, options).
|
||||
auto date_time_result = TRY(interpret_temporal_date_time_fields(vm, calendar, *fields, *options));
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
namespace JS {
|
||||
namespace Detail {
|
||||
|
||||
static NonnullRefPtr<Utf16StringImpl> the_empty_utf16_string()
|
||||
static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> the_empty_utf16_string(VM& vm)
|
||||
{
|
||||
static NonnullRefPtr<Utf16StringImpl> empty_string = Utf16StringImpl::create();
|
||||
static NonnullRefPtr<Utf16StringImpl> empty_string = TRY(Utf16StringImpl::create(vm));
|
||||
return empty_string;
|
||||
}
|
||||
|
||||
|
@ -22,27 +22,27 @@ Utf16StringImpl::Utf16StringImpl(Utf16Data string)
|
|||
{
|
||||
}
|
||||
|
||||
NonnullRefPtr<Utf16StringImpl> Utf16StringImpl::create()
|
||||
ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm)
|
||||
{
|
||||
return adopt_ref(*new Utf16StringImpl());
|
||||
return TRY_OR_THROW_OOM(vm, adopt_nonnull_ref_or_enomem(new (nothrow) Utf16StringImpl()));
|
||||
}
|
||||
|
||||
NonnullRefPtr<Utf16StringImpl> Utf16StringImpl::create(Utf16Data string)
|
||||
ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, Utf16Data string)
|
||||
{
|
||||
return adopt_ref(*new Utf16StringImpl(move(string)));
|
||||
return TRY_OR_THROW_OOM(vm, adopt_nonnull_ref_or_enomem(new (nothrow) Utf16StringImpl(move(string))));
|
||||
}
|
||||
|
||||
NonnullRefPtr<Utf16StringImpl> Utf16StringImpl::create(StringView string)
|
||||
ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, StringView string)
|
||||
{
|
||||
return create(AK::utf8_to_utf16(string).release_value_but_fixme_should_propagate_errors());
|
||||
return create(vm, TRY_OR_THROW_OOM(vm, utf8_to_utf16(string)));
|
||||
}
|
||||
|
||||
NonnullRefPtr<Utf16StringImpl> Utf16StringImpl::create(Utf16View const& view)
|
||||
ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> Utf16StringImpl::create(VM& vm, Utf16View const& view)
|
||||
{
|
||||
Utf16Data string;
|
||||
string.ensure_capacity(view.length_in_code_units());
|
||||
string.append(view.data(), view.length_in_code_units());
|
||||
return create(move(string));
|
||||
TRY_OR_THROW_OOM(vm, string.try_ensure_capacity(view.length_in_code_units()));
|
||||
string.unchecked_append(view.data(), view.length_in_code_units());
|
||||
return create(vm, move(string));
|
||||
}
|
||||
|
||||
Utf16Data const& Utf16StringImpl::string() const
|
||||
|
@ -57,23 +57,28 @@ Utf16View Utf16StringImpl::view() const
|
|||
|
||||
}
|
||||
|
||||
Utf16String::Utf16String()
|
||||
: m_string(Detail::the_empty_utf16_string())
|
||||
ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm)
|
||||
{
|
||||
return Utf16String { TRY(Detail::the_empty_utf16_string(vm)) };
|
||||
}
|
||||
|
||||
Utf16String::Utf16String(Utf16Data string)
|
||||
: m_string(Detail::Utf16StringImpl::create(move(string)))
|
||||
ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, Utf16Data string)
|
||||
{
|
||||
return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, move(string))) };
|
||||
}
|
||||
|
||||
Utf16String::Utf16String(StringView string)
|
||||
: m_string(Detail::Utf16StringImpl::create(move(string)))
|
||||
ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, StringView string)
|
||||
{
|
||||
return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, string)) };
|
||||
}
|
||||
|
||||
Utf16String::Utf16String(Utf16View const& string)
|
||||
: m_string(Detail::Utf16StringImpl::create(move(string)))
|
||||
ThrowCompletionOr<Utf16String> Utf16String::create(VM& vm, Utf16View const& string)
|
||||
{
|
||||
return Utf16String { TRY(Detail::Utf16StringImpl::create(vm, string)) };
|
||||
}
|
||||
|
||||
Utf16String::Utf16String(NonnullRefPtr<Detail::Utf16StringImpl> string)
|
||||
: m_string(move(string))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@ class Utf16StringImpl : public RefCounted<Utf16StringImpl> {
|
|||
public:
|
||||
~Utf16StringImpl() = default;
|
||||
|
||||
static NonnullRefPtr<Utf16StringImpl> create();
|
||||
static NonnullRefPtr<Utf16StringImpl> create(Utf16Data);
|
||||
static NonnullRefPtr<Utf16StringImpl> create(StringView);
|
||||
static NonnullRefPtr<Utf16StringImpl> create(Utf16View const&);
|
||||
static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> create(VM&);
|
||||
static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> create(VM&, Utf16Data);
|
||||
static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> create(VM&, StringView);
|
||||
static ThrowCompletionOr<NonnullRefPtr<Utf16StringImpl>> create(VM&, Utf16View const&);
|
||||
|
||||
Utf16Data const& string() const;
|
||||
Utf16View view() const;
|
||||
|
@ -40,10 +40,10 @@ private:
|
|||
|
||||
class Utf16String {
|
||||
public:
|
||||
Utf16String();
|
||||
explicit Utf16String(Utf16Data);
|
||||
explicit Utf16String(StringView);
|
||||
explicit Utf16String(Utf16View const&);
|
||||
static ThrowCompletionOr<Utf16String> create(VM&);
|
||||
static ThrowCompletionOr<Utf16String> create(VM&, Utf16Data);
|
||||
static ThrowCompletionOr<Utf16String> create(VM&, StringView);
|
||||
static ThrowCompletionOr<Utf16String> create(VM&, Utf16View const&);
|
||||
|
||||
Utf16Data const& string() const;
|
||||
Utf16View view() const;
|
||||
|
@ -57,6 +57,8 @@ public:
|
|||
bool is_empty() const;
|
||||
|
||||
private:
|
||||
explicit Utf16String(NonnullRefPtr<Detail::Utf16StringImpl>);
|
||||
|
||||
NonnullRefPtr<Detail::Utf16StringImpl> m_string;
|
||||
};
|
||||
|
||||
|
|
|
@ -351,7 +351,7 @@ DeprecatedString Value::to_string_without_side_effects() const
|
|||
case INT32_TAG:
|
||||
return DeprecatedString::number(as_i32());
|
||||
case STRING_TAG:
|
||||
return as_string().deprecated_string();
|
||||
return MUST(as_string().deprecated_string());
|
||||
case SYMBOL_TAG:
|
||||
return as_symbol().to_deprecated_string();
|
||||
case BIGINT_TAG:
|
||||
|
@ -382,7 +382,7 @@ ThrowCompletionOr<DeprecatedString> Value::to_string(VM& vm) const
|
|||
switch (m_value.tag) {
|
||||
// 1. If argument is a String, return argument.
|
||||
case STRING_TAG:
|
||||
return as_string().deprecated_string();
|
||||
return TRY(as_string().deprecated_string());
|
||||
// 2. If argument is a Symbol, throw a TypeError exception.
|
||||
case SYMBOL_TAG:
|
||||
return vm.throw_completion<TypeError>(ErrorType::Convert, "symbol", "string");
|
||||
|
@ -421,10 +421,10 @@ ThrowCompletionOr<DeprecatedString> Value::to_string(VM& vm) const
|
|||
ThrowCompletionOr<Utf16String> Value::to_utf16_string(VM& vm) const
|
||||
{
|
||||
if (is_string())
|
||||
return as_string().utf16_string();
|
||||
return TRY(as_string().utf16_string());
|
||||
|
||||
auto utf8_string = TRY(to_string(vm));
|
||||
return Utf16String(utf8_string);
|
||||
return Utf16String::create(vm, utf8_string);
|
||||
}
|
||||
|
||||
// 7.1.2 ToBoolean ( argument ), https://tc39.es/ecma262/#sec-toboolean
|
||||
|
@ -684,7 +684,7 @@ ThrowCompletionOr<Value> Value::to_number(VM& vm) const
|
|||
return Value(as_bool() ? 1 : 0);
|
||||
// 6. If argument is a String, return StringToNumber(argument).
|
||||
case STRING_TAG:
|
||||
return string_to_number(as_string().deprecated_string().view());
|
||||
return string_to_number(TRY(as_string().deprecated_string()));
|
||||
// 7. Assert: argument is an Object.
|
||||
case OBJECT_TAG: {
|
||||
// 8. Let primValue be ? ToPrimitive(argument, number).
|
||||
|
@ -738,7 +738,7 @@ ThrowCompletionOr<BigInt*> Value::to_bigint(VM& vm) const
|
|||
return &primitive.as_bigint();
|
||||
case STRING_TAG: {
|
||||
// 1. Let n be ! StringToBigInt(prim).
|
||||
auto bigint = string_to_bigint(vm, primitive.as_string().deprecated_string());
|
||||
auto bigint = string_to_bigint(vm, TRY(primitive.as_string().deprecated_string()));
|
||||
|
||||
// 2. If n is undefined, throw a SyntaxError exception.
|
||||
if (!bigint.has_value())
|
||||
|
@ -2150,7 +2150,8 @@ bool same_value_non_number(Value lhs, Value rhs)
|
|||
// 5. If x is a String, then
|
||||
if (lhs.is_string()) {
|
||||
// a. If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
|
||||
return lhs.as_string().deprecated_string() == rhs.as_string().deprecated_string();
|
||||
// FIXME: Propagate this error.
|
||||
return MUST(lhs.as_string().deprecated_string()) == MUST(rhs.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// 3. If x is undefined, return true.
|
||||
|
@ -2231,7 +2232,7 @@ ThrowCompletionOr<bool> is_loosely_equal(VM& vm, Value lhs, Value rhs)
|
|||
// 7. If Type(x) is BigInt and Type(y) is String, then
|
||||
if (lhs.is_bigint() && rhs.is_string()) {
|
||||
// a. Let n be StringToBigInt(y).
|
||||
auto bigint = string_to_bigint(vm, rhs.as_string().deprecated_string());
|
||||
auto bigint = string_to_bigint(vm, TRY(rhs.as_string().deprecated_string()));
|
||||
|
||||
// b. If n is undefined, return false.
|
||||
if (!bigint.has_value())
|
||||
|
@ -2312,8 +2313,8 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
|
|||
|
||||
// 3. If px is a String and py is a String, then
|
||||
if (x_primitive.is_string() && y_primitive.is_string()) {
|
||||
auto x_string = x_primitive.as_string().deprecated_string();
|
||||
auto y_string = y_primitive.as_string().deprecated_string();
|
||||
auto x_string = TRY(x_primitive.as_string().deprecated_string());
|
||||
auto y_string = TRY(y_primitive.as_string().deprecated_string());
|
||||
|
||||
Utf8View x_code_points { x_string };
|
||||
Utf8View y_code_points { y_string };
|
||||
|
@ -2348,7 +2349,7 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
|
|||
// a. If px is a BigInt and py is a String, then
|
||||
if (x_primitive.is_bigint() && y_primitive.is_string()) {
|
||||
// i. Let ny be StringToBigInt(py).
|
||||
auto y_bigint = string_to_bigint(vm, y_primitive.as_string().deprecated_string());
|
||||
auto y_bigint = string_to_bigint(vm, TRY(y_primitive.as_string().deprecated_string()));
|
||||
|
||||
// ii. If ny is undefined, return undefined.
|
||||
if (!y_bigint.has_value())
|
||||
|
@ -2363,7 +2364,7 @@ ThrowCompletionOr<TriState> is_less_than(VM& vm, Value lhs, Value rhs, bool left
|
|||
// b. If px is a String and py is a BigInt, then
|
||||
if (x_primitive.is_string() && y_primitive.is_bigint()) {
|
||||
// i. Let nx be StringToBigInt(px).
|
||||
auto x_bigint = string_to_bigint(vm, x_primitive.as_string().deprecated_string());
|
||||
auto x_bigint = string_to_bigint(vm, TRY(x_primitive.as_string().deprecated_string()));
|
||||
|
||||
// ii. If nx is undefined, return undefined.
|
||||
if (!x_bigint.has_value())
|
||||
|
|
|
@ -16,8 +16,10 @@ struct ValueTraits : public Traits<Value> {
|
|||
static unsigned hash(Value value)
|
||||
{
|
||||
VERIFY(!value.is_empty());
|
||||
if (value.is_string())
|
||||
return value.as_string().deprecated_string().hash();
|
||||
if (value.is_string()) {
|
||||
// FIXME: Propagate this error.
|
||||
return value.as_string().deprecated_string().release_value().hash();
|
||||
}
|
||||
|
||||
if (value.is_bigint())
|
||||
return value.as_bigint().big_integer().hash();
|
||||
|
|
|
@ -163,7 +163,7 @@ JS::NonnullGCPtr<JS::Promise> consume_body(JS::Realm& realm, BodyMixin const& ob
|
|||
// 4. Let steps be to return the result of package data with the first argument given, type, and object’s MIME type.
|
||||
auto steps = [&vm, &realm, &object, type](JS::Value value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||
VERIFY(value.is_string());
|
||||
auto bytes = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(value.as_string().deprecated_string().bytes()));
|
||||
auto bytes = TRY_OR_THROW_OOM(vm, ByteBuffer::copy(TRY(value.as_string().deprecated_string()).bytes()));
|
||||
return package_data(realm, move(bytes), type, object.mime_type_impl());
|
||||
};
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ WebIDL::ExceptionOr<DeprecatedString> serialize_javascript_value_to_json_string(
|
|||
VERIFY(result.is_string());
|
||||
|
||||
// 4. Return result.
|
||||
return result.as_string().deprecated_string();
|
||||
return TRY(result.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-json-bytes
|
||||
|
|
|
@ -35,7 +35,7 @@ JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> WebAssemblyTableConstructor:
|
|||
auto element_value = TRY(descriptor->get("element"));
|
||||
if (!element_value.is_string())
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects());
|
||||
auto& element = element_value.as_string().deprecated_string();
|
||||
auto const& element = TRY(element_value.as_string().deprecated_string());
|
||||
|
||||
Optional<Wasm::ValueType> reference_type;
|
||||
if (element == "anyfunc"sv)
|
||||
|
|
|
@ -95,7 +95,7 @@ static ErrorOr<JsonValue, ExecuteScriptResultType> internal_json_clone_algorithm
|
|||
if (value.is_number())
|
||||
return JsonValue { value.as_double() };
|
||||
if (value.is_string())
|
||||
return JsonValue { value.as_string().deprecated_string() };
|
||||
return JsonValue { TRY_OR_JS_ERROR(value.as_string().deprecated_string()) };
|
||||
|
||||
// NOTE: BigInt and Symbol not mentioned anywhere in the WebDriver spec, as it references ES5.
|
||||
// It assumes that all primitives are handled above, and the value is an object for the remaining steps.
|
||||
|
@ -114,7 +114,7 @@ static ErrorOr<JsonValue, ExecuteScriptResultType> internal_json_clone_algorithm
|
|||
auto to_json_result = TRY_OR_JS_ERROR(to_json.as_function().internal_call(value, JS::MarkedVector<JS::Value> { vm.heap() }));
|
||||
if (!to_json_result.is_string())
|
||||
return ExecuteScriptResultType::JavaScriptError;
|
||||
return to_json_result.as_string().deprecated_string();
|
||||
return TRY_OR_JS_ERROR(to_json_result.as_string().deprecated_string());
|
||||
}
|
||||
|
||||
// -> Otherwise
|
||||
|
|
Loading…
Reference in a new issue