Browse Source

LibJS: Add length parameter to Array::create()

This is now a bit closer to the spec's 10.4.2.2 ArrayCreate - it will
throw a RangeError if the requested length exceeds 2^32 - 1, so anyone
passing in a custom value (defaults to zero for same behaviour as
before) will need an exception check at the call site.
Linus Groh 4 years ago
parent
commit
1c906b07a4

+ 11 - 2
Userland/Libraries/LibJS/Runtime/Array.cpp

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -11,9 +12,17 @@
 
 
 namespace JS {
 namespace JS {
 
 
-Array* Array::create(GlobalObject& global_object)
+// 10.4.2.2 ArrayCreate, https://tc39.es/ecma262/#sec-arraycreate
+Array* Array::create(GlobalObject& global_object, size_t length)
 {
 {
-    return global_object.heap().allocate<Array>(global_object, *global_object.array_prototype());
+    if (length > NumericLimits<u32>::max()) {
+        auto& vm = global_object.vm();
+        vm.throw_exception<RangeError>(global_object, ErrorType::InvalidLength, "array");
+        return nullptr;
+    }
+    auto* array = global_object.heap().allocate<Array>(global_object, *global_object.array_prototype());
+    array->indexed_properties().set_array_like_size(length);
+    return array;
 }
 }
 
 
 // 7.3.17 CreateArrayFromList, https://tc39.es/ecma262/#sec-createarrayfromlist
 // 7.3.17 CreateArrayFromList, https://tc39.es/ecma262/#sec-createarrayfromlist

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Array.h

@@ -14,7 +14,7 @@ class Array : public Object {
     JS_OBJECT(Array, Object);
     JS_OBJECT(Array, Object);
 
 
 public:
 public:
-    static Array* create(GlobalObject&);
+    static Array* create(GlobalObject&, size_t length = 0);
     static Array* create_from(GlobalObject&, const Vector<Value>&);
     static Array* create_from(GlobalObject&, const Vector<Value>&);
 
 
     explicit Array(Object& prototype);
     explicit Array(Object& prototype);