Skip to content
Merged
Show file tree
Hide file tree
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
67 changes: 57 additions & 10 deletions docs/02.API-REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,29 +696,57 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_call_info_t *call

- [jerry_create_external_function](#jerry_create_external_function)

## jerry_value_free_callback_t

**Summary**

Native free callback of generic value types.

*Note*:
- Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)

**Prototype**

```c
typedef void (*jerry_value_free_callback_t) (void *native_p);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was wondering if it would make sense to have a "type" information as second argument for this callback. What do you think? Could this be a useful feature? This "type" could/would indicate what kind of data should be freed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am neutral. If others think this is a good idea we could do it in another patch (before release).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true. We could even do a different WIP PR to see how it would look.

```

*New in version [[NEXT_RELEASE]]*.

**See also**

- [jerry_create_external_string](#jerry_create_external_string)
- [jerry_create_external_string_sz](#jerry_create_external_string_sz)
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)

## jerry_object_native_free_callback_t

**Summary**

Native free callback of an object. It is used in `jerry_object_native_info_t` and for external Array buffers.
Native free callback of an object. The callback receives both the memory pointer and the type
information passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).

*Note*:
- Referred values by this method must have at least 1 reference. (Correct API usage satisfies this condition)

**Prototype**

```c
typedef void (*jerry_object_native_free_callback_t) (void *native_p);
typedef void (*jerry_object_native_free_callback_t) (void *native_p, struct jerry_object_native_info_t *info_p);
```

- `native_p` - native pointer passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).
- `info_p` - native type info passed to [jerry_set_object_native_pointer](#jerry_set_object_native_pointer).

*New in version 2.0*: Renamed from `jerry_object_free_callback_t`.

*Changed in version 2.2*: API calls are once again allowed. (See note)

*Changed in version [[NEXT_RELEASE]]*: `info_p` argument is added

**See also**

- [jerry_object_native_info_t](#jerry_object_native_info_t)
- [jerry_create_arraybuffer_external](#jerry_create_arraybuffer_external)

## jerry_error_object_created_callback_t

Expand Down Expand Up @@ -5655,7 +5683,7 @@ so the user can release the buffer which was provided.
jerry_value_t
jerry_create_arraybuffer_external (const jerry_length_t size
uint8_t *buffer_p,
jerry_object_native_free_callback_t free_cb);
jerry_value_free_callback_t free_cb);
```

- `size` - size of the buffer to use **in bytes** (should not be 0)
Expand All @@ -5667,6 +5695,8 @@ jerry_create_arraybuffer_external (const jerry_length_t size

*New in version 2.0*.

*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.

**Example**

```c
Expand Down Expand Up @@ -6473,7 +6503,7 @@ is no longer needed.
```c
jerry_value_t
jerry_create_external_string (const jerry_char_t *str_p,
jerry_object_native_free_callback_t free_cb)
jerry_value_free_callback_t free_cb)
```

- `str_p` - non-null pointer to string
Expand All @@ -6482,6 +6512,8 @@ jerry_create_external_string (const jerry_char_t *str_p,

*New in version 2.4*.

*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.

**Example**

```c
Expand Down Expand Up @@ -6519,7 +6551,7 @@ is no longer needed.
jerry_value_t
jerry_create_external_string_sz (const jerry_char_t *str_p,
jerry_size_t str_size,
jerry_object_native_free_callback_t free_cb)
jerry_value_free_callback_t free_cb)
```

- `str_p` - non-null pointer to string
Expand All @@ -6529,6 +6561,8 @@ jerry_create_external_string_sz (const jerry_char_t *str_p,

*New in version 2.4*.

*Changed in version [[NEXT_RELEASE]]*: type of `free_cb` has been changed.

**Example**

```c
Expand Down Expand Up @@ -8416,8 +8450,11 @@ typedef struct
#define SECRET_INFO ((void *) 42)

static void
buffer_native_freecb (void *native_p)
buffer_native_freecb (void *native_p,
jerry_object_native_info_t *info_p)
{
(void) info_p;

char *data_p = ((buffer_native_object_t*)native_p)->data_p;

if (data_p != NULL)
Expand All @@ -8429,14 +8466,21 @@ buffer_native_freecb (void *native_p)
}

static void
shape_native_freecb (void *native_p)
shape_native_freecb (void *native_p,
jerry_object_native_info_t *info_p)
{
(void) info_p;

free (native_p);
}

static void
destructor_freecb (void *native_p)
destructor_freecb (void *native_p,
jerry_object_native_info_t *info_p)
{
(void) native_p;
(void) info_p;

printf("Note: the object has been freed\n");
}

Expand Down Expand Up @@ -8988,8 +9032,11 @@ typedef struct
int match_foo_value;
} find_object_data_t;

static void native_freecb (void *native_p)
static void native_freecb (void *native_p,
jerry_object_native_info_t *info_p)
{
(void) info_p;

/* `native_p` was allocated via malloc. */
free (native_p);
} /* native_freecb */
Expand Down
14 changes: 6 additions & 8 deletions jerry-core/api/jerry.c
Original file line number Diff line number Diff line change
Expand Up @@ -2474,7 +2474,7 @@ jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */
*/
jerry_value_t
jerry_create_external_string (const jerry_char_t *str_p, /**< pointer to string */
jerry_object_native_free_callback_t free_cb) /**< free callback */
jerry_value_free_callback_t free_cb) /**< free callback */
{
return jerry_create_external_string_sz (str_p, lit_zt_utf8_string_size ((lit_utf8_byte_t *) str_p), free_cb);
} /* jerry_create_external_string */
Expand All @@ -2490,7 +2490,7 @@ jerry_create_external_string (const jerry_char_t *str_p, /**< pointer to string
jerry_value_t
jerry_create_external_string_sz (const jerry_char_t *str_p, /**< pointer to string */
jerry_size_t str_size, /**< string size */
jerry_object_native_free_callback_t free_cb) /**< free callback */
jerry_value_free_callback_t free_cb) /**< free callback */
{
jerry_assert_api_available ();

Expand Down Expand Up @@ -4022,7 +4022,7 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i
{
native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p);
if (native_pointer_p
&& !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p))
&& !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->native_p, user_data_p))
{
return true;
}
Expand Down Expand Up @@ -4066,7 +4066,7 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get

if (out_native_pointer_p != NULL)
{
*out_native_pointer_p = native_pointer_p->data_p;
*out_native_pointer_p = native_pointer_p->native_p;
}

return true;
Expand Down Expand Up @@ -5209,7 +5209,7 @@ jerry_create_arraybuffer (const jerry_length_t size) /**< size of the ArrayBuffe
jerry_value_t
jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the buffer to used */
uint8_t *buffer_p, /**< buffer to use as the ArrayBuffer's backing */
jerry_object_native_free_callback_t free_cb) /**< buffer free callback */
jerry_value_free_callback_t free_cb) /**< buffer free callback */
{
jerry_assert_api_available ();

Expand All @@ -5222,9 +5222,7 @@ jerry_create_arraybuffer_external (const jerry_length_t size, /**< size of the b
}
else
{
arraybuffer = ecma_arraybuffer_new_object_external (size,
buffer_p,
(ecma_object_native_free_callback_t) free_cb);
arraybuffer = ecma_arraybuffer_new_object_external (size, buffer_p, free_cb);
}

return jerry_return (ecma_make_object_value (arraybuffer));
Expand Down
43 changes: 30 additions & 13 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,37 +1175,54 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
* Free the native handle/pointer by calling its free callback.
*/
static void
ecma_gc_free_native_pointer (ecma_value_t value) /**< property value */
ecma_gc_free_native_pointer (ecma_property_t property, /**< property descriptor */
ecma_value_t value) /**< property value */
{
if (value == JMEM_CP_NULL)
if (JERRY_LIKELY (property & ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL))
{
JERRY_ASSERT (value != JMEM_CP_NULL);

ecma_native_pointer_t *native_pointer_p;
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);

jerry_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;

if (free_cb != NULL)
{
free_cb (native_pointer_p->native_p, native_pointer_p->info_p);
}

jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
return;
}

ecma_native_pointer_t *native_pointer_p;
if (value == JMEM_CP_NULL)
{
return;
}

native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);
JERRY_ASSERT (native_pointer_p != NULL);
ecma_native_pointer_chain_t *item_p;
item_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_chain_t, value);

do
{
if (native_pointer_p->info_p != NULL)
if (item_p->data.info_p != NULL)
{
ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;
jerry_object_native_free_callback_t free_cb = item_p->data.info_p->free_cb;

if (free_cb != NULL)
{
free_cb (native_pointer_p->data_p);
free_cb (item_p->data.native_p, item_p->data.info_p);
}
}

ecma_native_pointer_t *next_p = native_pointer_p->next_p;
ecma_native_pointer_chain_t *next_p = item_p->next_p;

jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
jmem_heap_free_block (item_p, sizeof (ecma_native_pointer_chain_t));

native_pointer_p = next_p;
item_p = next_p;
}
while (native_pointer_p != NULL);
while (item_p != NULL);
} /* ecma_gc_free_native_pointer */

/**
Expand Down Expand Up @@ -1518,7 +1535,7 @@ ecma_gc_free_property (ecma_object_t *object_p, /**< object */
default:
{
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_gc_free_native_pointer (value);
ecma_gc_free_native_pointer (property, value);
break;
}
}
Expand Down
29 changes: 12 additions & 17 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,27 +299,22 @@ typedef ecma_value_t (*ecma_native_handler_t) (const struct jerry_call_info_t *c
const uint32_t args_count);

/**
* Native free callback of an object.
*/
typedef void (*ecma_object_native_free_callback_t) (void *native_p);

/**
* Type information of a native pointer.
* Representation of native pointer data.
*/
typedef struct
{
ecma_object_native_free_callback_t free_cb; /**< the free callback of the native pointer */
} ecma_object_native_info_t;
void *native_p; /**< points to the data of the object */
jerry_object_native_info_t *info_p; /**< native info */
} ecma_native_pointer_t;

/**
* Representation for native pointer data.
* Representation of native pointer data chain.
*/
typedef struct ecma_native_pointer_t
typedef struct ecma_native_pointer_chain_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;
ecma_native_pointer_t data; /**< pointer data */
struct ecma_native_pointer_chain_t *next_p; /**< next in the list */
} ecma_native_pointer_chain_t;

/**
* Option bits for ecma_parse_options_t.
Expand Down Expand Up @@ -415,7 +410,7 @@ typedef enum
ECMA_PROPERTY_FLAG_CONFIGURABLE = (1u << 0), /**< property is configurable */
ECMA_PROPERTY_FLAG_ENUMERABLE = (1u << 1), /**< property is enumerable */
ECMA_PROPERTY_FLAG_WRITABLE = (1u << 2), /**< property is writable */

ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL = (1u << 2), /**< only one external pointer is assigned to this object */
ECMA_PROPERTY_FLAG_DELETED = (1u << 3), /**< property is deleted */
ECMA_FAST_ARRAY_FLAG = (1u << 3), /**< array is fast array */
ECMA_PROPERTY_FLAG_LCACHED = (1u << 4), /**< property is lcached */
Expand Down Expand Up @@ -1849,7 +1844,7 @@ typedef struct
typedef struct
{
ecma_long_string_t header;
ecma_object_native_free_callback_t free_cb; /**< free callback */
jerry_value_free_callback_t free_cb; /**< free callback */
} ecma_external_string_t;

/**
Expand Down Expand Up @@ -2101,7 +2096,7 @@ typedef struct
{
ecma_extended_object_t extended_object; /**< extended object part */
void *buffer_p; /**< external buffer pointer */
ecma_object_native_free_callback_t free_cb; /**< the free callback for the above buffer pointer */
jerry_value_free_callback_t free_cb; /**< the free callback for the above buffer pointer */
} ecma_arraybuffer_external_info;

/**
Expand Down
Loading