Skip to content

Commit 91baa17

Browse files
author
Tóth Béla
authored
Update TypedArray builtins to latest standard (#4210)
- Introduce `ecma_typedarray_species_create` and `ecma_typedarray_create` - Update Typedarray's filter method JerryScript-DCO-1.0-Signed-off-by: Bela Toth [email protected]
1 parent b46535c commit 91baa17

File tree

4 files changed

+124
-114
lines changed

4 files changed

+124
-114
lines changed

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this object *
204204
ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val);
205205

206206
// TODO: 22.2.3.18, 7-8.
207-
ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (src_info_p->id, src_info_p->length);
207+
ecma_value_t len = ecma_make_number_value (src_info_p->length);
208+
ecma_value_t new_typedarray = ecma_typedarray_species_create (this_arg, &len, 1);
209+
ecma_free_value (len);
208210

209211
if (ECMA_IS_VALUE_ERROR (new_typedarray))
210212
{
@@ -427,7 +429,9 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this objec
427429

428430
uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> info_p->shift);
429431

430-
ret_value = ecma_op_create_typedarray_with_type_and_length (info_p->id, pass_num);
432+
ecma_value_t collected = ecma_make_number_value (pass_num);
433+
ret_value = ecma_typedarray_species_create (this_arg, &collected, 1);
434+
ecma_free_value (collected);
431435

432436
if (!ECMA_IS_VALUE_ERROR (ret_value))
433437
{
@@ -868,7 +872,8 @@ ecma_builtin_typedarray_prototype_join (ecma_object_t *obj_p, /**< this object *
868872
* Returned value must be freed with ecma_free_value.
869873
*/
870874
static ecma_value_t
871-
ecma_builtin_typedarray_prototype_subarray (ecma_typedarray_info_t *info_p, /**< object info */
875+
ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this object */
876+
ecma_typedarray_info_t *info_p, /**< object info */
872877
ecma_value_t begin, /**< begin */
873878
ecma_value_t end) /**< end */
874879
{
@@ -918,7 +923,7 @@ ecma_builtin_typedarray_prototype_subarray (ecma_typedarray_info_t *info_p, /**<
918923
ecma_make_uint32_value (subarray_length)
919924
};
920925

921-
ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, info_p->id);
926+
ret_value = ecma_typedarray_species_create (this_arg, arguments_p, 3);
922927

923928
ecma_free_value (arguments_p[1]);
924929
ecma_free_value (arguments_p[2]);
@@ -1489,7 +1494,8 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this
14891494
* Returned value must be freed with ecma_free_value.
14901495
*/
14911496
static ecma_value_t
1492-
ecma_builtin_typedarray_prototype_slice (ecma_typedarray_info_t *info_p, /**< object info */
1497+
ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argument */
1498+
ecma_typedarray_info_t *info_p, /**< object info */
14931499
const ecma_value_t args[], /**< arguments list */
14941500
uint32_t args_number) /**< number of arguments */
14951501
{
@@ -1518,8 +1524,10 @@ ecma_builtin_typedarray_prototype_slice (ecma_typedarray_info_t *info_p, /**< ob
15181524
int32_t distance = (int32_t) (relative_end - relative_start);
15191525
uint32_t count = distance > 0 ? (uint32_t) distance : 0;
15201526

1527+
ecma_value_t len = ecma_make_number_value (count);
15211528
// TODO: 22.2.3.23, 12-13.
1522-
ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (info_p->id, count);
1529+
ecma_value_t new_typedarray = ecma_typedarray_species_create (this_arg, &len, 1);
1530+
ecma_free_value (len);
15231531

15241532
if (ECMA_IS_VALUE_ERROR (new_typedarray))
15251533
{
@@ -1763,7 +1771,6 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id,
17631771
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FILTER:
17641772
{
17651773
return ecma_builtin_typedarray_prototype_filter (this_arg, &info, arguments_list_p[0], arguments_list_p[1]);
1766-
17671774
}
17681775
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_REVERSE:
17691776
{
@@ -1775,7 +1782,7 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id,
17751782
}
17761783
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_SUBARRAY:
17771784
{
1778-
return ecma_builtin_typedarray_prototype_subarray (&info, arguments_list_p[0], arguments_list_p[1]);
1785+
return ecma_builtin_typedarray_prototype_subarray (this_arg, &info, arguments_list_p[0], arguments_list_p[1]);
17791786
}
17801787
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FILL:
17811788
{
@@ -1819,7 +1826,7 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id,
18191826
}
18201827
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_SLICE:
18211828
{
1822-
return ecma_builtin_typedarray_prototype_slice (&info, arguments_list_p, arguments_number);
1829+
return ecma_builtin_typedarray_prototype_slice (this_arg, &info, arguments_list_p, arguments_number);
18231830
}
18241831
case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_TO_LOCALE_STRING:
18251832
{

jerry-core/ecma/operations/ecma-typedarray-object.c

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
13901390
: ECMA_VALUE_UNDEFINED);
13911391

13921392
ecma_number_t offset;
1393-
if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg2, &offset)))
1393+
if (ECMA_IS_VALUE_ERROR (ecma_op_to_index (arg2, &offset)))
13941394
{
13951395
return ECMA_VALUE_ERROR;
13961396
}
@@ -1616,6 +1616,107 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob
16161616
return ECMA_VALUE_TRUE;
16171617
} /* ecma_op_typedarray_define_index_prop */
16181618

1619+
/**
1620+
* Specify the creation of a new TypedArray
1621+
* object using a constructor function.
1622+
*
1623+
* See also: ES11 22.2.4.6
1624+
*
1625+
* Used by:
1626+
* - ecma_typedarray_species_create
1627+
*
1628+
* @return ecma_value_t function object from created from constructor_p argument
1629+
*/
1630+
1631+
ecma_value_t
1632+
ecma_typedarray_create (ecma_object_t *constructor_p, /**< constructor function */
1633+
ecma_value_t *arguments_list_p, /**< argument list */
1634+
uint32_t arguments_list_len) /**< length of argument list */
1635+
{
1636+
ecma_value_t ret_val = ecma_op_function_construct (constructor_p,
1637+
constructor_p,
1638+
arguments_list_p,
1639+
arguments_list_len);
1640+
if (ECMA_IS_VALUE_ERROR (ret_val))
1641+
{
1642+
return ret_val;
1643+
}
1644+
1645+
if (!ecma_is_typedarray (ret_val))
1646+
{
1647+
ecma_free_value (ret_val);
1648+
return ecma_raise_type_error (ECMA_ERR_MSG ("Constructed object is not TypedArray."));
1649+
}
1650+
1651+
ecma_object_t *typedarray_p = ecma_get_object_from_value (ret_val);
1652+
1653+
if ((arguments_list_len == 1) && (ecma_is_value_number (arguments_list_p[0])))
1654+
{
1655+
ecma_number_t num = ecma_get_number_from_value (arguments_list_p[0]);
1656+
ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p);
1657+
1658+
if (info.length < num)
1659+
{
1660+
ecma_free_value (ret_val);
1661+
return ecma_raise_type_error (ECMA_ERR_MSG ("Constructed typedarray is smaller than filter call result"));
1662+
}
1663+
}
1664+
return ret_val;
1665+
} /* ecma_typedarray_create */
1666+
1667+
/* Specify the creation of a new TypedArray object
1668+
* using a constructor function that is derived from this_arg.
1669+
*
1670+
* See also: ES11 22.2.4.7
1671+
*
1672+
* @return ecma value of the new typedarray object, constructed by default or species constructor
1673+
*/
1674+
ecma_value_t
1675+
ecma_typedarray_species_create (ecma_value_t this_arg, /**< this argument */
1676+
ecma_value_t *arguments_list_p, /**< the arg list passed to typedarray construct */
1677+
uint32_t arguments_list_len) /**< length of the the arg list */
1678+
{
1679+
ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg);
1680+
ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p);
1681+
1682+
JERRY_ASSERT (ecma_is_typedarray (this_arg));
1683+
1684+
ecma_builtin_id_t default_constructor = ecma_typedarray_helper_get_constructor_id (info.id);
1685+
1686+
ecma_value_t constructor = ecma_op_species_constructor (typedarray_p, default_constructor);
1687+
1688+
if (ECMA_IS_VALUE_ERROR (constructor))
1689+
{
1690+
return constructor;
1691+
}
1692+
1693+
ecma_object_t *constructor_proto_p = ecma_get_object_from_value (constructor);
1694+
1695+
ecma_value_t result = ecma_typedarray_create (constructor_proto_p, arguments_list_p, arguments_list_len);
1696+
ecma_deref_object (constructor_proto_p);
1697+
1698+
if (ECMA_IS_VALUE_ERROR (result))
1699+
{
1700+
return result;
1701+
}
1702+
1703+
#if ENABLED (JERRY_BUILTIN_BIGINT)
1704+
ecma_object_t *result_p = ecma_get_object_from_value (result);
1705+
ecma_typedarray_info_t result_info = ecma_typedarray_get_info (result_p);
1706+
/*
1707+
* Check result_info.id to to be either bigint type if info.id is one
1708+
* or be neither of them is info.id is none of them as well.
1709+
*/
1710+
if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id) ^ ECMA_TYPEDARRAY_IS_BIGINT_TYPE (result_info.id))
1711+
{
1712+
ecma_free_value (result);
1713+
return ecma_raise_type_error (ECMA_ERR_MSG ("Source and result array does not match in [[ContentType]]"));
1714+
}
1715+
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
1716+
1717+
return result;
1718+
} /* ecma_typedarray_species_create */
1719+
16191720
/**
16201721
* Create a typedarray object based on the "type" and arraylength
16211722
* The "type" is same with arg1

jerry-core/ecma/operations/ecma-typedarray-object.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ ecma_value_t ecma_typedarray_create_object_with_length (uint32_t array_length,
7777
ecma_object_t *proto_p,
7878
uint8_t element_size_shift,
7979
ecma_typedarray_type_t typedarray_id);
80+
ecma_value_t ecma_typedarray_create (ecma_object_t *constructor_p, ecma_value_t *arguments_list_p,
81+
uint32_t arguments_list_len);
82+
ecma_value_t ecma_typedarray_species_create (ecma_value_t this_arg,
83+
ecma_value_t *length,
84+
uint32_t arguments_list_len);
8085

8186
/**
8287
* @}

0 commit comments

Comments
 (0)