mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Allow the JS objects to have more than one native pointer data (#2814)
Currently JS objects can only have one native pointer data which could be a limitation in special cases. This patch allows to register multiple native infos, which can be accessed/associated with the corresponding `jerry_object_native_info_t`. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
c818930cdc
commit
b3f4aa6816
@ -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**
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
int foo;
|
||||
bool bar;
|
||||
} native_obj_t;
|
||||
[doctest]: # ()
|
||||
|
||||
static void native_freecb (void *native_p)
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jerryscript.h"
|
||||
|
||||
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)
|
||||
if (!has_p)
|
||||
{
|
||||
// The type_p pointer address itself is used to identify the type:
|
||||
if (type_p == &native_obj_type_info)
|
||||
// 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 (need_shape_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)
|
||||
{
|
||||
// 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.
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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;
|
||||
|
||||
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
|
||||
if (free_cb != NULL)
|
||||
{
|
||||
free_cb (native_pointer_p->data_p);
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
/**
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.");
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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,17 +538,14 @@ 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);
|
||||
TEST_ASSERT (is_ok
|
||||
&& (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull
|
||||
&& out_info_p == &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
|
||||
|
||||
/* Passing NULL for out_info_p is allowed. */
|
||||
is_ok = jerry_get_object_native_pointer (res, &ptr, NULL);
|
||||
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);
|
||||
|
||||
/* Passing NULL for info_p is allowed. */
|
||||
is_ok = jerry_get_object_native_pointer (res, &ptr, NULL);
|
||||
TEST_ASSERT (!is_ok);
|
||||
|
||||
jerry_release_value (res);
|
||||
|
||||
/* Test: It is ok to set native pointer's free callback as NULL. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user