Add ArrayBuffer detach operations (#3208)

JerryScript-DCO-1.0-Signed-off-by: legendecas legendecas@gmail.com
This commit is contained in:
legendecas
2019-10-16 22:41:27 +08:00
committed by Dániel Bátyai
parent 09c5d98e25
commit 2e86bdae6f
11 changed files with 375 additions and 2 deletions
@@ -203,6 +203,79 @@ ecma_arraybuffer_get_buffer (ecma_object_t *object_p) /**< pointer to the ArrayB
}
} /* ecma_arraybuffer_get_buffer */
/**
* Helper function: check if the target ArrayBuffer is detached
*
* @return true - if value is an detached ArrayBuffer object
* false - otherwise
*/
inline bool JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_arraybuffer_is_detached (ecma_object_t *object_p) /**< pointer to the ArrayBuffer object */
{
JERRY_ASSERT (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (ext_object_p))
{
ecma_arraybuffer_external_info *array_p = (ecma_arraybuffer_external_info *) ext_object_p;
/* in case the arraybuffer has been detached */
return array_p->buffer_p == NULL;
}
return false;
} /* ecma_arraybuffer_is_detached */
/**
* Helper function: check if the target ArrayBuffer is detachable
*
* @return true - if value is an detachable ArrayBuffer object
* false - otherwise
*/
inline bool JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_arraybuffer_is_detachable (ecma_object_t *object_p) /**< pointer to the ArrayBuffer object */
{
JERRY_ASSERT (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (ext_object_p))
{
ecma_arraybuffer_external_info *array_p = (ecma_arraybuffer_external_info *) ext_object_p;
/* in case the arraybuffer has been detached */
return array_p->buffer_p != NULL;
}
return false;
} /* ecma_arraybuffer_is_detachable */
/**
* ArrayBuffer object detaching operation
*
* See also: ES2015 24.1.1.3
*
* @return true - if detach op succeeded
* false - otherwise
*/
inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_arraybuffer_detach (ecma_object_t *object_p) /**< pointer to the ArrayBuffer object */
{
JERRY_ASSERT (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
if (!ecma_arraybuffer_is_detachable (object_p))
{
return false;
}
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_arraybuffer_external_info *array_object_p = (ecma_arraybuffer_external_info *) ext_object_p;
array_object_p->buffer_p = NULL;
array_object_p->extended_object.u.class_prop.u.length = 0;
return true;
} /* ecma_arraybuffer_detach */
/**
* @}
* @}
@@ -43,6 +43,12 @@ lit_utf8_byte_t * JERRY_ATTR_PURE
ecma_arraybuffer_get_buffer (ecma_object_t *obj_p);
ecma_length_t JERRY_ATTR_PURE
ecma_arraybuffer_get_length (ecma_object_t *obj_p);
bool JERRY_ATTR_PURE
ecma_arraybuffer_is_detached (ecma_object_t *obj_p);
bool JERRY_ATTR_PURE
ecma_arraybuffer_is_detachable (ecma_object_t *obj_p);
bool
ecma_arraybuffer_detach (ecma_object_t *obj_p);
bool
ecma_is_arraybuffer (ecma_value_t val);
@@ -84,7 +84,11 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li
}
}
/* 8. TODO: Throw TypeError, when Detached ArrayBuffer will be supported. */
/* 8. */
if (ecma_arraybuffer_is_detached (buffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
/* 9. */
ecma_length_t buffer_byte_length = ecma_arraybuffer_get_length (buffer_p);
@@ -284,6 +288,10 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi
/* 9. */
ecma_object_t *buffer_p = view_p->buffer_p;
JERRY_ASSERT (ecma_object_class_is (buffer_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
if (ecma_arraybuffer_is_detached (buffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
/* 10. */
uint32_t view_offset = view_p->byte_offset;
@@ -544,6 +544,10 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
uint8_t element_size_shift, /**< the size shift of the element length */
ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */
{
if (ecma_arraybuffer_is_detached (arraybuffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
ecma_length_t expected_length = (ecma_arraybuffer_get_length (arraybuffer_p) >> element_size_shift);
bool needs_ext_typedarray_obj = (byte_offset != 0 || array_length != expected_length);
@@ -586,6 +590,11 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */
{
ecma_length_t array_length = ecma_typedarray_get_length (typedarray_p);
ecma_object_t *src_arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p);
if (ecma_arraybuffer_is_detached (src_arraybuffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid detached ArrayBuffer."));
}
ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (array_length,
proto_p,
@@ -599,7 +608,6 @@ ecma_typedarray_create_object_with_typedarray (ecma_object_t *typedarray_p, /**<
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);
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);
@@ -825,6 +833,12 @@ ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the
return buffer_length >> shift;
}
ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p);
if (ecma_arraybuffer_is_detached (arraybuffer_p))
{
return 0;
}
ecma_extended_typedarray_object_t *info_p = (ecma_extended_typedarray_object_t *) ext_object_p;
return info_p->array_length;
@@ -847,6 +861,12 @@ ecma_typedarray_get_offset (ecma_object_t *typedarray_p) /**< the pointer to the
return 0;
}
ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p);
if (ecma_arraybuffer_is_detached (arraybuffer_p))
{
return 0;
}
ecma_extended_typedarray_object_t *info_p = (ecma_extended_typedarray_object_t *) ext_object_p;
return info_p->byte_offset;
@@ -947,6 +967,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
{
ret = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset."));
}
else if (ecma_arraybuffer_is_detached (arraybuffer_p))
{
ret = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid detached ArrayBuffer."));
}
else
{
ecma_length_t buf_byte_length = ecma_arraybuffer_get_length (arraybuffer_p);