mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implementing API for associating native handle (uintptr_t) values with JS objects.
This commit is contained in:
parent
fc2dbf3b0b
commit
469ef4e622
@ -319,6 +319,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
|
||||
case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */
|
||||
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
|
||||
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
|
||||
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */
|
||||
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */
|
||||
case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */
|
||||
|
||||
@ -205,6 +205,7 @@ typedef enum
|
||||
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
|
||||
ECMA_INTERNAL_PROPERTY_CODE, /**< [[Code]] */
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE, /**< native handler location descriptor */
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
|
||||
ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS, /**< [[FormalParameters]] */
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE, /**< [[Primitive value]] for String objects */
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE, /**< [[Primitive value]] for Number objects */
|
||||
|
||||
@ -29,17 +29,35 @@
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE.
|
||||
*
|
||||
* @return true - if property was just created with specified value,
|
||||
* false - otherwise, if property existed before the call, it's value was updated.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
|
||||
ecma_internal_property_id_t id, /**< identifier of internal
|
||||
* property to create */
|
||||
ecma_external_pointer_t ptr_value) /**< value to store in the property */
|
||||
{
|
||||
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE);
|
||||
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE);
|
||||
|
||||
bool ret_val;
|
||||
ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id);
|
||||
|
||||
if (prop_p == NULL)
|
||||
{
|
||||
prop_p = ecma_create_internal_property (obj_p, id);
|
||||
|
||||
ret_val = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_val = false;
|
||||
}
|
||||
|
||||
ecma_property_t *prop_p = ecma_create_internal_property (obj_p, id);
|
||||
JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (prop_p->u.internal_property.value));
|
||||
|
||||
if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t))
|
||||
@ -53,6 +71,8 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (prop_p->u.internal_property.value, handler_p);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
} /* ecma_create_external_pointer_property */
|
||||
|
||||
/**
|
||||
@ -60,30 +80,44 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE.
|
||||
*
|
||||
* @return value of the external 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).
|
||||
*/
|
||||
ecma_external_pointer_t
|
||||
bool
|
||||
ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */
|
||||
ecma_internal_property_id_t id) /**< identifier of internal property
|
||||
ecma_internal_property_id_t id, /**< identifier of internal property
|
||||
* to get value from */
|
||||
ecma_external_pointer_t *out_pointer_p) /**< out: value of the external pointer */
|
||||
{
|
||||
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE);
|
||||
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE);
|
||||
|
||||
ecma_property_t* prop_p = ecma_find_internal_property (obj_p, id);
|
||||
|
||||
if (prop_p == NULL)
|
||||
{
|
||||
*out_pointer_p = (ecma_external_pointer_t) NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_property_t* prop_p = ecma_get_internal_property (obj_p, id);
|
||||
JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (prop_p->u.internal_property.value));
|
||||
|
||||
if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t))
|
||||
{
|
||||
return (ecma_external_pointer_t) prop_p->u.internal_property.value;
|
||||
*out_pointer_p = (ecma_external_pointer_t) prop_p->u.internal_property.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
|
||||
prop_p->u.internal_property.value);
|
||||
return *handler_p;
|
||||
*out_pointer_p = *handler_p;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* ecma_get_external_pointer_value */
|
||||
|
||||
/**
|
||||
@ -91,12 +125,14 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
|
||||
*
|
||||
* Note:
|
||||
* property identifier should be one of the following:
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
|
||||
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE.
|
||||
*/
|
||||
void
|
||||
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */
|
||||
{
|
||||
JERRY_ASSERT (prop_p->u.internal_property.type == ECMA_INTERNAL_PROPERTY_NATIVE_CODE);
|
||||
JERRY_ASSERT (prop_p->u.internal_property.type == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|
||||
|| prop_p->u.internal_property.type == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE);
|
||||
|
||||
if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t))
|
||||
{
|
||||
|
||||
@ -779,6 +779,7 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
|
||||
}
|
||||
|
||||
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
|
||||
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
|
||||
{
|
||||
ecma_free_external_pointer_in_property (property_p);
|
||||
|
||||
|
||||
@ -309,13 +309,14 @@ extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
|
||||
extern void ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p);
|
||||
|
||||
/* ecma-helpers-external-pointers.c */
|
||||
extern void
|
||||
extern bool
|
||||
ecma_create_external_pointer_property (ecma_object_t *obj_p,
|
||||
ecma_internal_property_id_t id,
|
||||
ecma_external_pointer_t ptr_value);
|
||||
extern ecma_external_pointer_t
|
||||
extern bool
|
||||
ecma_get_external_pointer_value (ecma_object_t *obj_p,
|
||||
ecma_internal_property_id_t id);
|
||||
ecma_internal_property_id_t id,
|
||||
ecma_external_pointer_t *out_pointer_p);
|
||||
extern void
|
||||
ecma_free_external_pointer_in_property (ecma_property_t *prop_p);
|
||||
|
||||
|
||||
@ -308,9 +308,10 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (function_obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
|
||||
ecma_create_external_pointer_property (function_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
|
||||
(ecma_external_pointer_t) code_p);
|
||||
bool is_created = ecma_create_external_pointer_property (function_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
|
||||
(ecma_external_pointer_t) code_p);
|
||||
JERRY_ASSERT (is_created);
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
@ -607,8 +608,11 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
}
|
||||
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||
{
|
||||
ecma_external_pointer_t handler_p = ecma_get_external_pointer_value (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE);
|
||||
ecma_external_pointer_t handler_p;
|
||||
bool is_retrieved = ecma_get_external_pointer_value (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
|
||||
&handler_p);
|
||||
JERRY_ASSERT (is_retrieved);
|
||||
|
||||
ret_value = jerry_dispatch_external_function (func_obj_p,
|
||||
handler_p,
|
||||
|
||||
@ -136,6 +136,12 @@ bool jerry_api_set_object_field_value (jerry_api_object_t *object_p,
|
||||
const char *field_name_p,
|
||||
const jerry_api_value_t *field_value_p);
|
||||
|
||||
extern EXTERN_C
|
||||
bool jerry_api_get_object_native_handle (jerry_api_object_t *object_p, uintptr_t* out_handle_p);
|
||||
|
||||
extern EXTERN_C
|
||||
void jerry_api_set_object_native_handle (jerry_api_object_t *object_p, uintptr_t handle);
|
||||
|
||||
extern EXTERN_C
|
||||
bool jerry_api_call_function (jerry_api_object_t *function_object_p,
|
||||
jerry_api_object_t *this_arg_p,
|
||||
|
||||
@ -616,6 +616,42 @@ jerry_api_set_object_field_value (jerry_api_object_t *object_p, /**< object */
|
||||
return is_successful;
|
||||
} /* jerry_api_set_object_field_value */
|
||||
|
||||
/**
|
||||
* Get native handle, associated with specified object
|
||||
*
|
||||
* @return true - if there is associated handle (handle is returned through out_handle_p),
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
jerry_api_get_object_native_handle (jerry_api_object_t *object_p, /**< object to get handle from */
|
||||
uintptr_t* out_handle_p) /**< out: handle value */
|
||||
{
|
||||
uintptr_t handle_value;
|
||||
|
||||
bool does_exist = ecma_get_external_pointer_value (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE,
|
||||
&handle_value);
|
||||
|
||||
if (does_exist)
|
||||
{
|
||||
*out_handle_p = handle_value;
|
||||
}
|
||||
|
||||
return does_exist;
|
||||
} /* jerry_api_get_object_native_handle */
|
||||
|
||||
/**
|
||||
* Set native handle for the specified object
|
||||
*/
|
||||
void
|
||||
jerry_api_set_object_native_handle (jerry_api_object_t *object_p, /**< object to set handle in */
|
||||
uintptr_t handle) /**< handle value */
|
||||
{
|
||||
ecma_create_external_pointer_property (object_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE,
|
||||
handle);
|
||||
} /* jerry_api_set_object_native_handle */
|
||||
|
||||
/**
|
||||
* Call function specified by a function object
|
||||
*
|
||||
|
||||
@ -125,6 +125,8 @@ handler_construct (const jerry_api_object_t *function_obj_p,
|
||||
|
||||
jerry_api_set_object_field_value (this_p->v_object, "value_field", &args_p [0]);
|
||||
|
||||
jerry_api_set_object_native_handle (this_p->v_object, (uintptr_t) 0x0012345678abcdefull);
|
||||
|
||||
return true;
|
||||
} /* handler_construct */
|
||||
|
||||
@ -322,6 +324,11 @@ main (void)
|
||||
&& val_value_field.v_bool == true);
|
||||
jerry_api_release_value (&val_value_field);
|
||||
|
||||
uintptr_t ptr;
|
||||
is_ok = jerry_api_get_object_native_handle (res.v_object, &ptr);
|
||||
assert (is_ok
|
||||
&& ptr == (uintptr_t) 0x0012345678abcdefull);
|
||||
|
||||
jerry_api_release_value (&res);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user