diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c
index 39d9105e2..c9cb34795 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c
@@ -15,7 +15,10 @@
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
+#include "ecma-conversion.h"
#include "ecma-exceptions.h"
+#include "ecma-function-object.h"
+#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
@@ -78,15 +81,15 @@ ecma_builtin_arraybuffer_prototype_bytelength_getter (ecma_value_t this_arg) /**
* The ArrayBuffer.prototype object's 'slice' routine
*
* See also:
- * ES2015, 24.1.4.3
+ * ECMA-262 v11, 24.1.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< this argument */
- ecma_value_t arg1, /**< routine's first argument */
- ecma_value_t arg2) /**< routine's second argument */
+ const ecma_value_t *argument_list_p, /**< arguments list */
+ uint32_t arguments_number) /**< number of arguments */
{
if (!ecma_is_value_object (this_arg))
{
@@ -95,53 +98,134 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
+ /* 2. */
if (!ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an ArrayBuffer object."));
}
+ /* TODO: step 3. if SharedArrayBuffer will be implemented */
+
+ /* 4. */
if (ecma_arraybuffer_is_detached (object_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
+ /* 5. */
uint32_t len = ecma_arraybuffer_get_length (object_p);
- uint32_t start = 0, end = len;
+ uint32_t start = 0;
+ uint32_t end = len;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
- if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg1,
- len,
- &start)))
+ if (arguments_number > 0)
{
- return ECMA_VALUE_ERROR;
- }
-
- if (!ecma_is_value_undefined (arg2))
- {
- if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg2,
+ /* 6-7. */
+ if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (argument_list_p[0],
len,
- &end)))
+ &start)))
{
return ECMA_VALUE_ERROR;
}
+
+ if (arguments_number > 1 && !ecma_is_value_undefined (argument_list_p[1]))
+ {
+ /* 8-9 .*/
+ if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (argument_list_p[1],
+ len,
+ &end)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
+ }
}
- if (ret_value != ECMA_VALUE_EMPTY)
- {
- return ret_value;
- }
-
- JERRY_ASSERT (start <= len && end <= len);
+ /* 10. */
uint32_t new_len = (end >= start) ? (end - start) : 0;
- ecma_object_t *new_arraybuffer_p = ecma_arraybuffer_new_object (new_len);
+
+ /* 11. */
+ ecma_value_t ctor = ecma_op_species_constructor (object_p, ECMA_BUILTIN_ID_ARRAYBUFFER);
+
+ if (ECMA_IS_VALUE_ERROR (ctor))
+ {
+ return ctor;
+ }
+
+ /* 12. */
+ ecma_object_t *ctor_obj_p = ecma_get_object_from_value (ctor);
+ ecma_value_t new_len_value = ecma_make_uint32_value (new_len);
+
+ ecma_value_t new_arraybuffer = ecma_op_function_construct (ctor_obj_p, ctor_obj_p, &new_len_value, 1);
+
+ ecma_deref_object (ctor_obj_p);
+ ecma_free_value (new_len_value);
+
+ if (ECMA_IS_VALUE_ERROR (new_arraybuffer))
+ {
+ return new_arraybuffer;
+ }
+
+ ecma_object_t *new_arraybuffer_p = ecma_get_object_from_value (new_arraybuffer);
+ ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+ /* 13. */
+ if (!ecma_object_class_is (new_arraybuffer_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
+ {
+ ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Return value is not an ArrayBuffer object."));
+ goto free_new_arraybuffer;
+ }
+
+ /* TODO: step 14. if SharedArrayBuffer will be implemented */
+
+ /* 15. */
+ if (ecma_arraybuffer_is_detached (new_arraybuffer_p))
+ {
+ ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Return ArrayBuffer has been detached."));
+ goto free_new_arraybuffer;
+ }
+
+ /* 16. */
+ if (ecma_op_same_value (new_arraybuffer, this_arg))
+ {
+ ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer subclass returned this from species constructor"));
+ goto free_new_arraybuffer;
+ }
+
+ /* 17. */
+ if (ecma_arraybuffer_get_length (new_arraybuffer_p) < new_len)
+ {
+ ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived ArrayBuffer constructor created a too small buffer."));
+ goto free_new_arraybuffer;
+ }
+
+ /* 19. */
+ if (ecma_arraybuffer_is_detached (object_p))
+ {
+ ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Original ArrayBuffer has been detached."));
+ goto free_new_arraybuffer;
+ }
+
+ /* 20. */
lit_utf8_byte_t *old_buf = ecma_arraybuffer_get_buffer (object_p);
+
+ /* 21. */
lit_utf8_byte_t *new_buf = ecma_arraybuffer_get_buffer (new_arraybuffer_p);
+ /* 22. */
memcpy (new_buf, old_buf + start, new_len);
- return ecma_make_object_value (new_arraybuffer_p);
+free_new_arraybuffer:
+ if (ret_value != ECMA_VALUE_EMPTY)
+ {
+ ecma_deref_object (new_arraybuffer_p);
+ }
+ else
+ {
+ /* 23. */
+ ret_value = ecma_make_object_value (new_arraybuffer_p);
+ }
+
+ return ret_value;
} /* ecma_builtin_arraybuffer_prototype_object_slice */
/**
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.inc.h
index 9b1ebb5e1..0cd59f17e 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.inc.h
@@ -40,7 +40,7 @@ STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
-ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_arraybuffer_prototype_object_slice, 2, 2)
+ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_arraybuffer_prototype_object_slice, NON_FIXED, 2)
#endif /* ENABLED (JERRY_BUILTIN_TYPEDARRAY) */
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 21ae9c096..5af5acdc8 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -164,14 +164,6 @@
-
-
-
-
-
-
-
-
@@ -4259,7 +4251,6 @@
-