mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add foreach function for inquiry properties into obj
JerryScript-DCO-1.0-Signed-off-by: pius.lee pius.lee@samsung.com
This commit is contained in:
parent
3d286b46d0
commit
ece246ef9e
@ -140,6 +140,13 @@ typedef bool (*jerry_external_handler_t) (const jerry_api_object_t *function_obj
|
||||
*/
|
||||
typedef void (*jerry_object_free_callback_t) (const uintptr_t native_p);
|
||||
|
||||
/**
|
||||
* function type applied for each fields in objects
|
||||
*/
|
||||
typedef bool (*jerry_object_field_foreach_t) (const jerry_api_string_t *field_name_p,
|
||||
const jerry_api_value_t *field_value_p,
|
||||
void *user_data_p);
|
||||
|
||||
extern EXTERN_C ssize_t
|
||||
jerry_api_string_to_char_buffer (const jerry_api_string_t *, jerry_api_char_t *, ssize_t);
|
||||
extern EXTERN_C
|
||||
@ -200,6 +207,9 @@ extern EXTERN_C
|
||||
bool jerry_api_set_object_field_value_sz (jerry_api_object_t *, const jerry_api_char_t *, jerry_api_size_t,
|
||||
const jerry_api_value_t *);
|
||||
|
||||
extern EXTERN_C
|
||||
bool jerry_api_foreach_object_field (jerry_api_object_t *, jerry_object_field_foreach_t, void *);
|
||||
|
||||
extern EXTERN_C
|
||||
bool jerry_api_get_object_native_handle (jerry_api_object_t *, uintptr_t *);
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "ecma-init-finalize.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "lit-magic-strings.h"
|
||||
#include "parser.h"
|
||||
#include "serializer.h"
|
||||
@ -898,6 +899,63 @@ bool jerry_api_get_object_field_value (jerry_api_object_t *object_p,
|
||||
field_value_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given function to the every fields in the objects
|
||||
*
|
||||
* @return true, if object fields traversal was performed successfully, i.e.:
|
||||
* - no unhandled exceptions were thrown in object fields traversal;
|
||||
* - object fields traversal was stopped on callback that returned false;
|
||||
* false - otherwise,
|
||||
* if getter of field threw a exception or unhandled exceptions were thrown during traversal;
|
||||
*/
|
||||
bool
|
||||
jerry_api_foreach_object_field (jerry_api_object_t *object_p, /**< object */
|
||||
jerry_object_field_foreach_t foreach_p, /**< foreach function */
|
||||
void *user_data_p) /**< user data for foreach function */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
ecma_collection_iterator_t names_iter;
|
||||
ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, false, true, true);
|
||||
ecma_collection_iterator_init (&names_iter, names_p);
|
||||
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
bool continuous = true;
|
||||
|
||||
while (ecma_is_completion_value_empty (ret_value)
|
||||
&& continuous
|
||||
&& ecma_collection_iterator_next (&names_iter))
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*names_iter.current_value_p);
|
||||
|
||||
ECMA_TRY_CATCH (property_value, ecma_op_object_get (object_p, property_name_p), ret_value);
|
||||
|
||||
jerry_api_value_t field_value;
|
||||
jerry_api_convert_ecma_value_to_api_value (&field_value, property_value);
|
||||
|
||||
continuous = foreach_p (property_name_p, &field_value, user_data_p);
|
||||
|
||||
jerry_api_release_value (&field_value);
|
||||
|
||||
ECMA_FINALIZE (property_value);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (names_p, true);
|
||||
if (ecma_is_completion_value_empty (ret_value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_completion_value_throw (ret_value));
|
||||
|
||||
ecma_free_completion_value (ret_value);
|
||||
|
||||
return false;
|
||||
}
|
||||
} /* jerry_api_foreach_object_field */
|
||||
|
||||
/**
|
||||
* Get value of field in the specified object
|
||||
*
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "jerry.h"
|
||||
#include "jerry-api.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "test-common.h"
|
||||
|
||||
@ -54,6 +55,9 @@ const char *test_source = (
|
||||
"function throw_reference_error() { "
|
||||
" throw new ReferenceError ();"
|
||||
"} "
|
||||
"p = {'alpha':32, 'bravo':false, 'charlie':{}, 'delta':123.45, 'echo':'foobar'};"
|
||||
"np = {}; Object.defineProperty (np, 'foxtrot', { "
|
||||
"get: function() { throw 'error'; }, enumerable: true }) "
|
||||
);
|
||||
|
||||
bool test_api_is_free_callback_was_called = false;
|
||||
@ -231,8 +235,81 @@ const jerry_api_char_ptr_t magic_string_items[] =
|
||||
#undef JERRY_MAGIC_STRING_DEF
|
||||
};
|
||||
|
||||
static bool foreach (const jerry_api_string_t *name,
|
||||
const jerry_api_value_t *value, void *user_data)
|
||||
{
|
||||
char str_buf_p[128];
|
||||
ssize_t sz = jerry_api_string_to_char_buffer (name, (jerry_api_char_t *)str_buf_p, 128);
|
||||
str_buf_p[sz] = '\0';
|
||||
|
||||
if (!strncmp (str_buf_p, "alpha", (size_t)sz))
|
||||
{
|
||||
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_FLOAT32);
|
||||
JERRY_ASSERT (value->v_float32 == 32.0f);
|
||||
#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_FLOAT64);
|
||||
JERRY_ASSERT (value->v_float64 == 32.0);
|
||||
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
|
||||
}
|
||||
else if (!strncmp (str_buf_p, "bravo", (size_t)sz))
|
||||
{
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_BOOLEAN);
|
||||
JERRY_ASSERT (value->v_bool == false);
|
||||
}
|
||||
else if (!strncmp (str_buf_p, "charlie", (size_t)sz))
|
||||
{
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_OBJECT);
|
||||
}
|
||||
else if (!strncmp (str_buf_p, "delta", (size_t)sz))
|
||||
{
|
||||
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_FLOAT32);
|
||||
JERRY_ASSERT (value->v_float32 == 123.45f);
|
||||
#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_FLOAT64);
|
||||
JERRY_ASSERT (value->v_float64 == 123.45);
|
||||
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
|
||||
}
|
||||
else if (!strncmp (str_buf_p, "echo", (size_t)sz))
|
||||
{
|
||||
JERRY_ASSERT (value->type == JERRY_API_DATA_TYPE_STRING);
|
||||
ssize_t echo_sz = jerry_api_string_to_char_buffer (value->v_string, (jerry_api_char_t *)str_buf_p, 128);
|
||||
str_buf_p[echo_sz] = '\0';
|
||||
JERRY_ASSERT (!strncmp (str_buf_p, "foobar", (size_t)echo_sz));
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (false);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!strncmp ((const char*)user_data, "user_data", 9));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool foreach_exception (const jerry_api_string_t *name, const jerry_api_value_t *, void *)
|
||||
{
|
||||
char str_buf_p[128];
|
||||
ssize_t sz = jerry_api_string_to_char_buffer (name, (jerry_api_char_t *)str_buf_p, 128);
|
||||
str_buf_p[sz] = '\0';
|
||||
|
||||
if (!strncmp (str_buf_p, "foxtrot", (size_t)sz))
|
||||
{
|
||||
JERRY_ASSERT (false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool foreach_subset (const jerry_api_string_t *, const jerry_api_value_t *, void *user_data)
|
||||
{
|
||||
int *count_p = reinterpret_cast<int *>(user_data);
|
||||
if (*count_p == 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
(*count_p)++;
|
||||
return true;
|
||||
}
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
@ -242,7 +319,7 @@ main (void)
|
||||
|
||||
bool is_ok, is_exception;
|
||||
ssize_t sz;
|
||||
jerry_api_value_t val_t, val_foo, val_bar, val_A, val_A_prototype, val_a, val_a_foo, val_value_field;
|
||||
jerry_api_value_t val_t, val_foo, val_bar, val_A, val_A_prototype, val_a, val_a_foo, val_value_field, val_p, val_np;
|
||||
jerry_api_value_t val_external, val_external_construct, val_call_external;
|
||||
jerry_api_object_t* global_obj_p, *obj_p;
|
||||
jerry_api_object_t* external_func_p, *external_construct_p;
|
||||
@ -352,6 +429,24 @@ main (void)
|
||||
&& res.v_float64 == 12.0);
|
||||
jerry_api_release_value (&res);
|
||||
|
||||
// foreach properties
|
||||
jerry_api_get_object_field_value (global_obj_p, (jerry_api_char_t *) "p", &val_p);
|
||||
is_ok = jerry_api_foreach_object_field (val_p.v_object, foreach, (void*)"user_data");
|
||||
JERRY_ASSERT (is_ok);
|
||||
|
||||
// break foreach at third element
|
||||
int count = 0;
|
||||
is_ok = jerry_api_foreach_object_field (val_p.v_object, foreach_subset, &count);
|
||||
JERRY_ASSERT (is_ok);
|
||||
JERRY_ASSERT (count == 3);
|
||||
jerry_api_release_value (&val_p);
|
||||
|
||||
// foreach with throw test
|
||||
jerry_api_get_object_field_value (global_obj_p, (jerry_api_char_t *) "np", &val_np);
|
||||
is_ok = !jerry_api_foreach_object_field (val_np.v_object, foreach_exception, NULL);
|
||||
JERRY_ASSERT (is_ok);
|
||||
jerry_api_release_value (&val_np);
|
||||
|
||||
// Get a.foo
|
||||
is_ok = jerry_api_get_object_field_value (val_a.v_object, (jerry_api_char_t *) "foo", &val_a_foo);
|
||||
JERRY_ASSERT (is_ok
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user