mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 01:20:25 +00:00
LibJS: Convert Array AOs to ThrowCompletionOr
This commit is contained in:
parent
3426285738
commit
db5df26841
Notes:
sideshowbarker
2024-07-18 02:03:29 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/db5df268412 Pull-request: https://github.com/SerenityOS/serenity/pull/10568 Reviewed-by: https://github.com/linusg ✅
14 changed files with 37 additions and 64 deletions
|
@ -1375,7 +1375,7 @@ static void generate_wrap_statement(SourceGenerator& generator, String const& va
|
|||
auto& sequence_generic_type = verify_cast<IDL::ParameterizedType>(type);
|
||||
|
||||
scoped_generator.append(R"~~~(
|
||||
auto* new_array@recursion_depth@ = JS::Array::create(global_object, 0);
|
||||
auto* new_array@recursion_depth@ = MUST(JS::Array::create(global_object, 0));
|
||||
|
||||
for (size_t i@recursion_depth@ = 0; i@recursion_depth@ < @value@.size(); ++i@recursion_depth@) {
|
||||
auto& element@recursion_depth@ = @value@.at(i@recursion_depth@);
|
||||
|
|
|
@ -2867,7 +2867,7 @@ Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
{
|
||||
InterpreterNodeScope node_scope { interpreter, *this };
|
||||
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
array->indexed_properties();
|
||||
size_t index = 0;
|
||||
for (auto& element : m_elements) {
|
||||
|
@ -2939,7 +2939,7 @@ Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& glo
|
|||
}
|
||||
auto& tag_function = tag.as_function();
|
||||
auto& expressions = m_template_literal->expressions();
|
||||
auto* strings = Array::create(global_object, 0);
|
||||
auto* strings = MUST(Array::create(global_object, 0));
|
||||
MarkedValueList arguments(vm.heap());
|
||||
arguments.append(strings);
|
||||
for (size_t i = 0; i < expressions.size(); ++i) {
|
||||
|
@ -2955,7 +2955,7 @@ Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& glo
|
|||
}
|
||||
}
|
||||
|
||||
auto* raw_strings = Array::create(global_object, 0);
|
||||
auto* raw_strings = MUST(Array::create(global_object, 0));
|
||||
for (auto& raw_string : m_template_literal->raw_strings()) {
|
||||
auto value = raw_string.execute(interpreter, global_object);
|
||||
if (vm.exception())
|
||||
|
|
|
@ -139,7 +139,7 @@ void IteratorToArray::execute_impl(Bytecode::Interpreter& interpreter) const
|
|||
return;
|
||||
auto* iterator = iterator_or_error.release_value();
|
||||
|
||||
auto array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
size_t index = 0;
|
||||
|
||||
while (true) {
|
||||
|
|
|
@ -14,13 +14,11 @@
|
|||
namespace JS {
|
||||
|
||||
// 10.4.2.2 ArrayCreate ( length [ , proto ] ), https://tc39.es/ecma262/#sec-arraycreate
|
||||
Array* Array::create(GlobalObject& global_object, size_t length, Object* prototype)
|
||||
ThrowCompletionOr<Array*> Array::create(GlobalObject& global_object, size_t length, Object* prototype)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
if (length > NumericLimits<u32>::max()) {
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
||||
return nullptr;
|
||||
}
|
||||
if (length > NumericLimits<u32>::max())
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
||||
if (!prototype)
|
||||
prototype = global_object.array_prototype();
|
||||
auto* array = global_object.heap().allocate<Array>(global_object, *prototype);
|
||||
|
@ -34,7 +32,7 @@ Array* Array::create_from(GlobalObject& global_object, Vector<Value> const& elem
|
|||
// 1. Assert: elements is a List whose elements are all ECMAScript language values.
|
||||
|
||||
// 2. Let array be ! ArrayCreate(0).
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
|
||||
// 3. Let n be 0.
|
||||
// 4. For each element e of elements, do
|
||||
|
@ -59,7 +57,7 @@ Array::~Array()
|
|||
}
|
||||
|
||||
// 10.4.2.4 ArraySetLength ( A, Desc ), https://tc39.es/ecma262/#sec-arraysetlength
|
||||
bool Array::set_length(PropertyDescriptor const& property_descriptor)
|
||||
ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_descriptor)
|
||||
{
|
||||
auto& global_object = this->global_object();
|
||||
auto& vm = this->vm();
|
||||
|
@ -72,14 +70,12 @@ bool Array::set_length(PropertyDescriptor const& property_descriptor)
|
|||
size_t new_length = indexed_properties().array_like_size();
|
||||
if (property_descriptor.value.has_value()) {
|
||||
// 3. Let newLen be ? ToUint32(Desc.[[Value]]).
|
||||
new_length = TRY_OR_DISCARD(property_descriptor.value->to_u32(global_object));
|
||||
new_length = TRY(property_descriptor.value->to_u32(global_object));
|
||||
// 4. Let numberLen be ? ToNumber(Desc.[[Value]]).
|
||||
auto number_length = TRY_OR_DISCARD(property_descriptor.value->to_number(global_object));
|
||||
auto number_length = TRY(property_descriptor.value->to_number(global_object));
|
||||
// 5. If newLen is not the same value as numberLen, throw a RangeError exception.
|
||||
if (new_length != number_length.as_double()) {
|
||||
vm.throw_exception<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
||||
return {};
|
||||
}
|
||||
if (new_length != number_length.as_double())
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::InvalidLength, "array");
|
||||
}
|
||||
|
||||
// 6. Set newLenDesc.[[Value]] to newLen.
|
||||
|
@ -175,10 +171,7 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyName const&
|
|||
// 2. If P is "length", then
|
||||
if (property_name.is_string() && property_name.as_string() == vm.names.length.as_string()) {
|
||||
// a. Return ? ArraySetLength(A, Desc).
|
||||
auto success = set_length(property_descriptor);
|
||||
if (auto* exception = vm.exception())
|
||||
return throw_completion(exception->value());
|
||||
return success;
|
||||
return set_length(property_descriptor);
|
||||
}
|
||||
|
||||
// 3. Else if P is an array index, then
|
||||
|
|
|
@ -19,7 +19,7 @@ class Array : public Object {
|
|||
JS_OBJECT(Array, Object);
|
||||
|
||||
public:
|
||||
static Array* create(GlobalObject&, size_t length, Object* prototype = nullptr);
|
||||
static ThrowCompletionOr<Array*> create(GlobalObject&, size_t length, Object* prototype = nullptr);
|
||||
static Array* create_from(GlobalObject&, Vector<Value> const&);
|
||||
// Non-standard but equivalent to CreateArrayFromList.
|
||||
template<typename T>
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
[[nodiscard]] bool length_is_writable() const { return m_length_writable; };
|
||||
|
||||
private:
|
||||
bool set_length(PropertyDescriptor const&);
|
||||
ThrowCompletionOr<bool> set_length(PropertyDescriptor const&);
|
||||
|
||||
bool m_length_writable { true };
|
||||
};
|
||||
|
|
|
@ -58,11 +58,11 @@ ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_targe
|
|||
auto* proto = TRY(get_prototype_from_constructor(global_object(), new_target, &GlobalObject::array_prototype));
|
||||
|
||||
if (vm.argument_count() == 0)
|
||||
return Array::create(global_object(), 0, proto);
|
||||
return MUST(Array::create(global_object(), 0, proto));
|
||||
|
||||
if (vm.argument_count() == 1) {
|
||||
auto length = vm.argument(0);
|
||||
auto* array = Array::create(global_object(), 0, proto);
|
||||
auto* array = MUST(Array::create(global_object(), 0, proto));
|
||||
size_t int_length;
|
||||
if (!length.is_number()) {
|
||||
MUST(array->create_data_property_or_throw(0, length));
|
||||
|
@ -76,9 +76,7 @@ ThrowCompletionOr<Object*> ArrayConstructor::construct(FunctionObject& new_targe
|
|||
return array;
|
||||
}
|
||||
|
||||
auto* array = Array::create(global_object(), vm.argument_count(), proto);
|
||||
if (auto* exception = vm.exception())
|
||||
return throw_completion(exception->value());
|
||||
auto* array = TRY(Array::create(global_object(), vm.argument_count(), proto));
|
||||
|
||||
for (size_t k = 0; k < vm.argument_count(); ++k)
|
||||
MUST(array->create_data_property_or_throw(k, vm.argument(k)));
|
||||
|
@ -112,7 +110,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
if (vm.exception())
|
||||
return {};
|
||||
} else {
|
||||
array = Array::create(global_object, 0);
|
||||
array = MUST(Array::create(global_object, 0));
|
||||
}
|
||||
|
||||
auto iterator = TRY_OR_DISCARD(get_iterator(global_object, items, IteratorHint::Sync, using_iterator));
|
||||
|
@ -163,9 +161,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::from)
|
|||
if (vm.exception())
|
||||
return {};
|
||||
} else {
|
||||
array = Array::create(global_object, length);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
array = TRY_OR_DISCARD(Array::create(global_object, length));
|
||||
}
|
||||
|
||||
auto& array_object = array.as_object();
|
||||
|
@ -204,9 +200,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(ArrayConstructor::of)
|
|||
if (vm.exception())
|
||||
return {};
|
||||
} else {
|
||||
array = Array::create(global_object, vm.argument_count());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
array = TRY_OR_DISCARD(Array::create(global_object, vm.argument_count()));
|
||||
}
|
||||
auto& array_object = array.as_object();
|
||||
for (size_t k = 0; k < vm.argument_count(); ++k)
|
||||
|
|
|
@ -109,12 +109,8 @@ static Object* array_species_create(GlobalObject& global_object, Object& origina
|
|||
|
||||
auto is_array = TRY_OR_DISCARD(Value(&original_array).is_array(global_object));
|
||||
|
||||
if (!is_array) {
|
||||
auto array = Array::create(global_object, length);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return array;
|
||||
}
|
||||
if (!is_array)
|
||||
return TRY_OR_DISCARD(Array::create(global_object, length));
|
||||
|
||||
auto constructor = TRY_OR_DISCARD(original_array.get(vm.names.constructor));
|
||||
if (constructor.is_constructor()) {
|
||||
|
@ -133,12 +129,8 @@ static Object* array_species_create(GlobalObject& global_object, Object& origina
|
|||
constructor = js_undefined();
|
||||
}
|
||||
|
||||
if (constructor.is_undefined()) {
|
||||
auto array = Array::create(global_object, length);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return array;
|
||||
}
|
||||
if (constructor.is_undefined())
|
||||
return TRY_OR_DISCARD(Array::create(global_object, length));
|
||||
|
||||
if (!constructor.is_constructor()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||
|
|
|
@ -402,7 +402,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
|
|||
[&](auto const& param) {
|
||||
Value argument_value;
|
||||
if (parameter.is_rest) {
|
||||
auto* array = Array::create(global_object(), 0);
|
||||
auto* array = MUST(Array::create(global_object(), 0));
|
||||
for (size_t rest_index = i; rest_index < execution_context_arguments.size(); ++rest_index)
|
||||
array->indexed_properties().append(execution_context_arguments[rest_index]);
|
||||
argument_value = move(array);
|
||||
|
|
|
@ -237,7 +237,7 @@ Array* format_list_to_parts(GlobalObject& global_object, ListFormat const& list_
|
|||
auto parts = create_parts_from_list(list_format, list);
|
||||
|
||||
// 2. Let result be ArrayCreate(0).
|
||||
auto result = Array::create(global_object, 0);
|
||||
auto* result = MUST(Array::create(global_object, 0));
|
||||
|
||||
// 3. Let n be 0.
|
||||
size_t n = 0;
|
||||
|
|
|
@ -428,7 +428,7 @@ Object* JSONObject::parse_json_object(GlobalObject& global_object, const JsonObj
|
|||
|
||||
Array* JSONObject::parse_json_array(GlobalObject& global_object, const JsonArray& json_array)
|
||||
{
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
size_t index = 0;
|
||||
json_array.for_each([&](auto& value) {
|
||||
array->define_direct_property(index++, parse_json_value(global_object, value), JS::default_attributes);
|
||||
|
|
|
@ -120,9 +120,7 @@ static Value make_indices_array(GlobalObject& global_object, Utf16View const& st
|
|||
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
auto* array = Array::create(global_object, indices.size());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* array = TRY_OR_DISCARD(Array::create(global_object, indices.size()));
|
||||
|
||||
auto groups = has_groups ? Object::create(global_object, nullptr) : js_undefined();
|
||||
|
||||
|
@ -206,9 +204,7 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege
|
|||
if (global || sticky)
|
||||
TRY_OR_DISCARD(regexp_object.set(vm.names.lastIndex, Value(end_index), Object::ShouldThrowExceptions::Yes));
|
||||
|
||||
auto* array = Array::create(global_object, result.n_named_capture_groups + 1);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* array = TRY_OR_DISCARD(Array::create(global_object, result.n_named_capture_groups + 1));
|
||||
|
||||
Vector<Optional<Match>> indices { Match::create(match) };
|
||||
HashMap<FlyString, Match> group_names;
|
||||
|
@ -379,9 +375,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(RegExpPrototype::symbol_match)
|
|||
|
||||
TRY_OR_DISCARD(regexp_object->set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes));
|
||||
|
||||
auto* array = Array::create(global_object, 0);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
|
||||
bool unicode = TRY_OR_DISCARD(regexp_object->get(vm.names.unicode)).to_boolean();
|
||||
|
||||
|
@ -599,7 +593,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
|
|||
if (vm.exception())
|
||||
return {};
|
||||
auto* splitter = TRY_OR_DISCARD(splitter_value.to_object(global_object));
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
size_t array_length = 0;
|
||||
|
||||
auto limit = NumericLimits<u32>::max();
|
||||
|
|
|
@ -666,7 +666,7 @@ JS_DEFINE_OLD_NATIVE_FUNCTION(StringPrototype::split)
|
|||
|
||||
auto string = TRY_OR_DISCARD(object.to_utf16_string(global_object));
|
||||
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
size_t array_length = 0;
|
||||
|
||||
auto limit = NumericLimits<u32>::max();
|
||||
|
|
|
@ -359,7 +359,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
|||
if (entry.is_rest) {
|
||||
VERIFY(i == binding.entries.size() - 1);
|
||||
|
||||
auto* array = Array::create(global_object, 0);
|
||||
auto* array = MUST(Array::create(global_object, 0));
|
||||
while (!iterator_done) {
|
||||
auto next_object_or_error = iterator_next(*iterator);
|
||||
if (next_object_or_error.is_throw_completion()) {
|
||||
|
|
|
@ -20,7 +20,7 @@ NavigatorObject::NavigatorObject(JS::GlobalObject& global_object)
|
|||
void NavigatorObject::initialize(JS::GlobalObject& global_object)
|
||||
{
|
||||
auto& heap = this->heap();
|
||||
auto* languages = JS::Array::create(global_object, 0);
|
||||
auto* languages = MUST(JS::Array::create(global_object, 0));
|
||||
languages->indexed_properties().append(js_string(heap, "en-US"));
|
||||
|
||||
// FIXME: All of these should be in Navigator's prototype and be native accessors
|
||||
|
|
Loading…
Reference in a new issue