Refactoring several array buffer and typed array functions. (#1715)

The ecma_typedarray_create_object_with_typedarray function is fully rewritten.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2017-04-07 11:20:03 +02:00
committed by GitHub
parent 1886d54474
commit 13b305f716
4 changed files with 195 additions and 209 deletions
@@ -32,53 +32,6 @@
* @{ * @{
*/ */
/**
* ArrayBuffer object creation operation.
*
* See also: ES2015 24.1.1.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_op_create_arraybuffer_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
* are passed to String constructor */
ecma_length_t arguments_list_len) /**< length of the arguments' list */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
uint32_t length = 0;
if (arguments_list_len > 0)
{
ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_OP_TO_NUMBER_TRY_CATCH (num, arguments_list_p[0], ret);
length = ecma_number_to_uint32 (num);
if (num != ((ecma_number_t) length))
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid ArrayBuffer length."));
}
ECMA_OP_TO_NUMBER_FINALIZE (num);
if (!ecma_is_value_empty (ret))
{
return ret;
}
}
if (length > UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid ArrayBuffer length."));
}
ecma_object_t *object_p = ecma_arraybuffer_new_object (length);
return ecma_make_object_value (object_p);
} /* ecma_op_create_arraybuffer_object */
/** /**
* Helper function: create arraybuffer object based on the array length * Helper function: create arraybuffer object based on the array length
* *
@@ -108,27 +61,55 @@ ecma_arraybuffer_new_object (ecma_length_t length) /**< length of the arraybuffe
} /* ecma_arraybuffer_new_object */ } /* ecma_arraybuffer_new_object */
/** /**
* Helper function: create arraybuffer object by cloning another arraybuffer * ArrayBuffer object creation operation.
* *
* See also: ES2015 24.1.1.4 * See also: ES2015 24.1.1.1
* *
* @return cloned array buffer * @return ecma value
* Returned value must be freed with ecma_free_value
*/ */
ecma_object_t * ecma_value_t
ecma_arraybuffer_clone_arraybuffer (ecma_object_t *array_buf_p, /**< the cloned array buffer */ ecma_op_create_arraybuffer_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
ecma_length_t offset) /**< start offset */ * are passed to String constructor */
ecma_length_t arguments_list_len) /**< length of the arguments' list */
{ {
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
JERRY_ASSERT (offset <= ecma_arraybuffer_get_length (array_buf_p)); uint32_t length = 0;
ecma_length_t length = ecma_arraybuffer_get_length (array_buf_p) - offset; if (arguments_list_len > 0)
ecma_object_t *new_array_buf_p = ecma_arraybuffer_new_object (length); {
lit_utf8_byte_t *src_buf_p = ecma_arraybuffer_get_buffer (array_buf_p); ecma_number_t num;
lit_utf8_byte_t *dst_buf_p = ecma_arraybuffer_get_buffer (new_array_buf_p);
memcpy (dst_buf_p, src_buf_p + offset, length);
return new_array_buf_p; if (ecma_is_value_number (arguments_list_p[0]))
} /* ecma_arraybuffer_clone_arraybuffer */ {
num = ecma_get_number_from_value (arguments_list_p[0]);
}
else
{
ecma_value_t to_number_value = ecma_op_to_number (arguments_list_p[0]);
if (ECMA_IS_VALUE_ERROR (to_number_value))
{
return to_number_value;
}
num = ecma_get_number_from_value (to_number_value);
ecma_free_value (to_number_value);
}
length = ecma_number_to_uint32 (num);
if (num != ((ecma_number_t) length)
|| length > (UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1))
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid ArrayBuffer length."));
}
}
return ecma_make_object_value (ecma_arraybuffer_new_object (length));
} /* ecma_op_create_arraybuffer_object */
/** /**
* Helper function: check if the target is ArrayBuffer * Helper function: check if the target is ArrayBuffer
@@ -142,15 +123,9 @@ ecma_arraybuffer_clone_arraybuffer (ecma_object_t *array_buf_p, /**< the cloned
bool bool
ecma_is_arraybuffer (ecma_value_t target) /**< the target value */ ecma_is_arraybuffer (ecma_value_t target) /**< the target value */
{ {
if (!ecma_is_value_object (target)) return (ecma_is_value_object (target)
{ && ecma_object_class_is (ecma_get_object_from_value (target),
return false; LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
}
ecma_object_t *obj_p = ecma_get_object_from_value (target);
lit_magic_string_id_t class_id = ecma_object_get_class_name (obj_p);
return class_id == LIT_MAGIC_STRING_ARRAY_BUFFER_UL;
} /* ecma_is_arraybuffer */ } /* ecma_is_arraybuffer */
/** /**
@@ -34,8 +34,6 @@ ecma_op_create_arraybuffer_object (const ecma_value_t *, ecma_length_t);
*/ */
ecma_object_t * ecma_object_t *
ecma_arraybuffer_new_object (ecma_length_t lengh); ecma_arraybuffer_new_object (ecma_length_t lengh);
ecma_object_t *
ecma_arraybuffer_clone_arraybuffer (ecma_object_t *src_p, ecma_length_t offset);
lit_utf8_byte_t * lit_utf8_byte_t *
ecma_arraybuffer_get_buffer (ecma_object_t *obj_p) __attr_pure___; ecma_arraybuffer_get_buffer (ecma_object_t *obj_p) __attr_pure___;
ecma_length_t ecma_length_t
@@ -13,6 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
#include <math.h>
#include "ecma-typedarray-object.h" #include "ecma-typedarray-object.h"
#include "ecma-arraybuffer-object.h" #include "ecma-arraybuffer-object.h"
#include "ecma-function-object.h" #include "ecma-function-object.h"
@@ -39,17 +41,8 @@
* cast it from type to ecma_number_t * cast it from type to ecma_number_t
* then assign to variale number * then assign to variale number
*/ */
#define GET_ELEMENT(type, location, number) \ #define GET_ELEMENT(type, location) \
type v = *((type *) location); \ ((ecma_number_t) (*((type *) location)));
number = (ecma_number_t) v;
/**
* Cast the number from ecma_numbet_t into type,
* and store the number in the location
*/
#define SET_ELEMENT(type, location, number) \
int64_t v = (int64_t) number; \
*((type *) location) = (type) v;
/** /**
* set typedarray's element value * set typedarray's element value
@@ -60,82 +53,63 @@ static ecma_number_t
get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal arraybuffer */ get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the internal arraybuffer */
lit_magic_string_id_t class_id) /**< class name of the typedarray */ lit_magic_string_id_t class_id) /**< class name of the typedarray */
{ {
ecma_number_t ret_num;
switch (class_id) switch (class_id)
{ {
case LIT_MAGIC_STRING_INT8_ARRAY_UL: case LIT_MAGIC_STRING_INT8_ARRAY_UL:
{ {
GET_ELEMENT (int8_t, src, ret_num); return GET_ELEMENT (int8_t, src);
break;
} }
case LIT_MAGIC_STRING_UINT8_ARRAY_UL: case LIT_MAGIC_STRING_UINT8_ARRAY_UL:
case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL: case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL:
{ {
GET_ELEMENT (uint8_t, src, ret_num); return GET_ELEMENT (uint8_t, src);
break;
} }
case LIT_MAGIC_STRING_INT16_ARRAY_UL: case LIT_MAGIC_STRING_INT16_ARRAY_UL:
{ {
GET_ELEMENT (int16_t, src, ret_num); return GET_ELEMENT (int16_t, src);
break;
} }
case LIT_MAGIC_STRING_UINT16_ARRAY_UL: case LIT_MAGIC_STRING_UINT16_ARRAY_UL:
{ {
GET_ELEMENT (uint16_t, src, ret_num); return GET_ELEMENT (uint16_t, src);
break;
} }
case LIT_MAGIC_STRING_INT32_ARRAY_UL: case LIT_MAGIC_STRING_INT32_ARRAY_UL:
{ {
GET_ELEMENT (int32_t, src, ret_num); return GET_ELEMENT (int32_t, src);
break;
} }
case LIT_MAGIC_STRING_UINT32_ARRAY_UL: case LIT_MAGIC_STRING_UINT32_ARRAY_UL:
{ {
GET_ELEMENT (uint32_t, src, ret_num); return GET_ELEMENT (uint32_t, src);
break;
} }
case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL: case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL:
{ {
GET_ELEMENT (float, src, ret_num); return GET_ELEMENT (float, src);
break;
} }
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL: case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL:
{ {
GET_ELEMENT (double, src, ret_num); return GET_ELEMENT (double, src);
break;
} }
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */ #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
default: default:
{ {
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
return 0;
} }
} }
return ret_num;
} /* get_typedarray_element */ } /* get_typedarray_element */
#undef GET_ELEMENT
/** /**
* set typedarray's element value * set typedarray's element value
*/ */
static void static void
set_typedarray_element (lit_utf8_byte_t *dst, /**< the location in the internal arraybuffer */ set_typedarray_element (lit_utf8_byte_t *dst_p, /**< the location in the internal arraybuffer */
ecma_number_t value, /**< the number value to set */ ecma_number_t value, /**< the number value to set */
lit_magic_string_id_t class_id) /**< class name of the typedarray */ lit_magic_string_id_t class_id) /**< class name of the typedarray */
{ {
switch (class_id) switch (class_id)
{ {
case LIT_MAGIC_STRING_INT8_ARRAY_UL:
{
SET_ELEMENT (int8_t, dst, value);
break;
}
case LIT_MAGIC_STRING_UINT8_ARRAY_UL:
{
SET_ELEMENT (uint8_t, dst, value);
break;
}
case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL: case LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL:
{ {
uint8_t clamped; uint8_t clamped;
@@ -144,7 +118,7 @@ set_typedarray_element (lit_utf8_byte_t *dst, /**< the location in the internal
{ {
clamped = 255; clamped = 255;
} }
else if (value < 0) else if (value <= 0)
{ {
clamped = 0; clamped = 0;
} }
@@ -153,46 +127,89 @@ set_typedarray_element (lit_utf8_byte_t *dst, /**< the location in the internal
clamped = (uint8_t) value; clamped = (uint8_t) value;
if (clamped + 0.5 < value if (clamped + 0.5 < value
|| (clamped + 0.5 == value && clamped % 2 == 1)) || (clamped + 0.5 == value && (clamped % 2) == 1))
{ {
clamped ++; clamped ++;
} }
} }
*((uint8_t *) dst) = clamped; *((uint8_t *) dst_p) = clamped;
break; return;
}
case LIT_MAGIC_STRING_INT16_ARRAY_UL:
{
SET_ELEMENT (int16_t, dst, value);
break;
}
case LIT_MAGIC_STRING_UINT16_ARRAY_UL:
{
SET_ELEMENT (uint16_t, dst, value);
break;
}
case LIT_MAGIC_STRING_INT32_ARRAY_UL:
{
SET_ELEMENT (int32_t, dst, value);
break;
}
case LIT_MAGIC_STRING_UINT32_ARRAY_UL:
{
SET_ELEMENT (uint32_t, dst, value);
break;
} }
case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL: case LIT_MAGIC_STRING_FLOAT32_ARRAY_UL:
{ {
*((float *) dst) = (float) value; *((float *) dst_p) = (float) value;
break; return;
} }
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL: case LIT_MAGIC_STRING_FLOAT64_ARRAY_UL:
{ {
*((double *) dst) = (double) value; *((double *) dst_p) = (double) value;
break; return;
} }
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */ #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
default:
{
break;
}
}
uint32_t uint32_value = 0;
if (!ecma_number_is_nan (value) && !ecma_number_is_infinity (value))
{
bool is_negative = false;
if (value < 0)
{
is_negative = true;
value = -value;
}
if (value > ((ecma_number_t) 0xffffffff))
{
value = (ecma_number_t) (fmod (value, (ecma_number_t) 0x100000000));
}
uint32_value = (uint32_t) value;
if (is_negative)
{
uint32_value = (uint32_t) (-(int32_t) uint32_value);
}
}
switch (class_id)
{
case LIT_MAGIC_STRING_INT8_ARRAY_UL:
{
*((int8_t *) dst_p) = (int8_t) uint32_value;
break;
}
case LIT_MAGIC_STRING_UINT8_ARRAY_UL:
{
*((uint8_t *) dst_p) = (uint8_t) uint32_value;
break;
}
case LIT_MAGIC_STRING_INT16_ARRAY_UL:
{
*((int16_t *) dst_p) = (int16_t) uint32_value;
break;
}
case LIT_MAGIC_STRING_UINT16_ARRAY_UL:
{
*((uint16_t *) dst_p) = (uint16_t) uint32_value;
break;
}
case LIT_MAGIC_STRING_INT32_ARRAY_UL:
{
*((int32_t *) dst_p) = (int32_t) uint32_value;
break;
}
case LIT_MAGIC_STRING_UINT32_ARRAY_UL:
{
*((uint32_t *) dst_p) = uint32_value;
break;
}
default: default:
{ {
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
@@ -258,36 +275,29 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
uint8_t element_size_shift, /**< the size shift of the element length */ uint8_t element_size_shift, /**< the size shift of the element length */
lit_magic_string_id_t class_id) /**< class name of the typedarray */ lit_magic_string_id_t class_id) /**< class name of the typedarray */
{ {
ecma_object_t *object_p; ecma_length_t expected_length = (ecma_arraybuffer_get_length (arraybuffer_p) >> element_size_shift);
if (byte_offset == 0 && array_length == ecma_arraybuffer_get_length (arraybuffer_p) >> element_size_shift) bool needs_ext_typedarray_obj = (byte_offset != 0 || array_length != expected_length);
{
object_p = ecma_create_object (proto_p,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; size_t object_size = (needs_ext_typedarray_obj ? sizeof (ecma_extended_typedarray_object_t)
ext_object_p->u.pseudo_array.u1.class_id = class_id; : sizeof (ecma_extended_object_t));
ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY;
ext_object_p->u.pseudo_array.extra_info = element_size_shift;
ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p);
return ecma_make_object_value (object_p); ecma_object_t *object_p = ecma_create_object (proto_p, object_size, ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
}
object_p = ecma_create_object (proto_p,
sizeof (ecma_extended_typedarray_object_t),
ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ext_object_p->u.pseudo_array.u1.class_id = class_id; ext_object_p->u.pseudo_array.u1.class_id = class_id;
ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO; ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY;
ext_object_p->u.pseudo_array.extra_info = element_size_shift; ext_object_p->u.pseudo_array.extra_info = element_size_shift;
ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p); ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p);
ecma_extended_typedarray_object_t *typedarray_info_p = (ecma_extended_typedarray_object_t *) ext_object_p; if (needs_ext_typedarray_obj)
typedarray_info_p->array_length = array_length; {
typedarray_info_p->byte_offset = byte_offset; ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO;
ecma_extended_typedarray_object_t *typedarray_info_p = (ecma_extended_typedarray_object_t *) object_p;
typedarray_info_p->array_length = array_length;
typedarray_info_p->byte_offset = byte_offset;
}
return ecma_make_object_value (object_p); return ecma_make_object_value (object_p);
} /* ecma_typedarray_create_object_with_buffer */ } /* ecma_typedarray_create_object_with_buffer */
@@ -307,57 +317,50 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
lit_magic_string_id_t class_id) /**< class name of the typedarray */ lit_magic_string_id_t class_id) /**< class name of the typedarray */
{ {
ecma_length_t array_length = ecma_typedarray_get_length (typedarray_p); ecma_length_t array_length = ecma_typedarray_get_length (typedarray_p);
ecma_length_t byte_offset = ecma_typedarray_get_offset (typedarray_p);
ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (array_length,
proto_p,
element_size_shift,
class_id);
if (ECMA_IS_VALUE_ERROR (new_typedarray))
{
return new_typedarray;
}
ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray);
ecma_object_t *src_arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p); ecma_object_t *src_arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p);
lit_utf8_byte_t *src_buf_p = ecma_arraybuffer_get_buffer (src_arraybuffer_p);
ecma_object_t *dst_arraybuffer_p = ecma_typedarray_get_arraybuffer (new_typedarray_p);
lit_utf8_byte_t *dst_buf_p = ecma_arraybuffer_get_buffer (dst_arraybuffer_p);
src_buf_p += ecma_typedarray_get_offset (typedarray_p);
lit_magic_string_id_t src_class_id = ecma_object_get_class_name (typedarray_p); lit_magic_string_id_t src_class_id = ecma_object_get_class_name (typedarray_p);
ecma_object_t *arraybuffer_p = NULL;
if (src_class_id == class_id) if (src_class_id == class_id)
{ {
arraybuffer_p = ecma_arraybuffer_clone_arraybuffer (src_arraybuffer_p, memcpy (dst_buf_p, src_buf_p, array_length << element_size_shift);
byte_offset);
} }
else else
{ {
if (array_length > (UINT32_MAX >> element_size_shift)) uint32_t src_element_size = 1u << ecma_typedarray_get_element_size_shift (typedarray_p);
{ uint32_t dst_element_size = 1u << element_size_shift;
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
}
ecma_length_t byte_length = array_length << element_size_shift;
if (byte_length > UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum typedarray size is reached."));
}
arraybuffer_p = ecma_arraybuffer_new_object (byte_length);
lit_utf8_byte_t *src_buf = ecma_arraybuffer_get_buffer (src_arraybuffer_p);
lit_utf8_byte_t *dst_buf = ecma_arraybuffer_get_buffer (arraybuffer_p);
uint8_t src_element_size_shift = ecma_typedarray_get_element_size_shift (typedarray_p);
for (uint32_t i = 0; i < array_length; i++) for (uint32_t i = 0; i < array_length; i++)
{ {
ecma_number_t tmp = get_typedarray_element (src_buf, /* Convert values from source to destination format. */
ecma_object_get_class_name (typedarray_p)); ecma_number_t tmp = get_typedarray_element (src_buf_p, src_class_id);
/** check dst type and set value to dst typedarray */ set_typedarray_element (dst_buf_p, tmp, class_id);
set_typedarray_element (dst_buf, tmp, class_id);
src_buf = src_buf + (1 << src_element_size_shift); src_buf_p += src_element_size;
dst_buf = dst_buf + (1 << element_size_shift); dst_buf_p += dst_element_size;
} }
} }
ecma_value_t obj = ecma_typedarray_create_object_with_buffer (arraybuffer_p, return new_typedarray;
0,
array_length,
proto_p,
element_size_shift,
class_id);
ecma_deref_object (arraybuffer_p);
return obj;
} /* ecma_typedarray_create_object_with_typedarray */ } /* ecma_typedarray_create_object_with_typedarray */
/** /**
@@ -388,17 +391,18 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
} }
/* 10 */ /* 10 */
ECMA_TRY_CATCH (arraylike, ECMA_TRY_CATCH (arraylike_object_val,
ecma_op_to_object (items_val), ecma_op_to_object (items_val),
ret_value); ret_value);
ecma_object_t *arraylike_p = ecma_get_object_from_value (arraylike); ecma_object_t *arraylike_object_p = ecma_get_object_from_value (arraylike_object_val);
/* 12 */ /* 12 */
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ecma_string_t magic_string_length;
ecma_init_ecma_length_string (&magic_string_length);
ECMA_TRY_CATCH (len_value, ECMA_TRY_CATCH (len_value,
ecma_op_object_get (arraylike_p, magic_string_length_p), ecma_op_object_get (arraylike_object_p, &magic_string_length),
ret_value); ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value); ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
@@ -427,7 +431,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
/* 17.b */ /* 17.b */
ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_p, index_str_p), ret_value); ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_object_p, index_str_p), ret_value);
if (ecma_is_value_found (current_value)) if (ecma_is_value_found (current_value))
{ {
@@ -476,8 +480,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
ECMA_OP_TO_NUMBER_FINALIZE (len_number); ECMA_OP_TO_NUMBER_FINALIZE (len_number);
ECMA_FINALIZE (len_value); ECMA_FINALIZE (len_value);
ecma_deref_ecma_string (magic_string_length_p); ECMA_FINALIZE (arraylike_object_val);
ECMA_FINALIZE (arraylike);
return ret_value; return ret_value;
} /* ecma_op_typedarray_from */ } /* ecma_op_typedarray_from */
@@ -13,12 +13,22 @@
* limitations under the License. * limitations under the License.
*/ */
var a = new Int32Array(3); var a = new Int32Array(8);
a[0] = 0xffffffff; a[0] = 0xffffffff;
a[1] = 0xff00000001; a[1] = 0xff00000001;
a[2] = -2.3; a[2] = 0xff80000001;
a[3] = -2.3;
a[4] = Number.NEGATIVE_INFINITY;
a[5] = NaN;
a[6] = 10e17;
a[7] = -10e17;
assert(a[0] === -1); assert(a[0] === -1);
assert(a[1] === 1); assert(a[1] === 1);
assert(a[2] === -2); assert(a[2] === -2147483647);
assert(a[3] === -2);
assert(a[4] === 0);
assert(a[5] === 0);
assert(a[6] === -1486618624);
assert(a[7] === 1486618624);