@@ -5923,7 +5923,8 @@ jerry_value_is_arraybuffer (const jerry_value_t value) /**< value to check if it
5923
5923
* @return value of the constructed ArrayBuffer object
5924
5924
*/
5925
5925
jerry_value_t
5926
- jerry_create_arraybuffer (const jerry_length_t size ) /**< size of the ArrayBuffer to create */
5926
+ jerry_create_arraybuffer (const jerry_length_t size ) /**< size of the backing store allocated
5927
+ * for the array buffer in bytes */
5927
5928
{
5928
5929
jerry_assert_api_available ();
5929
5930
@@ -5944,32 +5945,41 @@ jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffe
5944
5945
* * if the typed arrays are disabled this will return a TypeError.
5945
5946
* * if the size is zero or buffer_p is a null pointer this will return an empty ArrayBuffer.
5946
5947
*
5947
- * @return value of the construced ArrayBuffer object
5948
+ * @return value of the newly construced array buffer object
5948
5949
*/
5949
5950
jerry_value_t
5950
- jerry_create_arraybuffer_external (const jerry_length_t size , /**< size of the buffer to used */
5951
- uint8_t * buffer_p , /**< buffer to use as the ArrayBuffer's backing */
5952
- jerry_value_free_callback_t free_cb ) /**< buffer free callback */
5951
+ jerry_create_arraybuffer_external (const jerry_length_t size , /**< size of the buffer in bytes */
5952
+ uint8_t * buffer_p , /**< the backing store used by the array buffer object */
5953
+ void * arraybuffer_user_p ) /**< user pointer assigned to the array buffer object */
5953
5954
{
5954
5955
jerry_assert_api_available ();
5955
5956
5956
5957
#if JERRY_BUILTIN_TYPEDARRAY
5957
- ecma_object_t * arraybuffer ;
5958
+ ecma_object_t * arraybuffer_p ;
5958
5959
5959
- if (JERRY_UNLIKELY (size == 0 || buffer_p == NULL ))
5960
+ if (JERRY_UNLIKELY (size == 0 ))
5960
5961
{
5961
- arraybuffer = ecma_arraybuffer_new_object (0 );
5962
+ arraybuffer_p = ecma_arraybuffer_new_object (0 );
5962
5963
}
5963
5964
else
5964
5965
{
5965
- arraybuffer = ecma_arraybuffer_new_object_external (size , buffer_p , free_cb );
5966
+ arraybuffer_p = ecma_arraybuffer_create_object_with_buffer (ECMA_OBJECT_CLASS_ARRAY_BUFFER , size );
5967
+
5968
+ ecma_arraybuffer_pointer_t * arraybuffer_pointer_p = (ecma_arraybuffer_pointer_t * ) arraybuffer_p ;
5969
+ arraybuffer_pointer_p -> arraybuffer_user_p = arraybuffer_user_p ;
5970
+
5971
+ if (buffer_p != NULL )
5972
+ {
5973
+ arraybuffer_pointer_p -> extended_object .u .cls .u1 .array_buffer_flags |= ECMA_ARRAYBUFFER_ALLOCATED ;
5974
+ arraybuffer_pointer_p -> buffer_p = buffer_p ;
5975
+ }
5966
5976
}
5967
5977
5968
- return jerry_return (ecma_make_object_value (arraybuffer ));
5978
+ return jerry_return (ecma_make_object_value (arraybuffer_p ));
5969
5979
#else /* !JERRY_BUILTIN_TYPEDARRAY */
5970
5980
JERRY_UNUSED (size );
5971
5981
JERRY_UNUSED (buffer_p );
5972
- JERRY_UNUSED (free_cb );
5982
+ JERRY_UNUSED (arraybuffer_user_p );
5973
5983
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_typed_array_not_supported_p )));
5974
5984
#endif /* JERRY_BUILTIN_TYPEDARRAY */
5975
5985
} /* jerry_create_arraybuffer_external */
@@ -5999,7 +6009,8 @@ jerry_value_is_shared_arraybuffer (const jerry_value_t value) /**< value to chec
5999
6009
* @return value of the constructed SharedArrayBuffer object
6000
6010
*/
6001
6011
jerry_value_t
6002
- jerry_create_shared_arraybuffer (const jerry_length_t size ) /**< size of the SharedArrayBuffer to create */
6012
+ jerry_create_shared_arraybuffer (const jerry_length_t size ) /**< size of the backing store allocated
6013
+ * for the shared array buffer in bytes */
6003
6014
{
6004
6015
jerry_assert_api_available ();
6005
6016
@@ -6020,32 +6031,43 @@ jerry_create_shared_arraybuffer (const jerry_length_t size) /**< size of the Sha
6020
6031
* * if the typed arrays are disabled this will return a TypeError.
6021
6032
* * if the size is zero or buffer_p is a null pointer this will return an empty SharedArrayBuffer.
6022
6033
*
6023
- * @return value of the construced SharedArrayBuffer object
6034
+ * @return value of the newly construced shared array buffer object
6024
6035
*/
6025
6036
jerry_value_t
6026
- jerry_create_shared_arraybuffer_external (const jerry_length_t size , /**< size of the buffer to used */
6027
- uint8_t * buffer_p , /**< buffer to use as the SharedArrayBuffer's backing */
6028
- jerry_value_free_callback_t free_cb ) /**< buffer free callback */
6037
+ jerry_create_shared_arraybuffer_external (const jerry_length_t size , /**< size of the buffer in bytes */
6038
+ uint8_t * buffer_p , /**< the backing store used by the
6039
+ * shared array buffer object */
6040
+ void * arraybuffer_user_p ) /**< user pointer assigned to the
6041
+ * shared array buffer object */
6029
6042
{
6030
6043
jerry_assert_api_available ();
6031
6044
6032
6045
#if JERRY_BUILTIN_SHAREDARRAYBUFFER
6033
- ecma_object_t * shared_arraybuffer ;
6046
+ ecma_object_t * shared_arraybuffer_p ;
6034
6047
6035
- if (JERRY_UNLIKELY (size == 0 || buffer_p == NULL ))
6048
+ if (JERRY_UNLIKELY (size == 0 ))
6036
6049
{
6037
- shared_arraybuffer = ecma_shared_arraybuffer_new_object (0 );
6050
+ shared_arraybuffer_p = ecma_shared_arraybuffer_new_object (0 );
6038
6051
}
6039
6052
else
6040
6053
{
6041
- shared_arraybuffer = ecma_shared_arraybuffer_new_object_external (size , buffer_p , free_cb );
6054
+ shared_arraybuffer_p = ecma_arraybuffer_create_object_with_buffer (ECMA_OBJECT_CLASS_SHARED_ARRAY_BUFFER , size );
6055
+
6056
+ ecma_arraybuffer_pointer_t * shared_arraybuffer_pointer_p = (ecma_arraybuffer_pointer_t * ) shared_arraybuffer_p ;
6057
+ shared_arraybuffer_pointer_p -> arraybuffer_user_p = arraybuffer_user_p ;
6058
+
6059
+ if (buffer_p != NULL )
6060
+ {
6061
+ shared_arraybuffer_pointer_p -> extended_object .u .cls .u1 .array_buffer_flags |= ECMA_ARRAYBUFFER_ALLOCATED ;
6062
+ shared_arraybuffer_pointer_p -> buffer_p = buffer_p ;
6063
+ }
6042
6064
}
6043
6065
6044
- return jerry_return (ecma_make_object_value (shared_arraybuffer ));
6066
+ return jerry_return (ecma_make_object_value (shared_arraybuffer_p ));
6045
6067
#else /* !JERRY_BUILTIN_SHAREDARRAYBUFFER */
6046
6068
JERRY_UNUSED (size );
6047
6069
JERRY_UNUSED (buffer_p );
6048
- JERRY_UNUSED (free_cb );
6070
+ JERRY_UNUSED (arraybuffer_user_p );
6049
6071
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_shared_arraybuffer_not_supported_p )));
6050
6072
#endif /* JERRY_BUILTIN_SHAREDARRAYBUFFER */
6051
6073
} /* jerry_create_shared_arraybuffer_external */
@@ -6073,6 +6095,13 @@ jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer or S
6073
6095
}
6074
6096
6075
6097
ecma_object_t * buffer_p = ecma_get_object_from_value (value );
6098
+
6099
+ if (ECMA_ARRAYBUFFER_CHECK_BUFFER_ERROR (buffer_p ))
6100
+ {
6101
+ jerry_release_value (jcontext_take_exception ());
6102
+ return 0 ;
6103
+ }
6104
+
6076
6105
jerry_length_t length = ecma_arraybuffer_get_length (buffer_p );
6077
6106
6078
6107
if (offset >= length )
@@ -6122,6 +6151,13 @@ jerry_arraybuffer_read (const jerry_value_t value, /**< ArrayBuffer or SharedArr
6122
6151
}
6123
6152
6124
6153
ecma_object_t * buffer_p = ecma_get_object_from_value (value );
6154
+
6155
+ if (ECMA_ARRAYBUFFER_CHECK_BUFFER_ERROR (buffer_p ))
6156
+ {
6157
+ jerry_release_value (jcontext_take_exception ());
6158
+ return 0 ;
6159
+ }
6160
+
6125
6161
jerry_length_t length = ecma_arraybuffer_get_length (buffer_p );
6126
6162
6127
6163
if (offset >= length )
@@ -6191,15 +6227,19 @@ jerry_get_arraybuffer_pointer (const jerry_value_t array_buffer) /**< Array Buff
6191
6227
jerry_assert_api_available ();
6192
6228
6193
6229
#if JERRY_BUILTIN_TYPEDARRAY
6194
- if (ecma_is_value_error_reference (array_buffer )
6195
- || !(ecma_is_arraybuffer (array_buffer ) || ecma_is_shared_arraybuffer (array_buffer )))
6230
+ if (!(ecma_is_arraybuffer (array_buffer ) || ecma_is_shared_arraybuffer (array_buffer )))
6196
6231
{
6197
6232
return NULL ;
6198
6233
}
6199
6234
6200
6235
ecma_object_t * buffer_p = ecma_get_object_from_value (array_buffer );
6201
- lit_utf8_byte_t * mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p );
6202
- return (uint8_t * const ) mem_buffer_p ;
6236
+
6237
+ if (!(ECMA_ARRAYBUFFER_GET_FLAGS (buffer_p ) & ECMA_ARRAYBUFFER_ALLOCATED ))
6238
+ {
6239
+ return NULL ;
6240
+ }
6241
+
6242
+ return (uint8_t * ) ecma_arraybuffer_get_buffer (buffer_p );
6203
6243
#else /* !JERRY_BUILTIN_TYPEDARRAY */
6204
6244
JERRY_UNUSED (array_buffer );
6205
6245
#endif /* JERRY_BUILTIN_TYPEDARRAY */
@@ -6222,7 +6262,7 @@ jerry_is_arraybuffer_detachable (const jerry_value_t value) /**< ArrayBuffer */
6222
6262
if (ecma_is_arraybuffer (value ))
6223
6263
{
6224
6264
ecma_object_t * buffer_p = ecma_get_object_from_value (value );
6225
- return ecma_arraybuffer_is_detached (buffer_p ) ? ECMA_VALUE_FALSE : ECMA_VALUE_TRUE ;
6265
+ return ecma_make_boolean_value (! ecma_arraybuffer_is_detached (buffer_p )) ;
6226
6266
}
6227
6267
#else /* !JERRY_BUILTIN_TYPEDARRAY */
6228
6268
JERRY_UNUSED (value );
@@ -6233,8 +6273,8 @@ jerry_is_arraybuffer_detachable (const jerry_value_t value) /**< ArrayBuffer */
6233
6273
/**
6234
6274
* Detach the underlying data block from ArrayBuffer and set its bytelength to 0.
6235
6275
*
6236
- * Note: If the ArrayBuffer has been created with `jerry_create_arraybuffer_external`
6237
- * the optional free callback is called on a successful detach operation
6276
+ * Note: if the ArrayBuffer has a separate data buffer, the free callback set by
6277
+ * jerry_arraybuffer_set_allocation_callbacks is called for this buffer
6238
6278
*
6239
6279
* @return null value - if success
6240
6280
* value marked with error flag - otherwise
@@ -6260,6 +6300,83 @@ jerry_detach_arraybuffer (const jerry_value_t value) /**< ArrayBuffer */
6260
6300
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Expected an ArrayBuffer" )));
6261
6301
} /* jerry_detach_arraybuffer */
6262
6302
6303
+ /**
6304
+ * Checks whether a buffer is currently allocated for an array buffer or typed array.
6305
+ *
6306
+ * @return true, if a buffer is allocated for an array buffer or typed array
6307
+ * false, otherwise
6308
+ */
6309
+ bool
6310
+ jerry_arraybuffer_has_buffer (const jerry_value_t value ) /**< array buffer or typed array value */
6311
+ {
6312
+ jerry_assert_api_available ();
6313
+
6314
+ #if JERRY_BUILTIN_TYPEDARRAY
6315
+ if (!ecma_is_value_object (value ))
6316
+ {
6317
+ return false;
6318
+ }
6319
+
6320
+ ecma_object_t * object_p = ecma_get_object_from_value (value );
6321
+
6322
+ if (ecma_object_is_typedarray (object_p ))
6323
+ {
6324
+ object_p = ecma_typedarray_get_arraybuffer (object_p );
6325
+ }
6326
+ else if (!(ecma_object_class_is (object_p , ECMA_OBJECT_CLASS_ARRAY_BUFFER )
6327
+ || ecma_object_is_shared_arraybuffer (object_p )))
6328
+ {
6329
+ return false;
6330
+ }
6331
+
6332
+ return (ECMA_ARRAYBUFFER_GET_FLAGS (object_p ) & ECMA_ARRAYBUFFER_ALLOCATED ) != 0 ;
6333
+ #else /* !JERRY_BUILTIN_TYPEDARRAY */
6334
+ JERRY_UNUSED (value );
6335
+ return false;
6336
+ #endif /* JERRY_BUILTIN_TYPEDARRAY */
6337
+ } /* jerry_arraybuffer_has_buffer */
6338
+
6339
+ /**
6340
+ * Array buffers which size is less or equal than the limit passed to this function are allocated in
6341
+ * a single memory block. The allocator callbacks set by jerry_arraybuffer_set_allocation_callbacks
6342
+ * are not called for these array buffers. The default limit is 256 bytes.
6343
+ */
6344
+ void
6345
+ jerry_arraybuffer_set_compact_allocation_limit (const jerry_length_t allocation_limit ) /**< maximum size of
6346
+ * compact allocation */
6347
+ {
6348
+ jerry_assert_api_available ();
6349
+
6350
+ #if JERRY_BUILTIN_TYPEDARRAY
6351
+ JERRY_CONTEXT (arraybuffer_compact_allocation_limit ) = allocation_limit ;
6352
+ #else /* !JERRY_BUILTIN_TYPEDARRAY */
6353
+ JERRY_UNUSED (allocation_limit );
6354
+ #endif /* JERRY_BUILTIN_TYPEDARRAY */
6355
+ } /* jerry_arraybuffer_set_compact_allocation_limit */
6356
+
6357
+ /**
6358
+ * Set callbacks for allocating and freeing backing stores for array buffer objects.
6359
+ */
6360
+ void
6361
+ jerry_arraybuffer_set_allocator_callbacks (jerry_arraybuffer_allocate_t allocate_callback , /**< callback for allocating
6362
+ * array buffer memory */
6363
+ jerry_arraybuffer_free_t free_callback , /**< callback for freeing
6364
+ * array buffer memory */
6365
+ void * user_p ) /**< user pointer passed to the callbacks */
6366
+ {
6367
+ jerry_assert_api_available ();
6368
+
6369
+ #if JERRY_BUILTIN_TYPEDARRAY
6370
+ JERRY_CONTEXT (arraybuffer_allocate_callback ) = allocate_callback ;
6371
+ JERRY_CONTEXT (arraybuffer_free_callback ) = free_callback ;
6372
+ JERRY_CONTEXT (arraybuffer_allocate_callback_user_p ) = user_p ;
6373
+ #else /* !JERRY_BUILTIN_TYPEDARRAY */
6374
+ JERRY_UNUSED (allocate_callback );
6375
+ JERRY_UNUSED (free_callback );
6376
+ JERRY_UNUSED (user_p );
6377
+ #endif /* JERRY_BUILTIN_TYPEDARRAY */
6378
+ } /* jerry_arraybuffer_set_allocator_callbacks */
6379
+
6263
6380
/**
6264
6381
* DataView related functions
6265
6382
*/
0 commit comments