diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 44025b5b9..dec8efa08 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -122,8 +122,9 @@ typedef uint32_t jerry_value_t; **Summary** Structure that defines how a context data item will be initialized and deinitialized. JerryScript zeroes out the memory -for the item by default, and if the `init_cb` field is not NULL, it will be called with the pointer to the memory as -an additional custom initializer. +for the item by default, and if the `init_cb` field is not NULL, it will be called with the pointer to the memory as +an additional custom initializer. The `deinit_cb` (if non-`NULL`) is called during a call to `jerry_cleanup()` to run +any custom deinitialization. **Prototype** @@ -131,7 +132,7 @@ an additional custom initializer. typedef struct { void (*init_cb) (void *); /**< callback responsible for initializing a context item, or NULL */ - void (*deinit_cb) (void *); /**< callback responsible for deinitializing a context item */ + void (*deinit_cb) (void *); /**< callback responsible for deinitializing a context item, or NULL */ size_t bytes_needed; /**< number of bytes to allocate for this manager */ } jerry_context_data_manager_t; ``` diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 137061f8f..5b3d164c4 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -215,7 +215,10 @@ jerry_cleanup (void) this_p = next_p) { next_p = this_p->next_p; - this_p->manager_p->deinit_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p)); + if (this_p->manager_p->deinit_cb) + { + this_p->manager_p->deinit_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p)); + } jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed); } diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 8144816c3..e58b7d644 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -217,7 +217,7 @@ typedef bool (*jerry_object_property_foreach_t) (const jerry_value_t property_na typedef struct { void (*init_cb) (void *); /**< callback responsible for initializing a context item, or NULL to zero out the memory */ - void (*deinit_cb) (void *); /**< callback responsible for deinitializing a context item */ + void (*deinit_cb) (void *); /**< callback responsible for deinitializing a context item, or NULL */ size_t bytes_needed; /**< number of bytes to allocate for this manager */ } jerry_context_data_manager_t; diff --git a/tests/unit-core/test-context-data.c b/tests/unit-core/test-context-data.c index 5c0c604a8..52e3a2ed0 100644 --- a/tests/unit-core/test-context-data.c +++ b/tests/unit-core/test-context-data.c @@ -21,6 +21,7 @@ static bool test_context_data1_new_called = false; static bool test_context_data2_new_called = false; static bool test_context_data1_free_called = false; static bool test_context_data2_free_called = false; +static bool test_context_data3_new_called = false; /* Context item 1 */ const char *string1 = "item1"; @@ -70,6 +71,24 @@ static const jerry_context_data_manager_t manager2 = .bytes_needed = sizeof (const char *) }; +/* Context item 3 */ +const char *string3 = "item3"; + +static void +test_context_data3_new (void *user_data_p) +{ + test_context_data3_new_called = true; + *((const char **) user_data_p) = string3; +} /* test_context_data3_new */ + +static const jerry_context_data_manager_t manager3 = +{ + .init_cb = test_context_data3_new, + /* NULL is allowed: */ + .deinit_cb = NULL, + .bytes_needed = 0, +}; + int main (void) { @@ -79,9 +98,11 @@ main (void) TEST_ASSERT (!strcmp (*((const char **) jerry_get_context_data (&manager1)), "item1")); TEST_ASSERT (!strcmp (*((const char **) jerry_get_context_data (&manager2)), "item2")); + TEST_ASSERT (!strcmp (*((const char **) jerry_get_context_data (&manager3)), "item3")); TEST_ASSERT (test_context_data1_new_called); TEST_ASSERT (test_context_data2_new_called); + TEST_ASSERT (test_context_data3_new_called); TEST_ASSERT (!test_context_data1_free_called); TEST_ASSERT (!test_context_data2_free_called);