mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add ArrayBuffer with user specified buffer
New API functions: - jerry_create_arraybuffer_external - jerry_get_arraybuffer_pointer JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
This commit is contained in:
parent
7acd688513
commit
4b699e997a
@ -1030,6 +1030,7 @@ jerry_value_is_arraybuffer (const jerry_value_t value)
|
||||
**See also**
|
||||
|
||||
- [jerry_create_arraybuffer](#jerry_create_arraybuffer)
|
||||
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)
|
||||
|
||||
|
||||
## jerry_value_is_boolean
|
||||
@ -2465,6 +2466,56 @@ jerry_create_arraybuffer (jerry_length_t size);
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
|
||||
|
||||
## jerry_create_arraybuffer_external
|
||||
|
||||
**Summary**
|
||||
|
||||
Creates a jerry_value_t representing an ArrayBuffer object with
|
||||
user specified back-buffer.
|
||||
|
||||
User must pass a buffer pointer which is at least `size` big.
|
||||
After the object is not needed the GC will call the `free_cb`
|
||||
so the user can release the buffer which was provided.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_create_arraybuffer_external (const jerry_length_t size
|
||||
uint8_t *buffer_p,
|
||||
jerry_object_native_free_callback_t free_cb);
|
||||
```
|
||||
|
||||
- `size` - size of the buffer to use **in bytes** (should not be 0)
|
||||
- `buffer_p` - the buffer used for the Array Buffer object (should not be a null pointer)
|
||||
- `free_cb` - the callback function called when the object is released
|
||||
- return value
|
||||
- the new ArrayBuffer as a `jerry_value_t`
|
||||
- if the `size` is zero or `buffer_p` is a null pointer will return RangeError
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
{
|
||||
uint8_t buffer_p[15];
|
||||
jerry_value_t buffer_value = jerry_create_arraybuffer_external (15, buffer_p, NULL);
|
||||
|
||||
... // use the array buffer
|
||||
|
||||
jerry_release_value (buffer_value);
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_get_arraybuffer_pointer](#jerry_get_arraybuffer_pointer)
|
||||
- [jerry_arraybuffer_read](#jerry_arraybuffer_read)
|
||||
- [jerry_arraybuffer_write](#jerry_arraybuffer_write)
|
||||
- [jerry_value_is_arraybuffer](#jerry_value_is_arraybuffer)
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
- [jerry_object_native_free_callback_t](#jerry_object_native_free_callback_t)
|
||||
|
||||
|
||||
## jerry_create_boolean
|
||||
|
||||
**Summary**
|
||||
@ -4921,3 +4972,61 @@ jerry_arraybuffer_write (const jerry_value_t value,
|
||||
- [jerry_create_arraybuffer](#jerry_create_arraybuffer)
|
||||
- [jerry_arraybuffer_write](#jerry_arraybuffer_write)
|
||||
- [jerry_get_arraybuffer_byte_length](#jerry_get_arraybuffer_byte_length)
|
||||
|
||||
|
||||
## jerry_get_arraybuffer_pointer
|
||||
|
||||
**Summary**
|
||||
|
||||
The function allows access to the contents of the Array Buffer directly.
|
||||
Only allowed for Array Buffers which were created with
|
||||
[jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)
|
||||
function calls. In any other case this function will return `NULL`.
|
||||
|
||||
After using the pointer the [jerry_release_value](#jerry_release_value)
|
||||
function must be called.
|
||||
|
||||
**WARNING!** This operation is for expert use only! The programmer must
|
||||
ensure that the returned memory area is used correctly. That is
|
||||
there is no out of bounds reads or writes.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
uint8_t *
|
||||
jerry_get_arraybuffer_pointer (const jerry_value_t value);
|
||||
```
|
||||
|
||||
- `value` - Array Buffer object.
|
||||
- return value
|
||||
- pointer to the Array Buffer's data area.
|
||||
- NULL if the `value` is not an Array Buffer object with external memory.
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t buffer;
|
||||
|
||||
// acquire buffer somewhere which was created by a jerry_create_array_buffer_external call.
|
||||
|
||||
uint8_t *const data = jerry_get_arraybuffer_pointer (buffer);
|
||||
|
||||
for (int i = 0; i < 22; i++)
|
||||
{
|
||||
data[i] = (uint8_t) (i + 4);
|
||||
}
|
||||
|
||||
// required after jerry_get_arraybuffer_pointer call.
|
||||
jerry_release_value (buffer);
|
||||
|
||||
// use the Array Buffer
|
||||
|
||||
// release buffer as it is not needed after this point
|
||||
jerry_release_value (buffer);
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)
|
||||
|
||||
@ -2670,6 +2670,42 @@ jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffe
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
} /* jerry_create_arraybuffer */
|
||||
|
||||
/**
|
||||
* Creates an ArrayBuffer object with user specified buffer.
|
||||
*
|
||||
* Notes:
|
||||
* * the size is specified in bytes.
|
||||
* * the buffer passed should be at least the specified bytes big.
|
||||
* * if the typed arrays are disabled this will return a TypeError.
|
||||
* * if the size is zero or the buffer_p is a null pointer this will return a RangeError.
|
||||
*
|
||||
* @return value of the construced ArrayBuffer object
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */
|
||||
uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */
|
||||
jerry_object_native_free_callback_t free_cb) /**< buffer free callback */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
|
||||
if (size == 0 || buffer_p == NULL)
|
||||
{
|
||||
return jerry_throw (ecma_raise_range_error (ECMA_ERR_MSG ("invalid buffer size or storage reference")));
|
||||
}
|
||||
|
||||
ecma_object_t *arraybuffer = ecma_arraybuffer_new_object_external (size,
|
||||
buffer_p,
|
||||
(ecma_object_native_free_callback_t) free_cb);
|
||||
return jerry_return (ecma_make_object_value (arraybuffer));
|
||||
#else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
JERRY_UNUSED (size);
|
||||
JERRY_UNUSED (buffer_p);
|
||||
JERRY_UNUSED (free_cb);
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer not supported.")));
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
} /* jerry_create_arraybuffer_external */
|
||||
|
||||
/**
|
||||
* Copy bytes into the ArrayBuffer from a buffer.
|
||||
*
|
||||
@ -2798,6 +2834,45 @@ jerry_get_arraybuffer_byte_length (const jerry_value_t value) /**< ArrayBuffer *
|
||||
return 0;
|
||||
} /* jerry_get_arraybuffer_byte_length */
|
||||
|
||||
/**
|
||||
* Get a pointer for the start of the ArrayBuffer.
|
||||
*
|
||||
* Note:
|
||||
* * Only valid for ArrayBuffers created with jerry_create_arraybuffer_external.
|
||||
* * This is a high-risk operation as the bounds are not checked
|
||||
* when accessing the pointer elements.
|
||||
* * jerry_release_value must be called on the ArrayBuffer when the pointer is no longer needed.
|
||||
*
|
||||
* @return pointer to the back-buffer of the ArrayBuffer.
|
||||
* pointer is NULL if the parameter is not an ArrayBuffer with external memory
|
||||
or it is not an ArrayBuffer at all.
|
||||
*/
|
||||
uint8_t *
|
||||
jerry_get_arraybuffer_pointer (const jerry_value_t value) /**< Array Buffer to use */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
|
||||
jerry_value_t buffer = jerry_get_arg_value (value);
|
||||
|
||||
if (!ecma_is_arraybuffer (buffer))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
|
||||
if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (buffer_p))
|
||||
{
|
||||
jerry_acquire_value (value);
|
||||
lit_utf8_byte_t *mem_buffer_p = ecma_arraybuffer_get_buffer (buffer_p);
|
||||
return (uint8_t *const) mem_buffer_p;
|
||||
}
|
||||
#else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
JERRY_UNUSED (value);
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
|
||||
return NULL;
|
||||
} /* jerry_get_arraybuffer_pointer */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -570,11 +570,29 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
case LIT_MAGIC_STRING_ARRAY_BUFFER_UL:
|
||||
{
|
||||
ecma_length_t arraybuffer_length = ext_object_p->u.class_prop.u.length;
|
||||
size_t size = sizeof (ecma_extended_object_t) + arraybuffer_length;
|
||||
size_t size;
|
||||
|
||||
if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (ext_object_p))
|
||||
{
|
||||
size = sizeof (ecma_arraybuffer_external_info);
|
||||
|
||||
/* Call external free callback if any. */
|
||||
ecma_arraybuffer_external_info *array_p = (ecma_arraybuffer_external_info *) ext_object_p;
|
||||
JERRY_ASSERT (array_p != NULL);
|
||||
|
||||
if (array_p->free_cb != NULL)
|
||||
{
|
||||
(array_p->free_cb) (array_p->buffer_p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sizeof (ecma_extended_object_t) + arraybuffer_length;
|
||||
}
|
||||
|
||||
ecma_dealloc_extended_object (object_p, size);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||
case LIT_MAGIC_STRING_PROMISE_UL:
|
||||
|
||||
@ -712,6 +712,8 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
uint16_t class_id; /**< class id of the object */
|
||||
uint16_t extra_info; /**< extra information for the object
|
||||
e.g. array buffer type info (external/internal) */
|
||||
|
||||
/*
|
||||
* Description of extra fields. These extra fields depends on the class_id.
|
||||
@ -1243,6 +1245,33 @@ typedef struct
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
|
||||
|
||||
/**
|
||||
* Extra information for ArrayBuffers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_ARRAYBUFFER_INTERNAL_MEMORY = 0u, /* ArrayBuffer memory is handled internally. */
|
||||
ECMA_ARRAYBUFFER_EXTERNAL_MEMORY = (1u << 0), /* ArrayBuffer created via jerry_create_arraybuffer_external. */
|
||||
} ecma_arraybuffer_extra_flag_t;
|
||||
|
||||
#define ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY(object_p) \
|
||||
((((ecma_extended_object_t *) object_p)->u.class_prop.extra_info & ECMA_ARRAYBUFFER_EXTERNAL_MEMORY) != 0)
|
||||
|
||||
/**
|
||||
* Struct to store information for ArrayBuffers with external memory.
|
||||
*
|
||||
* The following elements are stored in Jerry memory.
|
||||
*
|
||||
* buffer_p - pointer to the external memory.
|
||||
* free_cb - pointer to a callback function which is called when the ArrayBuffer is freed.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_extended_object_t extended_object; /**< extended object part */
|
||||
void *buffer_p; /**< external buffer pointer */
|
||||
ecma_object_native_free_callback_t free_cb; /**< the free callback for the above buffer pointer */
|
||||
} ecma_arraybuffer_external_info;
|
||||
|
||||
/**
|
||||
* Some internal properties of TypedArray object.
|
||||
* It is only used when the offset is not 0, and
|
||||
|
||||
@ -51,6 +51,7 @@ ecma_arraybuffer_new_object (ecma_length_t length) /**< length of the arraybuffe
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ext_object_p->u.class_prop.extra_info = ECMA_ARRAYBUFFER_INTERNAL_MEMORY;
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_ARRAY_BUFFER_UL;
|
||||
ext_object_p->u.class_prop.u.length = length;
|
||||
|
||||
@ -60,6 +61,38 @@ ecma_arraybuffer_new_object (ecma_length_t length) /**< length of the arraybuffe
|
||||
return object_p;
|
||||
} /* ecma_arraybuffer_new_object */
|
||||
|
||||
/**
|
||||
* Helper function: create arraybuffer object with external buffer backing.
|
||||
*
|
||||
* The struct of external arraybuffer object:
|
||||
* ecma_object_t
|
||||
* extend_part
|
||||
* arraybuffer external info part
|
||||
*
|
||||
* @return ecma_object_t *, pointer to the created ArrayBuffer object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_arraybuffer_new_object_external (ecma_length_t length, /**< length of the buffer_p to use */
|
||||
void *buffer_p, /**< pointer for ArrayBuffer's buffer backing */
|
||||
ecma_object_native_free_callback_t free_cb) /**< buffer free callback */
|
||||
{
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE);
|
||||
ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
|
||||
sizeof (ecma_arraybuffer_external_info),
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
ecma_arraybuffer_external_info *array_object_p = (ecma_arraybuffer_external_info *) object_p;
|
||||
array_object_p->extended_object.u.class_prop.extra_info = ECMA_ARRAYBUFFER_EXTERNAL_MEMORY;
|
||||
array_object_p->extended_object.u.class_prop.class_id = LIT_MAGIC_STRING_ARRAY_BUFFER_UL;
|
||||
array_object_p->extended_object.u.class_prop.u.length = length;
|
||||
|
||||
array_object_p->buffer_p = buffer_p;
|
||||
array_object_p->free_cb = free_cb;
|
||||
|
||||
return object_p;
|
||||
} /* ecma_arraybuffer_new_object_external */
|
||||
|
||||
|
||||
/**
|
||||
* ArrayBuffer object creation operation.
|
||||
*
|
||||
@ -158,7 +191,16 @@ ecma_arraybuffer_get_buffer (ecma_object_t *object_p) /**< pointer to the ArrayB
|
||||
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;
|
||||
return (lit_utf8_byte_t *) (ext_object_p + 1);
|
||||
|
||||
if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (ext_object_p))
|
||||
{
|
||||
ecma_arraybuffer_external_info *array_p = (ecma_arraybuffer_external_info *) ext_object_p;
|
||||
return (lit_utf8_byte_t *) array_p->buffer_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (lit_utf8_byte_t *) (ext_object_p + 1);
|
||||
}
|
||||
} /* ecma_arraybuffer_get_buffer */
|
||||
|
||||
/**
|
||||
|
||||
@ -34,6 +34,10 @@ ecma_op_create_arraybuffer_object (const ecma_value_t *, ecma_length_t);
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_arraybuffer_new_object (ecma_length_t lengh);
|
||||
ecma_object_t *
|
||||
ecma_arraybuffer_new_object_external (ecma_length_t length,
|
||||
void *buffer_p,
|
||||
ecma_object_native_free_callback_t free_cb);
|
||||
lit_utf8_byte_t *
|
||||
ecma_arraybuffer_get_buffer (ecma_object_t *obj_p) __attr_pure___;
|
||||
ecma_length_t
|
||||
|
||||
@ -446,6 +446,9 @@ void jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, voi
|
||||
*/
|
||||
bool jerry_value_is_arraybuffer (const jerry_value_t value);
|
||||
jerry_value_t jerry_create_arraybuffer (const jerry_length_t size);
|
||||
jerry_value_t jerry_create_arraybuffer_external (const jerry_length_t size,
|
||||
uint8_t *buffer_p,
|
||||
jerry_object_native_free_callback_t free_cb);
|
||||
jerry_length_t jerry_arraybuffer_write (const jerry_value_t value,
|
||||
jerry_length_t offset,
|
||||
const uint8_t *buf_p,
|
||||
@ -455,6 +458,7 @@ jerry_length_t jerry_arraybuffer_read (const jerry_value_t value,
|
||||
uint8_t *buf_p,
|
||||
jerry_length_t buf_size);
|
||||
jerry_length_t jerry_get_arraybuffer_byte_length (const jerry_value_t value);
|
||||
uint8_t *jerry_get_arraybuffer_pointer (const jerry_value_t value);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@ -129,7 +129,6 @@ static void test_write_with_offset (uint8_t offset) /**< offset for buffer write
|
||||
jerry_value_t offset_val = jerry_create_number (offset);
|
||||
register_js_value ("offset", offset_val);
|
||||
jerry_release_value (offset_val);
|
||||
|
||||
}
|
||||
|
||||
const char *eval_arraybuffer_src_p = "var array = new Uint8Array (15); array.buffer";
|
||||
@ -145,7 +144,7 @@ static void test_write_with_offset (uint8_t offset) /**< offset for buffer write
|
||||
|
||||
for (uint8_t i = 0; i < 20; i++)
|
||||
{
|
||||
buffer[i] = (uint8_t)(i * 3);
|
||||
buffer[i] = (uint8_t) (i * 3);
|
||||
}
|
||||
|
||||
/* Intentionally copy more than the allowed space. */
|
||||
@ -170,6 +169,14 @@ static void test_write_with_offset (uint8_t offset) /**< offset for buffer write
|
||||
jerry_release_value (arraybuffer);
|
||||
} /* test_write_with_offset */
|
||||
|
||||
static bool callback_called = false;
|
||||
|
||||
static void test_free_cb (void *buffer) /**< buffer to free (if needed) */
|
||||
{
|
||||
(void) buffer;
|
||||
callback_called = true;
|
||||
} /* test_free_cb */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
@ -259,5 +266,128 @@ main (void)
|
||||
jerry_release_value (arraybuffer);
|
||||
}
|
||||
|
||||
/* Test ArrayBuffer with buffer allocated externally */
|
||||
{
|
||||
const uint32_t buffer_size = 15;
|
||||
const uint8_t base_value = 51;
|
||||
|
||||
uint8_t buffer_p[buffer_size];
|
||||
memset (buffer_p, base_value, buffer_size);
|
||||
|
||||
jerry_value_t arrayb = jerry_create_arraybuffer_external (buffer_size, buffer_p, test_free_cb);
|
||||
uint8_t new_value = 123;
|
||||
jerry_length_t copied = jerry_arraybuffer_write (arrayb, 0, &new_value, 1);
|
||||
TEST_ASSERT (copied == 1);
|
||||
TEST_ASSERT (buffer_p[0] == new_value);
|
||||
TEST_ASSERT (jerry_get_arraybuffer_byte_length (arrayb) == buffer_size);
|
||||
|
||||
for (uint32_t i = 1; i < buffer_size; i++)
|
||||
{
|
||||
TEST_ASSERT (buffer_p[i] == base_value);
|
||||
}
|
||||
|
||||
uint8_t test_buffer[buffer_size];
|
||||
jerry_length_t read = jerry_arraybuffer_read (arrayb, 0, test_buffer, buffer_size);
|
||||
TEST_ASSERT (read == buffer_size);
|
||||
TEST_ASSERT (test_buffer[0] == new_value);
|
||||
|
||||
for (uint32_t i = 1; i < buffer_size; i++)
|
||||
{
|
||||
TEST_ASSERT (test_buffer[i] == base_value);
|
||||
}
|
||||
|
||||
TEST_ASSERT (jerry_value_is_arraybuffer (arrayb));
|
||||
jerry_release_value (arrayb);
|
||||
}
|
||||
|
||||
/* Test ArrayBuffer external memory map/unmap */
|
||||
{
|
||||
const uint32_t buffer_size = 20;
|
||||
uint8_t buffer_p[buffer_size];
|
||||
{
|
||||
jerry_value_t input_buffer = jerry_create_arraybuffer_external (buffer_size, buffer_p, NULL);
|
||||
register_js_value ("input_buffer", input_buffer);
|
||||
jerry_release_value (input_buffer);
|
||||
}
|
||||
|
||||
const char *eval_arraybuffer_src_p = (
|
||||
"var array = new Uint8Array(input_buffer);"
|
||||
"for (var i = 0; i < array.length; i++)"
|
||||
"{"
|
||||
" array[i] = i * 2;"
|
||||
"};"
|
||||
"array.buffer");
|
||||
jerry_value_t buffer = jerry_eval ((jerry_char_t *) eval_arraybuffer_src_p,
|
||||
strlen (eval_arraybuffer_src_p),
|
||||
true);
|
||||
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (buffer));
|
||||
TEST_ASSERT (jerry_value_is_arraybuffer (buffer));
|
||||
TEST_ASSERT (jerry_get_arraybuffer_byte_length (buffer) == 20);
|
||||
|
||||
uint8_t *const data = jerry_get_arraybuffer_pointer (buffer);
|
||||
|
||||
/* test memory read */
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
TEST_ASSERT (data[i] == (uint8_t) (i * 2));
|
||||
}
|
||||
|
||||
/* "upload" new data */
|
||||
double sum = 0;
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
data[i] = (uint8_t)(i * 3);
|
||||
sum += data[i];
|
||||
}
|
||||
|
||||
jerry_release_value (buffer);
|
||||
|
||||
const char *eval_test_arraybuffer_p = (
|
||||
"var sum = 0;"
|
||||
"for (var i = 0; i < array.length; i++)"
|
||||
"{"
|
||||
" var expected = i * 3;"
|
||||
" assert(array[i] == expected, 'Array at index ' + i + ' was: ' + array[i] + ' should be: ' + expected);"
|
||||
" sum += array[i]"
|
||||
"};"
|
||||
"sum");
|
||||
jerry_value_t res = jerry_eval ((jerry_char_t *) eval_test_arraybuffer_p,
|
||||
strlen (eval_test_arraybuffer_p),
|
||||
true);
|
||||
TEST_ASSERT (jerry_value_is_number (res));
|
||||
TEST_ASSERT (jerry_get_number_value (res) == sum);
|
||||
jerry_release_value (res);
|
||||
|
||||
jerry_release_value (buffer);
|
||||
}
|
||||
|
||||
/* Test ArrayBuffer external with invalid arguments */
|
||||
{
|
||||
jerry_value_t input_buffer = jerry_create_arraybuffer_external (0, NULL, NULL);
|
||||
TEST_ASSERT (jerry_value_has_error_flag (input_buffer));
|
||||
jerry_value_clear_error_flag (&input_buffer);
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES))
|
||||
{
|
||||
jerry_char_t error_str[15];
|
||||
jerry_char_t expected_error_str[15] = "RangeError";
|
||||
|
||||
jerry_char_t *name_str_p = (jerry_char_t *) "name";
|
||||
jerry_value_t name_key = jerry_create_string (name_str_p);
|
||||
jerry_value_t name_value = jerry_get_property (input_buffer, name_key);
|
||||
|
||||
jerry_size_t name_size = jerry_string_to_char_buffer (name_value, error_str, sizeof (error_str));
|
||||
TEST_ASSERT (name_size == strlen ((char *) expected_error_str));
|
||||
TEST_ASSERT (strncmp ((char *) error_str, (char *) expected_error_str, name_size) == 0);
|
||||
|
||||
jerry_release_value (name_value);
|
||||
jerry_release_value (name_key);
|
||||
}
|
||||
jerry_release_value (input_buffer);
|
||||
}
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
TEST_ASSERT (callback_called == true);
|
||||
} /* main */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user