mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add 'type' argument to set/get native handle API (#1711)
Ecma-object have native handle type inside, and binding code could use type info to validate native handle's type. Related issue #1681 JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
parent
574dff512e
commit
e522e740a7
@ -167,7 +167,9 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_
|
||||
|
||||
**Summary**
|
||||
|
||||
Native free callback of an object
|
||||
**Deprecated: Please use jerry_object_native_free_callback_t instead.**
|
||||
|
||||
Native free callback of an object.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@ -175,6 +177,34 @@ Native free callback of an object
|
||||
typedef void (*jerry_object_free_callback_t) (const uintptr_t native_p);
|
||||
```
|
||||
|
||||
## jerry_object_native_free_callback_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Native free callback of an object. It is used in jerry_object_native_info_t.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef void (*jerry_object_native_free_callback_t) (void *native_p);
|
||||
```
|
||||
|
||||
## jerry_object_native_info_t
|
||||
|
||||
**Summary**
|
||||
|
||||
The type infomation of the native pointer.
|
||||
It includes the free callback that will be called when associated JavaScript object is garbage collected. It can be left NULL in case it is not needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
jerry_object_native_free_callback_t free_cb;
|
||||
} jerry_object_native_info_t;
|
||||
```
|
||||
|
||||
## jerry_object_property_foreach_t
|
||||
|
||||
**Summary**
|
||||
@ -3173,6 +3203,8 @@ jerry_set_prototype (const jerry_value_t obj_val,
|
||||
|
||||
**Summary**
|
||||
|
||||
**Deprecated: Please use jerry_get_object_native_pointer instead.**
|
||||
|
||||
Get native handle, previously associated with specified object.
|
||||
|
||||
**Prototype**
|
||||
@ -3211,12 +3243,16 @@ jerry_get_object_native_handle (const jerry_value_t obj_val,
|
||||
|
||||
- [jerry_create_object](#jerry_create_object)
|
||||
- [jerry_set_object_native_handle](#jerry_set_object_native_handle)
|
||||
- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
|
||||
|
||||
|
||||
## jerry_set_object_native_handle
|
||||
|
||||
**Summary**
|
||||
|
||||
Set native handle and an optional free callback for the specified object
|
||||
**Deprecated: Please use jerry_set_object_native_pointer instead.**
|
||||
|
||||
Set native handle and an optional free callback for the specified object.
|
||||
|
||||
*Note*: If native handle was already set for the object, its value is updated.
|
||||
|
||||
@ -3260,6 +3296,146 @@ jerry_set_object_native_handle (const jerry_value_t obj_val,
|
||||
|
||||
- [jerry_create_object](#jerry_create_object)
|
||||
- [jerry_get_object_native_handle](#jerry_get_object_native_handle)
|
||||
- [jerry_set_object_native_pointer](#jerry_set_object_native_pointer)
|
||||
|
||||
|
||||
## jerry_get_object_native_pointer
|
||||
|
||||
**Summary**
|
||||
|
||||
Get native pointer and its type information.
|
||||
The pointer and the type information are previously associated with the object by jerry_set_object_native_pointer.
|
||||
Users can check the pointer's type before processing it.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_get_object_native_pointer (const jerry_value_t obj_val,
|
||||
void **out_native_p,
|
||||
const jerry_object_native_info_t **out_info_p)
|
||||
```
|
||||
|
||||
- `obj_val` - object value to get native pointer from.
|
||||
- `out_native_p` - native pointer (output parameter).
|
||||
- `out_info_p` - native pointer's type infomation (output parameter).
|
||||
- return value
|
||||
- true, if there is native pointer associated with the object
|
||||
- false, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
static void native_freecb (uintptr_t native_p)
|
||||
{
|
||||
... // free the native pointer
|
||||
}
|
||||
|
||||
static const jerry_object_native_info_t type_info =
|
||||
{
|
||||
.free_cb = native_freecb
|
||||
};
|
||||
|
||||
{
|
||||
jerry_value_t object;
|
||||
uintptr_t native_set;
|
||||
|
||||
... // receive or construct object and native_set value
|
||||
|
||||
jerry_set_object_native_pointer (object, native_set, &type_info);
|
||||
|
||||
...
|
||||
|
||||
uintptr_t native_get;
|
||||
const jerry_object_native_info_t *type_get_p;
|
||||
bool is_there_associated_native = jerry_get_object_native_pointer (object, &native_get, &type_get_p);
|
||||
|
||||
if (is_there_associated_native)
|
||||
{
|
||||
if (out_info_p == &type_info)
|
||||
{
|
||||
... // the type of object's native pointer is expected, and then process the native pointer.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_create_object](#jerry_create_object)
|
||||
- [jerry_set_object_native_pointer](#jerry_set_object_native_pointer)
|
||||
- [jerry_object_native_info_t](#jerry_object_native_info_t)
|
||||
|
||||
|
||||
## jerry_set_object_native_pointer
|
||||
|
||||
**Summary**
|
||||
|
||||
Set native pointer and an optional type information for the specified object.
|
||||
You can get them by calling jerry_get_object_native_pointer later.
|
||||
|
||||
*Note*: If native pointer was already set for the object, its value is updated.
|
||||
|
||||
*Note*: If a non-NULL free callback is specified in the native type information,
|
||||
it will be called by the garbage collector when the object is freed.
|
||||
The type info is always overwrites the previous value, so passing
|
||||
a NULL value deletes the current type info.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_set_object_native_pointer (const jerry_value_t obj_val,
|
||||
void *native_p,
|
||||
const jerry_object_native_info_t *info_p)
|
||||
```
|
||||
|
||||
- `obj_val` - object to set native pointer in.
|
||||
- `native_p` - native pointer.
|
||||
- `info_p` - native pointer's type infomation or NULL.
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
static void native_freecb (uintptr_t native_p)
|
||||
{
|
||||
... // free the native pointer
|
||||
}
|
||||
|
||||
static const jerry_object_native_info_t type_info =
|
||||
{
|
||||
.free_cb = native_freecb
|
||||
};
|
||||
|
||||
{
|
||||
jerry_value_t object;
|
||||
uintptr_t native_set;
|
||||
|
||||
... // receive or construct object and native_set value
|
||||
|
||||
jerry_set_object_native_pointer (object, native_set, &type_info);
|
||||
|
||||
...
|
||||
|
||||
uintptr_t native_get;
|
||||
const jerry_object_native_info_t *type_get_p;
|
||||
bool is_there_associated_native = jerry_get_object_native_pointer (object, &native_get, &type_get_p);
|
||||
|
||||
if (is_there_associated_native)
|
||||
{
|
||||
if (out_info_p == &type_info)
|
||||
{
|
||||
... // the type of object's native pointer is expected, and then process the native pointer.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_create_object](#jerry_create_object)
|
||||
- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
|
||||
- [jerry_object_native_info_t](#jerry_object_native_info_t)
|
||||
|
||||
|
||||
## jerry_foreach_object_property
|
||||
|
||||
@ -86,7 +86,6 @@ DECLARE_ROUTINES_FOR (collection_header)
|
||||
DECLARE_ROUTINES_FOR (collection_chunk)
|
||||
DECLARE_ROUTINES_FOR (string)
|
||||
DECLARE_ROUTINES_FOR (getter_setter_pointers)
|
||||
DECLARE_ROUTINES_FOR (external_pointer)
|
||||
|
||||
/**
|
||||
* Allocate memory for extended object
|
||||
|
||||
@ -97,18 +97,6 @@ ecma_getter_setter_pointers_t *ecma_alloc_getter_setter_pointers (void);
|
||||
*/
|
||||
void ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *getter_setter_pointers_p);
|
||||
|
||||
/**
|
||||
* Allocate memory for external pointer
|
||||
*
|
||||
* @return pointer to allocated memory
|
||||
*/
|
||||
ecma_external_pointer_t *ecma_alloc_external_pointer (void);
|
||||
|
||||
/**
|
||||
* Dealloc memory from external pointer
|
||||
*/
|
||||
void ecma_dealloc_external_pointer (ecma_external_pointer_t *external_pointer_p);
|
||||
|
||||
/*
|
||||
* Allocate memory for extended object
|
||||
*
|
||||
|
||||
@ -353,6 +353,47 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
} /* ecma_gc_mark */
|
||||
|
||||
/**
|
||||
* Free the native handle/pointer by calling its free callback
|
||||
*/
|
||||
static void
|
||||
ecma_gc_free_native_pointer (ecma_property_t *property_p, /**< property */
|
||||
lit_magic_string_id_t id) /**< identifier of internal property */
|
||||
{
|
||||
JERRY_ASSERT (property_p != NULL);
|
||||
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
|
||||
ecma_external_pointer_t native_p;
|
||||
ecma_external_pointer_t free_cb;
|
||||
void *package_p;
|
||||
|
||||
package_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, value_p->value);
|
||||
|
||||
if (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE)
|
||||
{
|
||||
native_p = ((ecma_native_handle_package_t *) package_p)->handle_p;
|
||||
free_cb = ((ecma_native_handle_package_t *) package_p)->free_cb;
|
||||
|
||||
if ((jerry_object_free_callback_t) free_cb != NULL)
|
||||
{
|
||||
((jerry_object_free_callback_t) free_cb) ((uintptr_t) native_p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
native_p = ((ecma_native_pointer_package_t *) package_p)->native_p;
|
||||
free_cb = *(ecma_external_pointer_t *) (((ecma_native_pointer_package_t *) package_p)->info_p);
|
||||
|
||||
if ((jerry_object_native_free_callback_t) free_cb != NULL)
|
||||
{
|
||||
((jerry_object_native_free_callback_t) free_cb) ((void *) native_p);
|
||||
}
|
||||
}
|
||||
} /* ecma_gc_free_native_pointer */
|
||||
|
||||
/**
|
||||
* Free specified object
|
||||
*/
|
||||
@ -365,28 +406,6 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
|
||||
|
||||
bool obj_is_not_lex_env = !ecma_is_lexical_environment (object_p);
|
||||
|
||||
if (obj_is_not_lex_env)
|
||||
{
|
||||
/* if the object provides free callback, invoke it with handle stored in the object */
|
||||
|
||||
ecma_external_pointer_t freecb_p;
|
||||
ecma_external_pointer_t native_p;
|
||||
|
||||
bool is_retrieved = ecma_get_external_pointer_value (object_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK,
|
||||
&freecb_p);
|
||||
|
||||
if (is_retrieved && ((jerry_object_free_callback_t) freecb_p) != NULL)
|
||||
{
|
||||
is_retrieved = ecma_get_external_pointer_value (object_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
|
||||
&native_p);
|
||||
JERRY_ASSERT (is_retrieved);
|
||||
|
||||
jerry_dispatch_object_free_callback (freecb_p, native_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (obj_is_not_lex_env
|
||||
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
@ -410,9 +429,20 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
|
||||
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
|
||||
|
||||
/* Call the native's free callback. */
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
&& (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
|
||||
{
|
||||
ecma_gc_free_native_pointer (property_p, (lit_magic_string_id_t) name_cp);
|
||||
}
|
||||
|
||||
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], prop_iter_p->types + i);
|
||||
ecma_free_property (object_p, name_cp, property_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +195,28 @@ typedef int32_t ecma_integer_value_t;
|
||||
*/
|
||||
typedef uintptr_t ecma_external_pointer_t;
|
||||
|
||||
/**
|
||||
* Representation for native handle package.
|
||||
*
|
||||
* Note: It is for the deprecated api:
|
||||
* jerry_get_object_native_handle and jerry_set_object_native_handle
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ecma_external_pointer_t handle_p; /**< points to the external native object */
|
||||
ecma_external_pointer_t free_cb; /**< free callback of the native handle */
|
||||
} ecma_native_handle_package_t;
|
||||
|
||||
/**
|
||||
* Representation of the native pointer package.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_external_pointer_t native_p; /**< points to the external native object */
|
||||
ecma_external_pointer_t info_p; /**< type info of the native pointer */
|
||||
} ecma_native_pointer_package_t;
|
||||
|
||||
/**
|
||||
* Special property identifiers.
|
||||
*/
|
||||
|
||||
@ -25,24 +25,24 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create internal property with specified identifier and store external pointer in the property.
|
||||
* Create internal property with specified identifier and store native handle/pointer of the object.
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
* - LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
|
||||
*
|
||||
* @return true - if property was just created with specified value,
|
||||
* false - otherwise, if property existed before the call, it's value was updated
|
||||
*/
|
||||
bool
|
||||
ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
|
||||
lit_magic_string_id_t id, /**< identifier of internal
|
||||
* property to create */
|
||||
ecma_external_pointer_t ptr_value) /**< value to store in the property */
|
||||
static bool
|
||||
ecma_create_native_property (ecma_object_t *obj_p, /**< object to create property in */
|
||||
lit_magic_string_id_t id, /**< identifier of internal
|
||||
* property to create */
|
||||
void *package_p) /**< value to store in the property */
|
||||
{
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK);
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
ecma_string_t name;
|
||||
ecma_init_ecma_magic_string (&name, id);
|
||||
@ -58,6 +58,7 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
|
||||
else
|
||||
{
|
||||
value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
|
||||
ecma_free_native_package_property (property_p, id);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (&name));
|
||||
@ -65,51 +66,72 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
|
||||
JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (value_p->value),
|
||||
size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes);
|
||||
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
|
||||
value_p->value = (ecma_value_t) ptr_value;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
|
||||
ecma_external_pointer_t *handler_p;
|
||||
|
||||
if (is_new)
|
||||
{
|
||||
handler_p = ecma_alloc_external_pointer ();
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (value_p->value, handler_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, value_p->value);
|
||||
}
|
||||
|
||||
*handler_p = ptr_value;
|
||||
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, package_p);
|
||||
|
||||
return is_new;
|
||||
} /* ecma_create_external_pointer_property */
|
||||
} /* ecma_create_native_property */
|
||||
|
||||
/**
|
||||
* Get value of external pointer stored in the object's property with specified identifier
|
||||
* Create a native handle property to store the native handle and its free callback.
|
||||
*
|
||||
* @return true - if property was just created with specified value,
|
||||
* false - otherwise, if property existed before the call, it's value was updated
|
||||
*/
|
||||
bool
|
||||
ecma_create_native_handle_property (ecma_object_t *obj_p, /**< object to create property in */
|
||||
ecma_external_pointer_t handle_p, /**< native handle */
|
||||
ecma_external_pointer_t free_cb) /**< native handle's free callback*/
|
||||
{
|
||||
ecma_native_handle_package_t *package_p;
|
||||
package_p = jmem_heap_alloc_block (sizeof (ecma_native_handle_package_t));
|
||||
package_p->handle_p = handle_p;
|
||||
package_p->free_cb = free_cb;
|
||||
|
||||
return ecma_create_native_property (obj_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
|
||||
package_p);
|
||||
} /* ecma_create_native_handle_property */
|
||||
|
||||
/**
|
||||
* Create a native pointer property to store the native pointer and its type info.
|
||||
*
|
||||
* @return true - if property was just created with specified value,
|
||||
* false - otherwise, if property existed before the call, it's value was updated
|
||||
*/
|
||||
bool
|
||||
ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
|
||||
ecma_external_pointer_t native_p, /**< native pointer */
|
||||
ecma_external_pointer_t info_p) /**< native pointer's type info */
|
||||
{
|
||||
ecma_native_pointer_package_t *package_p;
|
||||
package_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_package_t));
|
||||
package_p->native_p = native_p;
|
||||
package_p->info_p = info_p;
|
||||
|
||||
return ecma_create_native_property (obj_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER,
|
||||
package_p);
|
||||
} /* ecma_create_native_pointer_property */
|
||||
|
||||
/**
|
||||
* Get value of native package stored in the object's property with specified identifier
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
* - LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
|
||||
*
|
||||
* @return true - if property exists and it's value is returned through out_pointer_p,
|
||||
* false - otherwise (value returned through out_pointer_p is NULL)
|
||||
*/
|
||||
bool
|
||||
ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */
|
||||
lit_magic_string_id_t id, /**< identifier of internal property
|
||||
* to get value from */
|
||||
ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */
|
||||
ecma_get_native_package_value (ecma_object_t *obj_p, /**< object to get property value from */
|
||||
lit_magic_string_id_t id, /**< identifier of internal property
|
||||
* to get value from */
|
||||
void **out_pointer_p) /**< [out] value of the native package */
|
||||
{
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK);
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
ecma_string_t name;
|
||||
ecma_init_ecma_magic_string (&name, id);
|
||||
@ -120,51 +142,46 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
*out_pointer_p = (ecma_external_pointer_t) NULL;
|
||||
*out_pointer_p = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
|
||||
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
|
||||
*out_pointer_p = value_p->value;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
|
||||
*out_pointer_p = *ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, value_p->value);
|
||||
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
*out_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, value_p->value);
|
||||
|
||||
return true;
|
||||
} /* ecma_get_external_pointer_value */
|
||||
} /* ecma_get_native_package_value */
|
||||
|
||||
/**
|
||||
* Free memory associated with external pointer stored in the property
|
||||
* Free the allocated native package struct.
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
* - LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK
|
||||
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
|
||||
*/
|
||||
void
|
||||
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */
|
||||
ecma_free_native_package_property (ecma_property_t *prop_p, /**< native property */
|
||||
lit_magic_string_id_t id) /**< identifier of internal */
|
||||
{
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
/* no additional memory was allocated for the pointer storage */
|
||||
JERRY_UNUSED (prop_p);
|
||||
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (prop_p);
|
||||
void *package_p;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
package_p = ECMA_GET_INTERNAL_VALUE_POINTER (void, value_p->value);
|
||||
|
||||
ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
|
||||
ECMA_PROPERTY_VALUE_PTR (prop_p)->value);
|
||||
if (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE)
|
||||
{
|
||||
jmem_heap_free_block (package_p, sizeof (ecma_native_handle_package_t));
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_dealloc_external_pointer (handler_p);
|
||||
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
} /* ecma_free_external_pointer_in_property */
|
||||
jmem_heap_free_block (package_p, sizeof (ecma_native_pointer_package_t));
|
||||
} /* ecma_free_native_package_property */
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@ -731,9 +731,9 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_STRING_CONTAINER_MAGIC_STRING)
|
||||
{
|
||||
if (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
|
||||
|| name_cp == LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK)
|
||||
|| name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER)
|
||||
{
|
||||
ecma_free_external_pointer_in_property (property_p);
|
||||
ecma_free_native_package_property (property_p, (lit_magic_string_id_t) name_cp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,11 +341,17 @@ void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
|
||||
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
|
||||
|
||||
/* ecma-helpers-external-pointers.c */
|
||||
bool ecma_create_external_pointer_property (ecma_object_t *obj_p, lit_magic_string_id_t id,
|
||||
ecma_external_pointer_t ptr_value);
|
||||
bool ecma_get_external_pointer_value (ecma_object_t *obj_p, lit_magic_string_id_t id,
|
||||
ecma_external_pointer_t *out_pointer_p);
|
||||
void ecma_free_external_pointer_in_property (ecma_property_t *prop_p);
|
||||
bool ecma_create_native_handle_property (ecma_object_t *obj_p,
|
||||
ecma_external_pointer_t handle_p,
|
||||
ecma_external_pointer_t free_cb);
|
||||
bool ecma_create_native_pointer_property (ecma_object_t *obj_p,
|
||||
ecma_external_pointer_t native_p,
|
||||
ecma_external_pointer_t info_p);
|
||||
bool ecma_get_native_package_value (ecma_object_t *obj_p,
|
||||
lit_magic_string_id_t id,
|
||||
void **out_pointer_p);
|
||||
void ecma_free_native_package_property (ecma_property_t *prop_p,
|
||||
lit_magic_string_id_t id);
|
||||
|
||||
/* 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);
|
||||
|
||||
@ -1902,7 +1902,9 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
|
||||
} /* jerry_set_prototype */
|
||||
|
||||
/**
|
||||
* Get native handle, associated with specified object
|
||||
* Get native handle, associated with specified object.
|
||||
*
|
||||
* Note: This API is deprecated, please use jerry_get_object_native_pointer instaed.
|
||||
*
|
||||
* @return true - if there is an associated handle (handle is returned through out_handle_p),
|
||||
* false - otherwise
|
||||
@ -1913,22 +1915,53 @@ jerry_get_object_native_handle (const jerry_value_t obj_val, /**< object to get
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
uintptr_t handle_value;
|
||||
ecma_native_handle_package_t *package_p;
|
||||
|
||||
bool does_exist = ecma_get_external_pointer_value (ecma_get_object_from_value (obj_val),
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
|
||||
&handle_value);
|
||||
bool does_exist = ecma_get_native_package_value (ecma_get_object_from_value (obj_val),
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
|
||||
(void **) &package_p);
|
||||
|
||||
if (does_exist)
|
||||
{
|
||||
*out_handle_p = handle_value;
|
||||
*out_handle_p = package_p->handle_p;
|
||||
}
|
||||
|
||||
return does_exist;
|
||||
} /* jerry_get_object_native_handle */
|
||||
|
||||
/**
|
||||
* Set native handle and an optional free callback for the specified object
|
||||
* Get native pointer and its type information, associated with specified object.
|
||||
*
|
||||
* @return true - if there is an associated pointer (pointer is returned through out_handle_p),
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get native pointer from */
|
||||
void **out_native_p, /**< [out] native pointer */
|
||||
const jerry_object_native_info_t **out_info_p) /**< [out] the type info
|
||||
* of the native pointer */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
ecma_native_pointer_package_t *package_p;
|
||||
|
||||
bool does_exist = ecma_get_native_package_value (ecma_get_object_from_value (obj_val),
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER,
|
||||
(void **) &package_p);
|
||||
|
||||
if (does_exist)
|
||||
{
|
||||
*out_native_p = (void *) package_p->native_p;
|
||||
*out_info_p = (const jerry_object_native_info_t *) package_p->info_p;
|
||||
}
|
||||
|
||||
return does_exist;
|
||||
} /* jerry_get_object_native_pointer */
|
||||
|
||||
/**
|
||||
* Set native handle and an optional free callback for the specified object.
|
||||
*
|
||||
* Note: This API is deprecated, please use jerry_set_object_native_pointer instaed.
|
||||
*
|
||||
* Note:
|
||||
* If native handle was already set for the object, its value is updated.
|
||||
@ -1948,15 +1981,40 @@ jerry_set_object_native_handle (const jerry_value_t obj_val, /**< object to set
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_create_external_pointer_property (object_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
|
||||
handle_p);
|
||||
|
||||
ecma_create_external_pointer_property (object_p,
|
||||
LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK,
|
||||
(uintptr_t) freecb_p);
|
||||
ecma_create_native_handle_property (object_p,
|
||||
handle_p,
|
||||
(ecma_external_pointer_t) freecb_p);
|
||||
} /* jerry_set_object_native_handle */
|
||||
|
||||
/**
|
||||
* Set native pointer and an optional type info for the specified object.
|
||||
*
|
||||
*
|
||||
* Note:
|
||||
* If native pointer was already set for the object, its value is updated.
|
||||
*
|
||||
* Note:
|
||||
* If a non-NULL free callback is specified in the native type info,
|
||||
* it will be called by the garbage collector when the object is freed.
|
||||
* The type info is always overwrites the previous value, so passing
|
||||
* a NULL value deletes the current type info.
|
||||
*/
|
||||
void
|
||||
jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set native pointer in */
|
||||
void *native_p, /**< native pointer */
|
||||
const jerry_object_native_info_t *info_p) /**< object's native type info */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_create_native_pointer_property (object_p,
|
||||
(ecma_external_pointer_t) native_p,
|
||||
(ecma_external_pointer_t) info_p);
|
||||
} /* jerry_set_object_native_pointer */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Applies the given function to the every property in the object.
|
||||
*
|
||||
|
||||
@ -25,6 +25,12 @@ extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define JERRY_DEPRECATED_API __attribute__((deprecated))
|
||||
#else /* !__GNUC__ */
|
||||
/* TODO: for other compilers */
|
||||
#define JERRY_DEPRECATED_API
|
||||
#endif /* __GNUC__ */
|
||||
/** \addtogroup jerry Jerry engine interface
|
||||
* @{
|
||||
*/
|
||||
@ -156,16 +162,28 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_
|
||||
const jerry_length_t args_count);
|
||||
|
||||
/**
|
||||
* Native free callback of an object
|
||||
* Native free callback of an object (deprecated)
|
||||
*/
|
||||
typedef void (*jerry_object_free_callback_t) (const uintptr_t native_p);
|
||||
|
||||
/**
|
||||
* Native free callback of an object
|
||||
*/
|
||||
typedef void (*jerry_object_native_free_callback_t) (void *native_p);
|
||||
|
||||
/**
|
||||
* Function type applied for each data property of an object
|
||||
*/
|
||||
typedef bool (*jerry_object_property_foreach_t) (const jerry_value_t property_name,
|
||||
const jerry_value_t property_value,
|
||||
void *user_data_p);
|
||||
/**
|
||||
* Type information of a native pointer.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_object_native_free_callback_t free_cb; /**< the free callback of the native pointer */
|
||||
} jerry_object_native_info_t;
|
||||
|
||||
/**
|
||||
* General engine functions
|
||||
@ -322,9 +340,19 @@ jerry_value_t jerry_get_object_keys (const jerry_value_t obj_val);
|
||||
jerry_value_t jerry_get_prototype (const jerry_value_t obj_val);
|
||||
jerry_value_t jerry_set_prototype (const jerry_value_t obj_val, const jerry_value_t proto_obj_val);
|
||||
|
||||
JERRY_DEPRECATED_API
|
||||
bool jerry_get_object_native_handle (const jerry_value_t obj_val, uintptr_t *out_handle_p);
|
||||
JERRY_DEPRECATED_API
|
||||
void jerry_set_object_native_handle (const jerry_value_t obj_val, uintptr_t handle_p,
|
||||
jerry_object_free_callback_t freecb_p);
|
||||
|
||||
bool jerry_get_object_native_pointer (const jerry_value_t obj_val,
|
||||
void **out_native_p,
|
||||
const jerry_object_native_info_t **out_info_p);
|
||||
void jerry_set_object_native_pointer (const jerry_value_t obj_val,
|
||||
void *native_p,
|
||||
const jerry_object_native_info_t *info_p);
|
||||
|
||||
bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_property_foreach_t foreach_p,
|
||||
void *user_data_p);
|
||||
|
||||
|
||||
@ -36,10 +36,9 @@ typedef enum
|
||||
#undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
|
||||
LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< number of non-internal magic strings */
|
||||
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< native handle associated
|
||||
* with an object */
|
||||
LIT_INTERNAL_MAGIC_STRING_FREE_CALLBACK, /**< object's native free callback */
|
||||
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< native handle package
|
||||
* associated with an object */
|
||||
LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER, /**< native pointer package associated with an object */
|
||||
LIT_MAGIC_STRING__COUNT /**< number of magic strings */
|
||||
} lit_magic_string_id_t;
|
||||
|
||||
|
||||
@ -107,14 +107,32 @@ handler_throw_test (const jerry_value_t func_obj_val, /**< function object */
|
||||
} /* handler_throw_test */
|
||||
|
||||
static void
|
||||
handler_construct_freecb (uintptr_t native_p)
|
||||
handler_construct_freecb (void *native_p)
|
||||
{
|
||||
TEST_ASSERT (native_p == (uintptr_t) 0x0012345678abcdefull);
|
||||
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 */
|
||||
|
||||
|
||||
/**
|
||||
* The name of the jerry_object_native_info_t struct.
|
||||
*/
|
||||
#define JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE(c_type) _jerry_object_native_info_##c_type
|
||||
|
||||
/**
|
||||
* Define a native pointer's type based on the C type and free callback.
|
||||
*/
|
||||
#define JERRY_DEFINE_NATIVE_HANDLE_INFO(c_type, native_free_cb) \
|
||||
static const jerry_object_native_info_t JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (c_type) = \
|
||||
{ \
|
||||
.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);
|
||||
|
||||
static jerry_value_t
|
||||
handler_construct (const jerry_value_t func_obj_val, /**< function object */
|
||||
const jerry_value_t this_val, /**< this value */
|
||||
@ -134,18 +152,20 @@ handler_construct (const jerry_value_t func_obj_val, /**< function object */
|
||||
jerry_set_property (this_val, field_name, args_p[0]);
|
||||
jerry_release_value (field_name);
|
||||
|
||||
jerry_set_object_native_handle (this_val,
|
||||
(uintptr_t) 0x0000000000000000ull,
|
||||
handler_construct_freecb);
|
||||
|
||||
uintptr_t ptr = (uintptr_t) NULL;
|
||||
bool is_ok = jerry_get_object_native_handle (this_val, &ptr);
|
||||
TEST_ASSERT (is_ok && ptr == (uintptr_t) 0x0000000000000000ull);
|
||||
jerry_set_object_native_pointer (this_val,
|
||||
(void *) 0x0000000000000000ull,
|
||||
&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);
|
||||
TEST_ASSERT (is_ok
|
||||
&& (uintptr_t) ptr == (uintptr_t) 0x0000000000000000ull
|
||||
&& out_info_p == &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind1));
|
||||
/* check if setting handle for second time is handled correctly */
|
||||
jerry_set_object_native_handle (this_val,
|
||||
(uintptr_t) 0x0012345678abcdefull,
|
||||
handler_construct_freecb);
|
||||
jerry_set_object_native_pointer (this_val,
|
||||
(void *) 0x0012345678abcdefull,
|
||||
&JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
|
||||
|
||||
return jerry_create_boolean (true);
|
||||
} /* handler_construct */
|
||||
@ -734,10 +754,12 @@ main (void)
|
||||
jerry_release_value (val_value_field);
|
||||
jerry_release_value (external_construct_val);
|
||||
|
||||
uintptr_t ptr = (uintptr_t) NULL;
|
||||
is_ok = jerry_get_object_native_handle (res, &ptr);
|
||||
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
|
||||
&& ptr == (uintptr_t) 0x0012345678abcdefull);
|
||||
&& (uintptr_t) ptr == (uintptr_t) 0x0012345678abcdefull
|
||||
&& out_info_p == &JERRY_NATIVE_HANDLE_INFO_FOR_CTYPE (bind2));
|
||||
|
||||
jerry_release_value (res);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user