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:
Robert Fancsik 2019-10-17 13:56:49 +02:00 committed by GitHub
parent a40eb9bab8
commit fd1f7eab9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 684 additions and 0 deletions

View File

@ -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

View File

@ -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.
*/

View File

@ -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,

View File

@ -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 */

View 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 */