From 908b48fa3a0ed339e4a703e5b461224928fc41a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csaba=20Osztrogon=C3=A1c?= Date: Mon, 16 Sep 2019 12:00:57 +0000 Subject: [PATCH] Fix jerry_get_context_data() API function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If manager_p->bytes_needed == 0, jerry_get_context_data() should return NULL pointer. Additionally init_cb, deinit_cb and finalize_cb should be called with NULL pointer in this case. JerryScript-DCO-1.0-Signed-off-by: Csaba Osztrogonác oszi@inf.u-szeged.hu --- docs/02.API-REFERENCE.md | 1 + jerry-core/api/jerry.c | 16 ++++++--- tests/unit-core/test-context-data.c | 50 +++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index af1e6ebca3..07244288dc 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -224,6 +224,7 @@ for the item by default, and if the `init_cb` field is not NULL, it will be call an additional custom initializer. The `deinit_cb` (if non-`NULL`) is called during a call to `jerry_cleanup ()` to run any custom deinitialization *before* the VM has been fully cleaned up. The `finalize_cb` (if non-`NULL`) is also called during a call to `jerry_cleanup ()` to run any custom deinitialization *after* the VM has been fully cleaned up. +If bytes_needed field is 0, no buffer is allocated for the manager, callback functions are called with NULL pointer. **Prototype** diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 6278df3620..2c49f1b911 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -206,7 +206,8 @@ jerry_cleanup (void) { if (this_p->manager_p->deinit_cb) { - this_p->manager_p->deinit_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p)); + void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL; + this_p->manager_p->deinit_cb (data); } } @@ -223,7 +224,8 @@ jerry_cleanup (void) next_p = this_p->next_p; if (this_p->manager_p->finalize_cb) { - this_p->manager_p->finalize_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p)); + void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL; + this_p->manager_p->finalize_cb (data); } jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed); } @@ -249,7 +251,7 @@ jerry_get_context_data (const jerry_context_data_manager_t *manager_p) { if (item_p->manager_p == manager_p) { - return JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p); + return (manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p) : NULL; } } @@ -257,9 +259,13 @@ jerry_get_context_data (const jerry_context_data_manager_t *manager_p) item_p->manager_p = manager_p; item_p->next_p = JERRY_CONTEXT (context_data_p); JERRY_CONTEXT (context_data_p) = item_p; - ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p); - memset (ret, 0, manager_p->bytes_needed); + if (manager_p->bytes_needed > 0) + { + ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p); + memset (ret, 0, manager_p->bytes_needed); + } + if (manager_p->init_cb) { manager_p->init_cb (ret); diff --git a/tests/unit-core/test-context-data.c b/tests/unit-core/test-context-data.c index 56cefcefe0..1522116875 100644 --- a/tests/unit-core/test-context-data.c +++ b/tests/unit-core/test-context-data.c @@ -20,9 +20,12 @@ static bool test_context_data1_new_called = false; static bool test_context_data2_new_called = false; static bool test_context_data3_new_called = false; +static bool test_context_data4_new_called = false; static bool test_context_data1_free_called = false; static bool test_context_data2_free_called = false; +static bool test_context_data4_free_called = false; static bool test_context_data1_finalize_called = false; +static bool test_context_data4_finalize_called = false; /* Context item 1 */ const char *string1 = "item1"; @@ -84,13 +87,12 @@ static const jerry_context_data_manager_t manager2 = }; /* Context item 3 */ -const char *string3 = "item3"; static void test_context_data3_new (void *user_data_p) { + JERRY_UNUSED (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 = @@ -102,6 +104,41 @@ static const jerry_context_data_manager_t manager3 = .bytes_needed = 0, }; +/* Context item 4 */ + +static void +test_context_data4_new (void *user_data_p) +{ + test_context_data4_new_called = true; + TEST_ASSERT (user_data_p == NULL); +} /* test_context_data4_new */ + + +static void +test_context_data4_free (void *user_data_p) +{ + test_context_data4_free_called = true; + TEST_ASSERT (user_data_p == NULL); + TEST_ASSERT (!test_context_data4_finalize_called); +} /* test_context_data4_free */ + +static void +test_context_data4_finalize (void *user_data_p) +{ + TEST_ASSERT (!test_context_data4_finalize_called); + test_context_data4_finalize_called = true; + TEST_ASSERT (user_data_p == NULL); +} /* test_context_data4_finalize */ + +static const jerry_context_data_manager_t manager4 = +{ + .init_cb = test_context_data4_new, + .deinit_cb = test_context_data4_free, + .finalize_cb = test_context_data4_finalize, + .bytes_needed = 0 +}; + + int main (void) { @@ -111,19 +148,26 @@ 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 (jerry_get_context_data (&manager3) == NULL); + TEST_ASSERT (jerry_get_context_data (&manager4) == NULL); 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_data4_new_called); TEST_ASSERT (!test_context_data1_free_called); TEST_ASSERT (!test_context_data2_free_called); + TEST_ASSERT (!test_context_data4_free_called); jerry_cleanup (); TEST_ASSERT (test_context_data1_free_called); TEST_ASSERT (test_context_data2_free_called); + TEST_ASSERT (test_context_data4_free_called); + + TEST_ASSERT (test_context_data1_finalize_called); + TEST_ASSERT (test_context_data4_finalize_called); return 0; } /* main */