diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 780e5fd4e6..107a9c189b 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -4756,23 +4756,11 @@ jerry_set_prototype (const jerry_value_t obj_val, **Summary** -Get native pointer and its type information. +Get native pointer by the given type information. The pointer and the type information are previously associated with the object by jerry_set_object_native_pointer. -*Note*: It is recommended to ensure that the `out_native_info_p` value pointer - is equal to the native info pointer that is expected, before casting - and accessing the `out_native_pointer_p`. - An example of when this is important: external functions that expect - `this` to have a native pointer of a certain C type. - It is possible in JavaScript to change `this` at will – using `call()`, - `apply()` or `bind()`. Therefore, it is possible that the native pointer - of `this` is not of the expected C type. To handle this safely and - securely, one must always add type checks to make sure that the - `out_native_pointer_p` is of the expected type, before casting - and dereferencing `out_native_pointer_p`. - -*Note*: `out_native_pointer_p` and `out_native_info_p` can be NULL, and it means the - caller doesn't want to get the native_pointer or type information. +*Note*: `out_native_pointer_p` can be NULL, and it means the + caller doesn't want to get the native_pointer. **Prototype** @@ -4780,73 +4768,185 @@ The pointer and the type information are previously associated with the object b bool jerry_get_object_native_pointer (const jerry_value_t obj_val, void **out_native_pointer_p, - const jerry_object_native_info_t **out_native_info_p) + const jerry_object_native_info_t *native_info_p) ``` - `obj_val` - object value to get native pointer from. - `out_native_pointer_p` - native pointer (output parameter). -- `out_native_info_p` - native pointer's type information (output parameter). +- `native_info_p` - native pointer's type information. - return value - - true, if there is native pointer associated with the object + - true, if there is native pointer associated of the specified object with the given native type info - false, otherwise **Example** +[doctest]: # () + ```c -typedef struct { - int foo; - bool bar; -} native_obj_t; +#include +#include +#include +#include "jerryscript.h" -static void native_freecb (void *native_p) +typedef struct { - ... // free the native pointer + char *data_p; + unsigned int length; +} buffer_native_object_t; + +typedef struct +{ + int area; + int perimeter; +} shape_native_object_t; + +#define SECRET_INFO ((void *) 42) + +static void +buffer_native_freecb (void *native_p) +{ + char *data_p = ((buffer_native_object_t*)native_p)->data_p; + + if (data_p != NULL) + { + free (data_p); + } + + free (native_p); +} + +static void +shape_native_freecb (void *native_p) +{ + free (native_p); +} + +static void +destructor_freecb (void *native_p) +{ + printf("Note: the object has been freed\n"); } // NOTE: The address (!) of type_info acts as a way to uniquely "identify" the -// C type `native_obj_t *`. -static const jerry_object_native_info_t native_obj_type_info = +// C type `buffer_native_object_t *`. +static const jerry_object_native_info_t buffer_obj_type_info = { - .free_cb = native_freecb + .free_cb = buffer_native_freecb }; -// Function creating JS object that is "backed" by a native_obj_t *: +// NOTE: The address (!) of type_info acts as a way to uniquely "identify" the +// C type `shape_native_object_t *`. +static const jerry_object_native_info_t shape_obj_type_info = { - ... + .free_cb = shape_native_freecb +}; - // construct object and native_set value: - jerry_value_t object = ...; - native_obj_t *native_obj = malloc(sizeof(*native_obj)); - jerry_set_object_native_pointer (object, native_obj, &native_obj_type_info); +// NOTE: The address (!) of type_info is the unique "identifier" +static const jerry_object_native_info_t destructor_obj_type_info = +{ + .free_cb = destructor_freecb +}; - ... +static void +print_buffer (char *data_p, + unsigned int length) +{ + for (unsigned int i = 0; i < length; ++i) + { + printf("%c", data_p[i]); + } + + printf("\n"); } -// Native method, `this` is expected to be "backed" by a native_obj_t *: +static void +do_stuff (jerry_value_t object) { void *native_p; - const jerry_object_native_info_t *type_p; - bool has_p = jerry_get_object_native_pointer (this_val, &native_p, &type_p); + bool has_p = jerry_get_object_native_pointer (object, &native_p, &buffer_obj_type_info); + + if (!has_p) + { + // Process the error + return; + } + + // It is safe to cast to buffer_native_object_t * and dereference the pointer: + buffer_native_object_t *buffer_p = (buffer_native_object_t *) native_p; + print_buffer (buffer_p->data_p, buffer_p->length); // Usage of buffer_p + + bool need_shape_info = true; // implementation dependent - if (has_p) + if (need_shape_info) { - // The type_p pointer address itself is used to identify the type: - if (type_p == &native_obj_type_info) + has_p = jerry_get_object_native_pointer (object, &native_p, &shape_obj_type_info); + + if (!has_p) { - // The type of this's native pointer matches what is expected. - // Only now is it safe to cast to native_obj_t * and dereference the - // pointer: - native_obj_t *native_obj = native_p; - native_obj->bar = ...; // Safe to access now! + // Process the error + return; } - else + + // It is safe to cast to shape_native_object_t * and dereference the pointer: + shape_native_object_t *shape_p = (shape_native_object_t *) native_p; + + printf("Area: %d\tPerimeter: %d\n", shape_p->area, shape_p->perimeter); // Usage of shape_p + } + + bool need_secret_info = true; // implementation dependent + + if (need_secret_info) + { + has_p = jerry_get_object_native_pointer (object, &native_p, NULL); + + if (!has_p) + { + // Process the error + return; + } + + printf("Secret: %d\n", (int)((uintptr_t) native_p)); // Usage of native_p + + bool deleted = jerry_delete_object_native_pointer (object, NULL); + + if (deleted) { - // The type of this's native pointer is NOT what we expected! - // We should not cast to native_obj_t * and dereference because it's unsafe. - // Handle the error here, for example throw an error. + printf("The secret is no longer available\n"); } } - ... +} + +int +main (void) +{ + jerry_init (JERRY_INIT_EMPTY); + + jerry_value_t object = jerry_create_object (); + buffer_native_object_t *buffer_p = (buffer_native_object_t *) malloc (sizeof (buffer_native_object_t)); + buffer_p->length = 14; + buffer_p->data_p = (char *) malloc (buffer_p->length * sizeof (char)); + memcpy (buffer_p->data_p, "My buffer data", buffer_p->length); + jerry_set_object_native_pointer (object, buffer_p, &buffer_obj_type_info); + + shape_native_object_t *shape_p = (shape_native_object_t *) malloc (sizeof (shape_native_object_t)); + shape_p->area = 6; + shape_p->perimeter = 12; + jerry_set_object_native_pointer (object, shape_p, &shape_obj_type_info); + + // The native pointer can be NULL. This gives possibily to get notified via the native type info's + // free callback when the object has been freed by the GC. + jerry_set_object_native_pointer (object, NULL, &destructor_obj_type_info); + + // The native type info can be NULL as well. In this case the registered property is simply freed + // when the object is freed by te GC. + jerry_set_object_native_pointer (object, SECRET_INFO, NULL); + + do_stuff (object); + + jerry_release_value (object); + jerry_cleanup (); + + return 0; } ``` @@ -4897,6 +4997,40 @@ best-practice example. - [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) - [jerry_object_native_info_t](#jerry_object_native_info_t) +## jerry_delete_object_native_pointer + +**Summary** + +Delete the native pointer of the specified object associated with the given native type info. +You can get them by calling jerry_get_object_native_pointer later. + +*Note*: + - If the specified object has no matching native pointer for the given native type info the operation has no effect. + - This operation cannot throw an exception. + +**Prototype** + +```c +bool +jerry_delete_object_native_pointer (const jerry_value_t obj_val, + const jerry_object_native_info_t *info_p) +``` + +- `obj_val` - object to delete native pointer from. +- `info_p` - native pointer's type information. + +**Example** + +See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a +best-practice example. + +**See also** + +- [jerry_create_object](#jerry_create_object) +- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) +- [jerry_get_object_native_pointer](#jerry_set_object_native_pointer) +- [jerry_object_native_info_t](#jerry_object_native_info_t) + ## jerry_foreach_object_property diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 5cc072115e..c2097804e0 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -2591,9 +2591,8 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i { if (!ecma_is_lexical_environment (iter_p)) { - native_pointer_p = ecma_get_native_pointer_value (iter_p); + native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p); if (native_pointer_p - && ((const jerry_object_native_info_t *) native_pointer_p->info_p) == native_info_p && !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p)) { return true; @@ -2605,11 +2604,10 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i } /* jerry_objects_foreach_by_native_info */ /** - * Get native pointer and its type information, associated with specified object. + * Get native pointer and its type information, associated with the given native type info. * * Note: - * If native pointer is present, its type information is returned - * in out_native_pointer_p and out_native_info_p. + * If native pointer is present, its type information is returned in out_native_pointer_p * * @return true - if there is an associated pointer, * false - otherwise @@ -2617,8 +2615,8 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i bool jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get native pointer from */ void **out_native_pointer_p, /**< [out] native pointer */ - const jerry_object_native_info_t **out_native_info_p) /**< [out] the type info - * of the native pointer */ + const jerry_object_native_info_t *native_info_p) /**< the type info + * of the native pointer */ { jerry_assert_api_available (); @@ -2628,7 +2626,7 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get } ecma_native_pointer_t *native_pointer_p; - native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val)); + native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val), (void *) native_info_p); if (native_pointer_p == NULL) { @@ -2640,11 +2638,6 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get *out_native_pointer_p = native_pointer_p->data_p; } - if (out_native_info_p != NULL) - { - *out_native_info_p = (const jerry_object_native_info_t *) native_pointer_p->info_p; - } - return true; } /* jerry_get_object_native_pointer */ @@ -2676,6 +2669,35 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set } } /* jerry_set_object_native_pointer */ +/** + * Delete the previously set native pointer by the native type info from the specified object. + * + * Note: + * If the specified object has no matching native pointer for the given native type info + * the function has no effect. + * + * Note: + * This operation cannot throw an exception. + * + * @return true - if the native pointer has been deleted succesfully + * false - otherwise + */ +bool +jerry_delete_object_native_pointer (const jerry_value_t obj_val, /**< object to delete native pointer from */ + const jerry_object_native_info_t *native_info_p) /**< object's native type info */ +{ + jerry_assert_api_available (); + + if (ecma_is_value_object (obj_val)) + { + ecma_object_t *object_p = ecma_get_object_from_value (obj_val); + + return ecma_delete_native_pointer_property (object_p, (void *) native_info_p); + } + + return false; +} /* jerry_delete_object_native_pointer */ + /** * Applies the given function to the every property in the object. * diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 60dc357c57..7c0e984436 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -501,17 +501,24 @@ ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */ native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value); - if (native_pointer_p->info_p != NULL) + while (native_pointer_p != NULL) { - ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb; - - if (free_cb != NULL) + if (native_pointer_p->info_p != NULL) { - free_cb (native_pointer_p->data_p); + ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb; + + if (free_cb != NULL) + { + free_cb (native_pointer_p->data_p); + } } - } - jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t)); + ecma_native_pointer_t *next_p = native_pointer_p->next_p; + + jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t)); + + native_pointer_p = next_p; + } } /* ecma_gc_free_native_pointer */ /** diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index a115b08d44..c403e699db 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -294,10 +294,11 @@ typedef struct /** * Representation for native pointer data. */ -typedef struct +typedef struct ecma_native_pointer_t { void *data_p; /**< points to the data of the object */ ecma_object_native_info_t *info_p; /**< native info */ + struct ecma_native_pointer_t *next_p; /**< points to the next ecma_native_pointer_t element */ } ecma_native_pointer_t; /** diff --git a/jerry-core/ecma/base/ecma-helpers-external-pointers.c b/jerry-core/ecma/base/ecma-helpers-external-pointers.c index 0fb4421f2b..6ac1b283e4 100644 --- a/jerry-core/ecma/base/ecma-helpers-external-pointers.c +++ b/jerry-core/ecma/base/ecma-helpers-external-pointers.c @@ -15,6 +15,7 @@ #include "ecma-alloc.h" #include "ecma-globals.h" +#include "ecma-objects.h" #include "ecma-helpers.h" /** \addtogroup ecma ECMA @@ -42,10 +43,10 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create ecma_native_pointer_t *native_pointer_p; - if (is_new) + if (property_p == NULL) { ecma_property_value_t *value_p; - value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_FLAG_WRITABLE, &property_p); + value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_CONFIGURABLE_WRITABLE, &property_p); ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p); @@ -57,11 +58,37 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create { ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value); + ecma_native_pointer_t *iter_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value); + + /* There should be at least 1 native pointer in the chain */ + JERRY_ASSERT (iter_p != NULL); + + while (true) + { + if (iter_p->info_p == info_p) + { + /* The native info already exists -> update the corresponding data */ + iter_p->data_p = native_p; + return false; + } + + if (iter_p->next_p == NULL) + { + /* The native info does not exist -> append a new element to the chain */ + break; + } + + iter_p = iter_p->next_p; + } + + native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t)); + + iter_p->next_p = native_pointer_p; } native_pointer_p->data_p = native_p; native_pointer_p->info_p = info_p; + native_pointer_p->next_p = NULL; return is_new; } /* ecma_create_native_pointer_property */ @@ -77,7 +104,8 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create * NULL otherwise */ ecma_native_pointer_t * -ecma_get_native_pointer_value (ecma_object_t *obj_p) /**< object to get property value from */ +ecma_get_native_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */ + void *info_p) /**< native pointer's type info */ { ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); @@ -89,9 +117,94 @@ ecma_get_native_pointer_value (ecma_object_t *obj_p) /**< object to get property ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p); - return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value); + ecma_native_pointer_t *native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, + value_p->value); + + JERRY_ASSERT (native_pointer_p != NULL); + + while (native_pointer_p != NULL) + { + if (native_pointer_p->info_p == info_p) + { + return native_pointer_p; + } + + native_pointer_p = native_pointer_p->next_p; + } + + return NULL; } /* ecma_get_native_pointer_value */ +/** + * Delete the previously set native pointer by the native type info from the specified object. + * + * Note: + * If the specified object has no matching native pointer for the given native type info + * the function has no effect. + * + * @return true - if the native pointer has been deleted succesfully + * false - otherwise + */ +bool +ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete property from */ + void *info_p) /**< native pointer's type info */ +{ + ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER); + ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); + + if (property_p == NULL) + { + return false; + } + + ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p); + + ecma_native_pointer_t *native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, + value_p->value); + ecma_native_pointer_t *prev_p = NULL; + + JERRY_ASSERT (native_pointer_p != NULL); + + while (native_pointer_p != NULL) + { + if (native_pointer_p->info_p == info_p) + { + if (prev_p == NULL) + { + if (native_pointer_p->next_p == NULL) + { + /* Only one native pointer property exists, so the property can be deleted as well. */ + ecma_op_object_delete (obj_p, name_p, false); + jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t)); + return true; + } + else + { + /* There are at least two native pointers and the first one should be deleted. + In this case the second element's data is copied to the head of the chain, and freed as well. */ + ecma_native_pointer_t *next_p = native_pointer_p->next_p; + memcpy (native_pointer_p, next_p, sizeof (ecma_native_pointer_t)); + jmem_heap_free_block (next_p, sizeof (ecma_native_pointer_t)); + return true; + } + } + else + { + /* There are at least two native pointers and not the first element should be deleted. + In this case the current element's next element reference is copied to the previous element. */ + prev_p->next_p = native_pointer_p->next_p; + jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t)); + return true; + } + } + + prev_p = native_pointer_p; + native_pointer_p = native_pointer_p->next_p; + } + + return false; +} /* ecma_delete_native_pointer_property */ + /** * @} * @} diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 233635338f..eb6a0d2aee 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -389,7 +389,8 @@ void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p); /* ecma-helpers-external-pointers.c */ bool ecma_create_native_pointer_property (ecma_object_t *obj_p, void *native_p, void *info_p); -ecma_native_pointer_t *ecma_get_native_pointer_value (ecma_object_t *obj_p); +ecma_native_pointer_t *ecma_get_native_pointer_value (ecma_object_t *obj_p, void *info_p); +bool ecma_delete_native_pointer_property (ecma_object_t *obj_p, void *info_p); /* ecma-helpers-conversion.c */ ecma_number_t ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, lit_utf8_size_t str_size); diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 2bec6dd94a..b6dc7601c9 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -527,10 +527,12 @@ jerry_value_t jerry_set_prototype (const jerry_value_t obj_val, const jerry_valu bool jerry_get_object_native_pointer (const jerry_value_t obj_val, void **out_native_pointer_p, - const jerry_object_native_info_t **out_pointer_info_p); + const jerry_object_native_info_t *native_pointer_info_p); void jerry_set_object_native_pointer (const jerry_value_t obj_val, void *native_pointer_p, const jerry_object_native_info_t *native_info_p); +bool jerry_delete_object_native_pointer (const jerry_value_t obj_val, + const jerry_object_native_info_t *native_info_p); bool jerry_objects_foreach (jerry_objects_foreach_t foreach_p, void *user_data); diff --git a/jerry-ext/arg/arg-transform-functions.c b/jerry-ext/arg/arg-transform-functions.c index 64edf2d0c1..6c5132d8d1 100644 --- a/jerry-ext/arg/arg-transform-functions.c +++ b/jerry-ext/arg/arg-transform-functions.c @@ -455,12 +455,11 @@ jerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p, /* } const jerry_object_native_info_t *expected_info_p; - const jerry_object_native_info_t *out_info_p; expected_info_p = (const jerry_object_native_info_t *) c_arg_p->extra_info; void **ptr_p = (void **) c_arg_p->dest; - bool is_ok = jerry_get_object_native_pointer (js_arg, ptr_p, &out_info_p); + bool is_ok = jerry_get_object_native_pointer (js_arg, ptr_p, expected_info_p); - if (!is_ok || out_info_p != expected_info_p) + if (!is_ok) { return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "The object has no native pointer or type does not match."); diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/AnalogIn-js.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/AnalogIn-js.cpp index 450ef5efc8..5bbd22383f 100644 --- a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/AnalogIn-js.cpp +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/AnalogIn-js.cpp @@ -47,10 +47,9 @@ DECLARE_CLASS_FUNCTION(AnalogIn, read) { // Extract native AnalogIn pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native AnalogIn pointer"); } @@ -73,10 +72,9 @@ DECLARE_CLASS_FUNCTION(AnalogIn, read_u16) { // Extract native AnalogIn pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native AnalogIn pointer"); } diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut-js.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut-js.cpp index 7edae9431e..c60fce663c 100644 --- a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut-js.cpp +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/DigitalOut-js.cpp @@ -50,10 +50,9 @@ DECLARE_CLASS_FUNCTION(DigitalOut, write) { // Extract native DigitalOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native DigitalOut pointer"); } @@ -78,10 +77,9 @@ DECLARE_CLASS_FUNCTION(DigitalOut, read) { // Extract native DigitalOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native DigitalOut pointer"); } @@ -103,10 +101,9 @@ DECLARE_CLASS_FUNCTION(DigitalOut, is_connected) { // Extract native DigitalOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native DigitalOut pointer"); } diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C-js.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C-js.cpp index 23e35144fb..e1ba83e30b 100644 --- a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C-js.cpp +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/I2C-js.cpp @@ -49,10 +49,9 @@ DECLARE_CLASS_FUNCTION(I2C, frequency) { // Unwrap native I2C object void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -92,10 +91,9 @@ DECLARE_CLASS_FUNCTION(I2C, read) { if (args_count == 1) { CHECK_ARGUMENT_TYPE_ALWAYS(I2C, read, 0, number); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -114,10 +112,9 @@ DECLARE_CLASS_FUNCTION(I2C, read) { CHECK_ARGUMENT_TYPE_ON_CONDITION(I2C, read, 3, boolean, (args_count == 4)); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -189,10 +186,9 @@ DECLARE_CLASS_FUNCTION(I2C, write) { // Extract native I2C object void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -213,10 +209,9 @@ DECLARE_CLASS_FUNCTION(I2C, write) { // Extract native I2C object void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -254,10 +249,9 @@ DECLARE_CLASS_FUNCTION(I2C, start) { // Extract native I2C object void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } @@ -278,10 +272,9 @@ DECLARE_CLASS_FUNCTION(I2C, stop) { // Extract native I2C object void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native I2C pointer"); } diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn-js.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn-js.cpp index db10f9164a..539a509555 100644 --- a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn-js.cpp +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/InterruptIn-js.cpp @@ -53,10 +53,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, rise) { // Detach the rise callback when InterruptIn::rise(null) is called if (jerry_value_is_null(args[0])) { void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -83,10 +82,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, rise) { CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, rise, 0, function); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -120,10 +118,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, fall) { // Detach the fall callback when InterruptIn::fall(null) is called if (jerry_value_is_null(args[0])) { void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -150,10 +147,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, fall) { CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, fall, 0, function); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -186,10 +182,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, mode) { CHECK_ARGUMENT_TYPE_ALWAYS(InterruptIn, mode, 0, number); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -211,10 +206,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, disable_irq) { CHECK_ARGUMENT_COUNT(InterruptIn, disable_irq, (args_count == 0)); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } @@ -234,10 +228,9 @@ DECLARE_CLASS_FUNCTION(InterruptIn, enable_irq) { CHECK_ARGUMENT_COUNT(InterruptIn, enable_irq, (args_count == 0)); void *void_ptr; - const jerry_object_native_info_t *type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native InterruptIn pointer"); } diff --git a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/PwmOut-js.cpp b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/PwmOut-js.cpp index 1c098fbe7b..baa541697c 100644 --- a/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/PwmOut-js.cpp +++ b/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/PwmOut-js.cpp @@ -52,10 +52,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, write) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -86,10 +85,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, read) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -115,10 +113,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, period) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -142,10 +139,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, period_ms) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -169,10 +165,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, period_us) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -196,10 +191,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, pulsewidth) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -223,10 +217,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, pulsewidth_ms) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } @@ -250,10 +243,9 @@ DECLARE_CLASS_FUNCTION(PwmOut, pulsewidth_us) { // Extract native PwmOut pointer void* void_ptr; - const jerry_object_native_info_t* type_ptr; - bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); + bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &native_obj_type_info); - if (!has_ptr || type_ptr != &native_obj_type_info) { + if (!has_ptr) { return jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t *) "Failed to get native PwmOut pointer"); } diff --git a/tests/unit-core/test-api.c b/tests/unit-core/test-api.c index b0d216d575..6e58a0698b 100644 --- a/tests/unit-core/test-api.c +++ b/tests/unit-core/test-api.c @@ -102,13 +102,22 @@ handler_throw_test (const jerry_value_t func_obj_val, /**< function object */ } /* handler_throw_test */ static void -handler_construct_freecb (void *native_p) +handler_construct_1_freecb (void *native_p) +{ + TEST_ASSERT ((uintptr_t) native_p == (uintptr_t) 0x0000000000000000ull); + printf ("ok object free callback\n"); + + test_api_is_free_callback_was_called = true; +} /* handler_construct_1_freecb */ + +static void +handler_construct_2_freecb (void *native_p) { TEST_ASSERT ((uintptr_t) native_p == (uintptr_t) 0x0012345678abcdefull); printf ("ok object free callback\n"); test_api_is_free_callback_was_called = true; -} /* handler_construct_freecb */ +} /* handler_construct_2_freecb */ /** @@ -125,8 +134,8 @@ handler_construct_freecb (void *native_p) .free_cb = (jerry_object_native_free_callback_t) native_free_cb \ } -JERRY_DEFINE_NATIVE_HANDLE_INFO (bind1, handler_construct_freecb); -JERRY_DEFINE_NATIVE_HANDLE_INFO (bind2, handler_construct_freecb); +JERRY_DEFINE_NATIVE_HANDLE_INFO (bind1, handler_construct_1_freecb); +JERRY_DEFINE_NATIVE_HANDLE_INFO (bind2, handler_construct_2_freecb); JERRY_DEFINE_NATIVE_HANDLE_INFO (bind3, NULL); static jerry_value_t @@ -153,11 +162,9 @@ handler_construct (const jerry_value_t func_obj_val, /**< function object */ &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1)); void *ptr = NULL; - const jerry_object_native_info_t *out_info_p; - bool is_ok = jerry_get_object_native_pointer (this_val, &ptr, &out_info_p); + bool is_ok = jerry_get_object_native_pointer (this_val, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1)); TEST_ASSERT (is_ok - && (uintptr_t) ptr == (uintptr_t) 0x0000000000000000ull - && out_info_p == &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1)); + && (uintptr_t) ptr == (uintptr_t) 0x0000000000000000ull); /* check if setting handle for second time is handled correctly */ jerry_set_object_native_pointer (this_val, (void *) 0x0012345678abcdefull, @@ -531,16 +538,13 @@ main (void) jerry_release_value (external_construct_val); void *ptr = NULL; - const jerry_object_native_info_t *out_info_p; - is_ok = jerry_get_object_native_pointer (res, &ptr, &out_info_p); + is_ok = jerry_get_object_native_pointer (res, &ptr, &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2)); TEST_ASSERT (is_ok - && (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull - && out_info_p == &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2)); + && (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull); - /* Passing NULL for out_info_p is allowed. */ + /* Passing NULL for info_p is allowed. */ is_ok = jerry_get_object_native_pointer (res, &ptr, NULL); - TEST_ASSERT (is_ok - && (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull); + TEST_ASSERT (!is_ok); jerry_release_value (res);