Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 67 additions & 49 deletions docs/02.API-REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ typedef void (*jerry_object_native_free_callback_t) (void *native_p);
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.

Typically, one would create a `static const jerry_object_native_info_t` for
each distinct C type for which a pointer is used with
`jerry_set_object_native_pointer ()` and `jerry_get_object_native_pointer ()`.
This way, each `const jerry_object_native_info_t *` pointer address value itself
uniquely identifies the C type of the native pointer.

See [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
for a best-practice code example.

**Prototype**

```c
Expand All @@ -205,6 +214,11 @@ typedef struct
} jerry_object_native_info_t;
```

**See also**

- [jerry_set_object_native_pointer](#jerry_set_object_native_pointer)
- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)

## jerry_object_property_foreach_t

**Summary**
Expand Down Expand Up @@ -3416,7 +3430,18 @@ jerry_set_object_native_handle (const jerry_value_t obj_val,

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.

*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`.

**Prototype**

Expand All @@ -3437,37 +3462,60 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val,
**Example**

```c
static void native_freecb (uintptr_t native_p)
typedef struct {
int foo;
bool bar;
} native_obj_t;

static void native_freecb (void *native_p)
{
... // free the native pointer
}

static const jerry_object_native_info_t type_info =
// 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 =
{
.free_cb = native_freecb
};

// Function creating JS object that is "backed" by a native_obj_t *:
{
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);
// 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);

...
}

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);
// Native method, `this` is expected to be "backed" by a native_obj_t *:
{
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);

if (is_there_associated_native)
if (has_p)
{
if (out_info_p == &type_info)
// The type_p pointer address itself is used to identify the type:
if (type_p == &native_obj_type_info)
{
// 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!
}
else
{
... // the type of object's native pointer is expected, and then process the native pointer.
// 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.
}
}
...
}
```

Expand Down Expand Up @@ -3503,44 +3551,14 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val,

- `obj_val` - object to set native pointer in.
- `native_p` - native pointer.
- `info_p` - native pointer's type infomation or NULL.
- `info_p` - native pointer's type infomation or NULL. When used, this should
be a long-lived pointer, usually a pointer to a
`static const jerry_object_native_info_t` makes most sense.

**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 [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) for a
best-practice example.

**See also**

Expand Down