njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
int64_t start, int64_t length, njs_value_t *retval)
{
+ double idx;
size_t size;
uint32_t n;
njs_int_t ret;
njs_set_array(&self, array);
- if (njs_fast_object(length)) {
- do {
- ret = njs_value_property_i64(vm, this, start++, &val);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return NJS_ERROR;
- }
-
- if (ret == NJS_OK) {
- ret = njs_value_property_i64_set(vm, &self, start, &val);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
- }
-
- length--;
- } while (length != 0);
-
- ret = NJS_OK;
- goto done;
- }
-
keys = njs_array_indices(vm, this);
if (njs_slow_path(keys == NULL)) {
return NJS_ERROR;
}
for (n = 0; n < keys->length; n++) {
+ idx = njs_string_to_index(&keys->start[n]);
+
+ if (idx < start || idx >= start + length) {
+ continue;
+ }
+
ret = njs_value_property(vm, this, keys->start[n].atom_id, &val);
if (njs_slow_path(ret == NJS_ERROR)) {
goto done;
}
- ret = njs_value_property_set(vm, &self, keys->start[n].atom_id, &val);
+ ret = njs_value_property_i64_set(vm, &self, idx - start, &val);
if (njs_slow_path(ret == NJS_ERROR)) {
goto done;
}
{ njs_str("Array.prototype.slice.call({ length: Object.create(null) })"),
njs_str("TypeError: Cannot convert object to primitive value") },
+ /* Large sparse slice goes through the non-fast keys path. */
+
+ { njs_str("var a = []; a[10] = 'a'; a[40000] = 'b'; a.length = 50000;"
+ "var s = a.slice(5, 45000);"
+ "[s.length, s[5], s[39995], (10 in s), (40000 in s)].join(',')"),
+ njs_str("44995,a,b,false,false") },
+
{ njs_str("Array.prototype.slice.call({length:-1})"),
njs_str("") },