mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add public API functions for internal property management (#3128)
These 4 new API functions give possibility to perform [[Get]], [[Set]], [[Has]], [[Delete]] operations for properties which are not accessible from the JavaScript context only from the public API. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
a40eb9bab8
commit
fd1f7eab9f
@ -4683,6 +4683,63 @@ main (void)
|
||||
- [jerry_delete_property](#jerry_delete_property)
|
||||
|
||||
|
||||
## jerry_has_internal_property
|
||||
|
||||
**Summary**
|
||||
|
||||
Checks whether the object has the given internal property.
|
||||
|
||||
*Note*:
|
||||
- Properties which were not created with [jerry_set_internal_property](#jerry_set_internal_property) are excluded
|
||||
during the operation.
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_has_internal_property (const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val);
|
||||
```
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- return value
|
||||
- true, if the property exists
|
||||
- false, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global_object = jerry_get_global_object ();
|
||||
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "hidden_property");
|
||||
|
||||
bool has_internal_js_prop = jerry_has_internal_property (global_object, prop_name);
|
||||
|
||||
jerry_release_value (prop_name);
|
||||
jerry_release_value (global_object);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_delete_internal_property](#jerry_delete_internal_property)
|
||||
- [jerry_get_internal_property](#jerry_get_internal_property)
|
||||
- [jerry_set_internal_property](#jerry_set_internal_property)
|
||||
|
||||
|
||||
## jerry_delete_property
|
||||
|
||||
**Summary**
|
||||
@ -4772,6 +4829,50 @@ jerry_delete_property_by_index (const jerry_value_t obj_val,
|
||||
- [jerry_get_property_by_index](#jerry_get_property_by_index)
|
||||
- [jerry_set_property_by_index](#jerry_set_property_by_index)
|
||||
|
||||
## jerry_delete_internal_property
|
||||
|
||||
**Summary**
|
||||
|
||||
Delete an internal property from an object.
|
||||
|
||||
*Note*: Properties which were not created with [jerry_set_internal_property](#jerry_set_internal_property) are excluded
|
||||
during the operation.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_delete_internal_property (const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val);
|
||||
```
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- return value
|
||||
- true, if property was deleted successfully
|
||||
- false, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t global_object = jerry_get_global_object ();
|
||||
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "hidden_property");
|
||||
|
||||
bool delete_result = jerry_delete_internal_property (global_object, prop_name);
|
||||
/* use "delete_result" */
|
||||
|
||||
jerry_release_value (prop_name);
|
||||
jerry_release_value (global_object);
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_has_internal_property](#jerry_has_internal_property)
|
||||
- [jerry_get_internal_property](#jerry_get_internal_property)
|
||||
- [jerry_set_internal_property](#jerry_set_internal_property)
|
||||
|
||||
|
||||
## jerry_get_property
|
||||
|
||||
@ -4884,6 +4985,66 @@ jerry_get_property_by_index (const jerry_value_t obj_val,
|
||||
- [jerry_set_property](#jerry_set_property)
|
||||
- [jerry_set_property_by_index](#jerry_set_property_by_index)
|
||||
|
||||
## jerry_get_internal_property
|
||||
|
||||
**Summary**
|
||||
|
||||
Get value of an internal property to the specified object with the given name.
|
||||
|
||||
*Note*:
|
||||
- Properties which were not created with [jerry_set_internal_property](#jerry_set_internal_property) are excluded
|
||||
during the operation.
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_get_internal_property (const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val);
|
||||
```
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- return value
|
||||
- value of property, if the internal property exists
|
||||
- undefined value, if the, if the internal does not property exists
|
||||
- thrown error, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global_object = jerry_get_global_object ();
|
||||
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "hidden_property");
|
||||
|
||||
jerry_value_t prop_value = jerry_get_internal_property (global_object, prop_name);
|
||||
|
||||
/* use "prop_value" then release it. */
|
||||
|
||||
jerry_release_value (prop_value);
|
||||
jerry_release_value (prop_name);
|
||||
jerry_release_value (global_object);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_has_internal_property](#jerry_has_internal_property)
|
||||
- [jerry_delete_internal_property](#jerry_delete_internal_property)
|
||||
- [jerry_set_internal_property](#jerry_set_internal_property)
|
||||
|
||||
|
||||
## jerry_set_property
|
||||
|
||||
@ -5001,6 +5162,68 @@ jerry_set_property_by_index (const jerry_value_t obj_val,
|
||||
- [jerry_get_property_by_index](#jerry_get_property_by_index)
|
||||
|
||||
|
||||
## jerry_set_internal_property
|
||||
|
||||
**Summary**
|
||||
|
||||
Set an internal property to the specified object with the given name.
|
||||
|
||||
*Note*:
|
||||
- The property cannot be accessed from the JavaScript context, only from the public API.
|
||||
- It is different from [jerry_set_object_native_pointer](#jerry_set_object_native_pointer) in that any jerry API value
|
||||
can be hidden from the JavaScript context, not only native pointers.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_set_internal_property (const jerry_value_t obj_val,
|
||||
const jerry_value_t prop_name_val,
|
||||
const jerry_value_t value_to_set)
|
||||
```
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- `value_to_set` - value to set
|
||||
- return value
|
||||
- true, if success
|
||||
- thrown error, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global_object = jerry_get_global_object ();
|
||||
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "hidden_property");
|
||||
jerry_value_t value_to_set = jerry_create_number (5);
|
||||
|
||||
bool set_result = jerry_set_internal_property (global_object, prop_name, value_to_set);
|
||||
|
||||
/* check the result of internal property set call */
|
||||
|
||||
jerry_release_value (value_to_set);
|
||||
jerry_release_value (prop_name);
|
||||
jerry_release_value (global_object);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_has_internal_property](#jerry_has_internal_property)
|
||||
- [jerry_delete_internal_property](#jerry_delete_internal_property)
|
||||
- [jerry_get_internal_property](#jerry_get_internal_property)
|
||||
|
||||
|
||||
## jerry_init_property_descriptor_fields
|
||||
|
||||
**Summary**
|
||||
@ -5763,6 +5986,9 @@ You can get them by calling [jerry_get_object_native_pointer](#jerry_get_object_
|
||||
the free callback will be invoked during the execution of `jerry_cleanup`.
|
||||
- The free callback **must not** invoke API functions.
|
||||
|
||||
*Note*: If possible do not store API values in native pointers, rather check
|
||||
[jerry_set_internal_property](#jerry_set_internal_property).
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
|
||||
@ -1996,6 +1996,47 @@ jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
return ecma_make_boolean_value (has_property);
|
||||
} /* jerry_has_own_property */
|
||||
|
||||
/**
|
||||
* Checks whether the object has the given internal property.
|
||||
*
|
||||
* @return true - if the internal property exists
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_has_internal_property (const jerry_value_t obj_val, /**< object value */
|
||||
const jerry_value_t prop_name_val) /**< property name value */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (!ecma_is_value_object (obj_val)
|
||||
|| !ecma_is_value_prop_name (prop_name_val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
|
||||
|
||||
return property_p != NULL;
|
||||
} /* jerry_has_internal_property */
|
||||
|
||||
/**
|
||||
* Delete a property from an object.
|
||||
*
|
||||
@ -2046,6 +2087,54 @@ jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value *
|
||||
return ecma_is_value_true (ret_value);
|
||||
} /* jerry_delete_property_by_index */
|
||||
|
||||
/**
|
||||
* Delete an internal property from an object.
|
||||
*
|
||||
* @return true - if property was deleted successfully
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_delete_internal_property (const jerry_value_t obj_val, /**< object value */
|
||||
const jerry_value_t prop_name_val) /**< property name value */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (!ecma_is_value_object (obj_val)
|
||||
|| !ecma_is_value_prop_name (prop_name_val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_delete_property (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p));
|
||||
|
||||
return true;
|
||||
} /* jerry_delete_internal_property */
|
||||
|
||||
/**
|
||||
* Get value of a property to the specified object with the given name.
|
||||
*
|
||||
@ -2099,6 +2188,56 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
|
||||
return jerry_return (ret_value);
|
||||
} /* jerry_get_property_by_index */
|
||||
|
||||
/**
|
||||
* Get value of an internal property to the specified object with the given name.
|
||||
*
|
||||
* Note:
|
||||
* returned value must be freed with jerry_release_value, when it is no longer needed.
|
||||
*
|
||||
* @return value of the internal property - if the internal property exists
|
||||
* undefined value - if the internal does not property exists
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_get_internal_property (const jerry_value_t obj_val, /**< object value */
|
||||
const jerry_value_t prop_name_val) /**< property name value */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (!ecma_is_value_object (obj_val)
|
||||
|| !ecma_is_value_prop_name (prop_name_val))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
return jerry_return (ECMA_VALUE_UNDEFINED);
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
return jerry_return (ECMA_VALUE_UNDEFINED);
|
||||
}
|
||||
|
||||
ecma_object_t *internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
property_p = ecma_find_named_property (internal_object_p, ecma_get_prop_name_from_value (prop_name_val));
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
return jerry_return (ECMA_VALUE_UNDEFINED);
|
||||
}
|
||||
|
||||
return jerry_return (ecma_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value));
|
||||
} /* jerry_get_internal_property */
|
||||
|
||||
/**
|
||||
* Set a property to the specified object with the given name.
|
||||
*
|
||||
@ -2160,6 +2299,79 @@ jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */
|
||||
return jerry_return (ret_value);
|
||||
} /* jerry_set_property_by_index */
|
||||
|
||||
/**
|
||||
* Set an internal property to the specified object with the given name.
|
||||
*
|
||||
* Note:
|
||||
* - the property cannot be accessed from the JavaScript context, only from the public API
|
||||
* - returned value must be freed with jerry_release_value, when it is no longer needed.
|
||||
*
|
||||
* @return true value - if the operation was successful
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_set_internal_property (const jerry_value_t obj_val, /**< object value */
|
||||
const jerry_value_t prop_name_val, /**< property name value */
|
||||
const jerry_value_t value_to_set) /**< value to set */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (ecma_is_value_error_reference (value_to_set)
|
||||
|| !ecma_is_value_object (obj_val)
|
||||
|| !ecma_is_value_prop_name (prop_name_val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
ecma_string_t *internal_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_API_INTERNAL);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (obj_p);
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, internal_string_p);
|
||||
ecma_object_t *internal_object_p;
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
ecma_property_value_t *value_p = ecma_create_named_data_property (obj_p,
|
||||
internal_string_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
|
||||
internal_object_p = ecma_create_object (NULL, 0, ECMA_OBJECT_TYPE_GENERAL);
|
||||
value_p->value = ecma_make_object_value (internal_object_p);
|
||||
ecma_deref_object (internal_object_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_object_p = ecma_get_object_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val);
|
||||
property_p = ecma_find_named_property (internal_object_p, prop_name_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
{
|
||||
ecma_property_value_t *value_p = ecma_create_named_data_property (internal_object_p,
|
||||
prop_name_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
|
||||
value_p->value = ecma_copy_value_if_not_object (value_to_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_named_data_property_assign_value (internal_object_p, ECMA_PROPERTY_VALUE_PTR (property_p), value_to_set);
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* jerry_set_internal_property */
|
||||
|
||||
/**
|
||||
* Initialize property descriptor.
|
||||
*/
|
||||
|
||||
@ -502,15 +502,20 @@ jerry_value_t jerry_create_undefined (void);
|
||||
*/
|
||||
jerry_value_t jerry_has_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
jerry_value_t jerry_has_own_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
bool jerry_has_internal_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
bool jerry_delete_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
bool jerry_delete_property_by_index (const jerry_value_t obj_val, uint32_t index);
|
||||
bool jerry_delete_internal_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
|
||||
jerry_value_t jerry_get_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
jerry_value_t jerry_get_property_by_index (const jerry_value_t obj_val, uint32_t index);
|
||||
jerry_value_t jerry_get_internal_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val);
|
||||
jerry_value_t jerry_set_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val,
|
||||
const jerry_value_t value_to_set);
|
||||
jerry_value_t jerry_set_property_by_index (const jerry_value_t obj_val, uint32_t index,
|
||||
const jerry_value_t value_to_set);
|
||||
bool jerry_set_internal_property (const jerry_value_t obj_val, const jerry_value_t prop_name_val,
|
||||
const jerry_value_t value_to_set);
|
||||
|
||||
void jerry_init_property_descriptor_fields (jerry_property_descriptor_t *prop_desc_p);
|
||||
jerry_value_t jerry_define_own_property (const jerry_value_t obj_val,
|
||||
|
||||
@ -48,6 +48,7 @@ typedef enum
|
||||
LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT, /**< [[RemainingElement]] property */
|
||||
LIT_INTERNAL_MAGIC_STRING_ITERATOR_NEXT_INDEX, /**< [[%Iterator%NextIndex]] property */
|
||||
LIT_INTERNAL_MAGIC_STRING_MAP_KEY, /**< Property key used when an object is a key in a map object */
|
||||
LIT_INTERNAL_MAGIC_API_INTERNAL, /**< Property key used to add non-visible JS properties from the public API */
|
||||
/* List of well known symbols */
|
||||
LIT_GLOBAL_SYMBOL_HAS_INSTANCE, /**< @@hasInstance well known symbol */
|
||||
LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE, /**< @@isConcatSpreadable well known symbol */
|
||||
|
||||
240
tests/unit-core/test-internal-properties.c
Normal file
240
tests/unit-core/test-internal-properties.c
Normal file
@ -0,0 +1,240 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "test-common.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t object = jerry_create_object ();
|
||||
|
||||
jerry_value_t prop_name_1 = jerry_create_string ((const jerry_char_t *) "foo");
|
||||
jerry_value_t prop_name_2 = jerry_create_string ((const jerry_char_t *) "non_hidden_prop");
|
||||
jerry_value_t prop_name_3;
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_SYMBOL))
|
||||
{
|
||||
jerry_value_t prop_name_3_desc = jerry_create_string ((const jerry_char_t *) "bar");
|
||||
prop_name_3 = jerry_create_symbol (prop_name_3_desc);
|
||||
jerry_release_value (prop_name_3_desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_name_3 = jerry_create_string ((const jerry_char_t *) "non_hidden_string_prop");
|
||||
}
|
||||
|
||||
jerry_value_t internal_prop_name_1 = jerry_create_string ((const jerry_char_t *) "hidden_foo");
|
||||
jerry_value_t internal_prop_name_2 = jerry_create_string ((const jerry_char_t *) "hidden_prop");
|
||||
jerry_value_t internal_prop_name_3;
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_SYMBOL))
|
||||
{
|
||||
jerry_value_t internal_prop_name_3_desc = jerry_create_string ((const jerry_char_t *) "bar");
|
||||
internal_prop_name_3 = jerry_create_symbol (internal_prop_name_3_desc);
|
||||
jerry_release_value (internal_prop_name_3_desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_prop_name_3 = jerry_create_string ((const jerry_char_t *) "hidden_string_prop");
|
||||
}
|
||||
|
||||
jerry_value_t prop_value_1 = jerry_create_number (5.5);
|
||||
jerry_value_t prop_value_2 = jerry_create_number (6.5);
|
||||
jerry_value_t prop_value_3 = jerry_create_number (7.5);
|
||||
|
||||
jerry_value_t internal_prop_value_1 = jerry_create_number (8.5);
|
||||
jerry_value_t internal_prop_value_2 = jerry_create_number (9.5);
|
||||
jerry_value_t internal_prop_value_3 = jerry_create_number (10.5);
|
||||
|
||||
/* Test the normal [[Set]] method */
|
||||
bool set_result_1 = jerry_set_property (object, prop_name_1, prop_value_1);
|
||||
bool set_result_2 = jerry_set_property (object, prop_name_2, prop_value_2);
|
||||
bool set_result_3 = jerry_set_property (object, prop_name_3, prop_value_3);
|
||||
|
||||
TEST_ASSERT (set_result_1);
|
||||
TEST_ASSERT (set_result_2);
|
||||
TEST_ASSERT (set_result_3);
|
||||
|
||||
/* Test the internal [[Set]] method */
|
||||
bool set_internal_result_1 = jerry_set_internal_property (object, internal_prop_name_1, internal_prop_value_1);
|
||||
bool set_internal_result_2 = jerry_set_internal_property (object, internal_prop_name_2, internal_prop_value_2);
|
||||
bool set_internal_result_3 = jerry_set_internal_property (object, internal_prop_name_3, internal_prop_value_3);
|
||||
|
||||
TEST_ASSERT (set_internal_result_1);
|
||||
TEST_ASSERT (set_internal_result_2);
|
||||
TEST_ASSERT (set_internal_result_3);
|
||||
|
||||
/* Test the normal [[Has]] method. */
|
||||
jerry_value_t has_result_1 = jerry_has_property (object, prop_name_1);
|
||||
jerry_value_t has_result_2 = jerry_has_property (object, prop_name_2);
|
||||
jerry_value_t has_result_3 = jerry_has_property (object, prop_name_3);
|
||||
jerry_value_t has_result_4 = jerry_has_property (object, internal_prop_name_1);
|
||||
jerry_value_t has_result_5 = jerry_has_property (object, internal_prop_name_2);
|
||||
jerry_value_t has_result_6 = jerry_has_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_1) && jerry_get_boolean_value (has_result_1));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_2) && jerry_get_boolean_value (has_result_2));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_3) && jerry_get_boolean_value (has_result_3));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_4) && !jerry_get_boolean_value (has_result_4));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_5) && !jerry_get_boolean_value (has_result_5));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_result_6) && !jerry_get_boolean_value (has_result_6));
|
||||
|
||||
jerry_release_value (has_result_1);
|
||||
jerry_release_value (has_result_2);
|
||||
jerry_release_value (has_result_3);
|
||||
jerry_release_value (has_result_4);
|
||||
jerry_release_value (has_result_5);
|
||||
jerry_release_value (has_result_6);
|
||||
|
||||
/* Test the internal [[Has]] method. */
|
||||
bool has_internal_result_1 = jerry_has_internal_property (object, prop_name_1);
|
||||
bool has_internal_result_2 = jerry_has_internal_property (object, prop_name_2);
|
||||
bool has_internal_result_3 = jerry_has_internal_property (object, prop_name_3);
|
||||
bool has_internal_result_4 = jerry_has_internal_property (object, internal_prop_name_1);
|
||||
bool has_internal_result_5 = jerry_has_internal_property (object, internal_prop_name_2);
|
||||
bool has_internal_result_6 = jerry_has_internal_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (!has_internal_result_1);
|
||||
TEST_ASSERT (!has_internal_result_2);
|
||||
TEST_ASSERT (!has_internal_result_3);
|
||||
TEST_ASSERT (has_internal_result_4);
|
||||
TEST_ASSERT (has_internal_result_5);
|
||||
TEST_ASSERT (has_internal_result_6);
|
||||
|
||||
/* Test the normal [[Get]] method. */
|
||||
jerry_value_t get_result_1 = jerry_get_property (object, prop_name_1);
|
||||
jerry_value_t get_result_2 = jerry_get_property (object, prop_name_2);
|
||||
jerry_value_t get_result_3 = jerry_get_property (object, prop_name_3);
|
||||
jerry_value_t get_result_4 = jerry_get_property (object, internal_prop_name_1);
|
||||
jerry_value_t get_result_5 = jerry_get_property (object, internal_prop_name_2);
|
||||
jerry_value_t get_result_6 = jerry_get_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_number (get_result_1) && jerry_get_number_value (get_result_1) == 5.5);
|
||||
TEST_ASSERT (jerry_value_is_number (get_result_2) && jerry_get_number_value (get_result_2) == 6.5);
|
||||
TEST_ASSERT (jerry_value_is_number (get_result_3) && jerry_get_number_value (get_result_3) == 7.5);
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_result_4));
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_result_5));
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_result_6));
|
||||
|
||||
jerry_release_value (get_result_1);
|
||||
jerry_release_value (get_result_2);
|
||||
jerry_release_value (get_result_3);
|
||||
jerry_release_value (get_result_4);
|
||||
jerry_release_value (get_result_5);
|
||||
jerry_release_value (get_result_6);
|
||||
|
||||
/* Test the internal [[Get]] method. */
|
||||
jerry_value_t get_internal_result_1 = jerry_get_internal_property (object, prop_name_1);
|
||||
jerry_value_t get_internal_result_2 = jerry_get_internal_property (object, prop_name_2);
|
||||
jerry_value_t get_internal_result_3 = jerry_get_internal_property (object, prop_name_3);
|
||||
jerry_value_t get_internal_result_4 = jerry_get_internal_property (object, internal_prop_name_1);
|
||||
jerry_value_t get_internal_result_5 = jerry_get_internal_property (object, internal_prop_name_2);
|
||||
jerry_value_t get_internal_result_6 = jerry_get_internal_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_internal_result_1));
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_internal_result_2));
|
||||
TEST_ASSERT (jerry_value_is_undefined (get_internal_result_3));
|
||||
TEST_ASSERT (jerry_value_is_number (get_internal_result_4) && jerry_get_number_value (get_internal_result_4) == 8.5);
|
||||
TEST_ASSERT (jerry_value_is_number (get_internal_result_5) && jerry_get_number_value (get_internal_result_5) == 9.5);
|
||||
TEST_ASSERT (jerry_value_is_number (get_internal_result_6) && jerry_get_number_value (get_internal_result_6) == 10.5);
|
||||
|
||||
jerry_release_value (get_internal_result_1);
|
||||
jerry_release_value (get_internal_result_2);
|
||||
jerry_release_value (get_internal_result_3);
|
||||
jerry_release_value (get_internal_result_4);
|
||||
jerry_release_value (get_internal_result_5);
|
||||
jerry_release_value (get_internal_result_6);
|
||||
|
||||
/* Test the normal [[Delete]] method. */
|
||||
bool delete_result_1 = jerry_delete_property (object, prop_name_1);
|
||||
bool delete_result_2 = jerry_delete_property (object, prop_name_2);
|
||||
bool delete_result_3 = jerry_delete_property (object, prop_name_3);
|
||||
bool delete_result_4 = jerry_delete_property (object, internal_prop_name_1);
|
||||
bool delete_result_5 = jerry_delete_property (object, internal_prop_name_2);
|
||||
bool delete_result_6 = jerry_delete_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (delete_result_1);
|
||||
TEST_ASSERT (delete_result_2);
|
||||
TEST_ASSERT (delete_result_3);
|
||||
TEST_ASSERT (delete_result_4);
|
||||
TEST_ASSERT (delete_result_5);
|
||||
TEST_ASSERT (delete_result_6);
|
||||
|
||||
jerry_value_t has_after_delete_result_1 = jerry_has_property (object, prop_name_1);
|
||||
jerry_value_t has_after_delete_result_2 = jerry_has_property (object, prop_name_2);
|
||||
jerry_value_t has_after_delete_result_3 = jerry_has_property (object, prop_name_3);
|
||||
bool has_after_delete_result_4 = jerry_has_internal_property (object, internal_prop_name_1);
|
||||
bool has_after_delete_result_5 = jerry_has_internal_property (object, internal_prop_name_2);
|
||||
bool has_after_delete_result_6 = jerry_has_internal_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_after_delete_result_1)
|
||||
&& !jerry_get_boolean_value (has_after_delete_result_1));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_after_delete_result_2)
|
||||
&& !jerry_get_boolean_value (has_after_delete_result_2));
|
||||
TEST_ASSERT (jerry_value_is_boolean (has_after_delete_result_3)
|
||||
&& !jerry_get_boolean_value (has_after_delete_result_3));
|
||||
TEST_ASSERT (has_after_delete_result_4);
|
||||
TEST_ASSERT (has_after_delete_result_5);
|
||||
TEST_ASSERT (has_after_delete_result_6);
|
||||
|
||||
jerry_release_value (has_after_delete_result_1);
|
||||
jerry_release_value (has_after_delete_result_2);
|
||||
jerry_release_value (has_after_delete_result_3);
|
||||
|
||||
/* Test the internal [[Delete]] method. */
|
||||
bool delete_internal_result_4 = jerry_delete_internal_property (object, internal_prop_name_1);
|
||||
bool delete_internal_result_5 = jerry_delete_internal_property (object, internal_prop_name_2);
|
||||
bool delete_internal_result_6 = jerry_delete_internal_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (delete_internal_result_4);
|
||||
TEST_ASSERT (delete_internal_result_5);
|
||||
TEST_ASSERT (delete_internal_result_6);
|
||||
|
||||
bool has_after_internal_delete_result_1 = jerry_has_internal_property (object, internal_prop_name_1);
|
||||
bool has_after_internal_delete_result_2 = jerry_has_internal_property (object, internal_prop_name_2);
|
||||
bool has_after_internal_delete_result_3 = jerry_has_internal_property (object, internal_prop_name_3);
|
||||
|
||||
TEST_ASSERT (!has_after_internal_delete_result_1);
|
||||
TEST_ASSERT (!has_after_internal_delete_result_2);
|
||||
TEST_ASSERT (!has_after_internal_delete_result_3);
|
||||
|
||||
/* Cleanup */
|
||||
jerry_release_value (prop_value_3);
|
||||
jerry_release_value (prop_value_2);
|
||||
jerry_release_value (prop_value_1);
|
||||
|
||||
jerry_release_value (prop_name_3);
|
||||
jerry_release_value (prop_name_2);
|
||||
jerry_release_value (prop_name_1);
|
||||
|
||||
jerry_release_value (internal_prop_value_3);
|
||||
jerry_release_value (internal_prop_value_2);
|
||||
jerry_release_value (internal_prop_value_1);
|
||||
|
||||
jerry_release_value (internal_prop_name_3);
|
||||
jerry_release_value (internal_prop_name_2);
|
||||
jerry_release_value (internal_prop_name_1);
|
||||
|
||||
jerry_release_value (object);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
Loading…
x
Reference in New Issue
Block a user