mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implement the core of Proxy object (#3562)
- Internal routines of the of the proxy object are unimplemented - For-in enumerate with proxy target is currently not supported JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
9b393ee2ea
commit
4e136c8973
@ -70,6 +70,7 @@ Possible compile time enabled feature types:
|
||||
- JERRY_FEATURE_LOGGING - logging
|
||||
- JERRY_FEATURE_SYMBOL - symbol support
|
||||
- JERRY_FEATURE_DATAVIEW - DataView support
|
||||
- JERRY_FEATURE_PROXY - Proxy support
|
||||
|
||||
*New in version 2.0*.
|
||||
|
||||
@ -1865,6 +1866,55 @@ jerry_value_is_promise (const jerry_value_t value)
|
||||
- [jerry_create_promise](#jerry_create_promise)
|
||||
|
||||
|
||||
## jerry_value_is_proxy
|
||||
|
||||
**Summary**
|
||||
|
||||
Returns whether the given `jerry_value_t` is a proxy value.
|
||||
|
||||
*Notes*:
|
||||
- This API depends on a build option (`JERRY_ES2015_BUILTIN_PROXY`) and can be checked
|
||||
in runtime with the `JERRY_FEATURE_PROXY` feature enum value,
|
||||
see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
|
||||
- The ES2015-subset profile enables this by default.
|
||||
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_value_is_proxy (const jerry_value_t value)
|
||||
```
|
||||
|
||||
- `value` - api value
|
||||
- return value
|
||||
- true, if the given `jerry_value_t` is a proxy object
|
||||
- false, otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
*New in version [next_version]*.
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
... // create or acquire value
|
||||
|
||||
if (jerry_value_is_proxy (value))
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
- [jerry_create_proxy](#jerry_create_proxy)
|
||||
|
||||
|
||||
## jerry_value_is_string
|
||||
|
||||
**Summary**
|
||||
@ -4212,6 +4262,65 @@ jerry_create_promise (void)
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
|
||||
|
||||
## jerry_create_proxy
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a new Proxy object with the given target and handler.
|
||||
|
||||
*Note*:
|
||||
- This API depends on the ES2015-subset profile.
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value)
|
||||
when it is no longer needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_create_proxy (const jerry_value_t target,
|
||||
const jerry_value_t handler)
|
||||
```
|
||||
|
||||
- `target` - proxy target
|
||||
- `handler` - proxy handler
|
||||
- return thrown error - if the Proxy construction fails
|
||||
value of the newly created proxy object - otherwise
|
||||
|
||||
**Example**
|
||||
|
||||
*New in version [next_version]*.
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t target = jerry_create_object ();
|
||||
jerry_value_t handler = jerry_create_object ();
|
||||
jerry_value_t proxy = jerry_create_proxy (target, handler);
|
||||
|
||||
jerry_release_value (target);
|
||||
jerry_release_value (handler);
|
||||
|
||||
// usage of the proxy
|
||||
|
||||
jerry_release_value (proxy);
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_value_is_proxy](#jerry_value_is_proxy)
|
||||
- [jerry_release_value](#jerry_release_value)
|
||||
|
||||
|
||||
## jerry_create_string
|
||||
|
||||
**Summary**
|
||||
@ -4746,9 +4855,9 @@ jerry_has_property (const jerry_value_t obj_val,
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- return value - JavaScript boolean value that evaluates to
|
||||
- true, if the property exists
|
||||
- false, otherwise
|
||||
- return value - JavaScript value that evaluates to
|
||||
- raised error - if the operation fail
|
||||
- true/false API value - depend on whether the property exists
|
||||
|
||||
*Changed in version 2.0*: The return value type is now a JavaScript value and not a primitive boolean value.
|
||||
|
||||
@ -4805,9 +4914,9 @@ jerry_has_own_property (const jerry_value_t obj_val,
|
||||
|
||||
- `obj_val` - object value
|
||||
- `prop_name_val` - property name
|
||||
- return value - JavaScript boolean value that evaluates to
|
||||
- true, if the property exists
|
||||
- false, otherwise
|
||||
- return value - JavaScript value that evaluates to
|
||||
- raised error - if the operation fails
|
||||
- true/false API value - depend on whether the property exists
|
||||
|
||||
*Changed in version 2.0*: The return value type is now a JavaScript value and not a primitive boolean value.
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-regexp-object.h"
|
||||
#include "ecma-promise-object.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-symbol-object.h"
|
||||
#include "ecma-typedarray-object.h"
|
||||
#include "opcodes.h"
|
||||
@ -803,6 +804,25 @@ jerry_value_is_promise (const jerry_value_t value) /**< api value */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
|
||||
} /* jerry_value_is_promise */
|
||||
|
||||
/**
|
||||
* Check if the specified value is a proxy object.
|
||||
*
|
||||
* @return true - if the specified value is a proxy object,
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_value_is_proxy (const jerry_value_t value) /**< api value */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
return (ecma_is_value_object (value)
|
||||
&& ECMA_OBJECT_IS_PROXY (ecma_get_object_from_value (value)));
|
||||
#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
JERRY_UNUSED (value);
|
||||
return false;
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
} /* jerry_value_is_proxy */
|
||||
|
||||
/**
|
||||
* Check if the specified value is string.
|
||||
*
|
||||
@ -966,6 +986,9 @@ jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check *
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
|
||||
|| feature == JERRY_FEATURE_DATAVIEW
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
|| feature == JERRY_FEATURE_PROXY
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
#if ENABLED (JERRY_BUILTIN_DATE)
|
||||
|| feature == JERRY_FEATURE_DATE
|
||||
#endif /* ENABLED (JERRY_BUILTIN_DATE) */
|
||||
@ -1585,6 +1608,34 @@ jerry_create_promise (void)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
|
||||
} /* jerry_create_promise */
|
||||
|
||||
/**
|
||||
* Create a new Proxy object with the given target and handler
|
||||
*
|
||||
* Note:
|
||||
* returned value must be freed with jerry_release_value, when it is no longer needed.
|
||||
*
|
||||
* @return value of the created Proxy object
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_create_proxy (const jerry_value_t target, /**< target argument */
|
||||
const jerry_value_t handler) /**< handler argument */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
if (ecma_is_value_error_reference (target)
|
||||
|| ecma_is_value_error_reference (handler))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
ecma_object_t *proxy_p = ecma_proxy_create (target, handler);
|
||||
return jerry_return (proxy_p == NULL ? ECMA_VALUE_ERROR : ecma_make_object_value (proxy_p));
|
||||
#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Proxy is not supported.")));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
} /* jerry_create_proxy */
|
||||
|
||||
/**
|
||||
* Create string from a valid UTF-8 string
|
||||
*
|
||||
@ -1986,8 +2037,8 @@ jerry_substring_to_utf8_char_buffer (const jerry_value_t value, /**< input strin
|
||||
/**
|
||||
* Checks whether the object or it's prototype objects have the given property.
|
||||
*
|
||||
* @return true - if the property exists
|
||||
* false - otherwise
|
||||
* @return raised error - if the operation fail
|
||||
* true/false API value - depend on whether the property exists
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_has_property (const jerry_value_t obj_val, /**< object value */
|
||||
@ -2001,17 +2052,15 @@ jerry_has_property (const jerry_value_t obj_val, /**< object value */
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
bool has_property = ecma_op_object_has_property (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val));
|
||||
|
||||
return ecma_make_boolean_value (has_property);
|
||||
return ecma_op_object_has_property (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val));
|
||||
} /* jerry_has_property */
|
||||
|
||||
/**
|
||||
* Checks whether the object has the given property.
|
||||
*
|
||||
* @return true - if the property exists
|
||||
* false - otherwise
|
||||
* @return ECMA_VALUE_ERROR - if the operation raises error
|
||||
* ECMA_VALUE_{TRUE, FALSE} - based on whether the property exists
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
@ -2025,10 +2074,26 @@ jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
bool has_property = ecma_op_object_has_own_property (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val));
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name_val);
|
||||
|
||||
return ecma_make_boolean_value (has_property);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
|
||||
|
||||
if (ecma_is_value_true (status))
|
||||
{
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
}
|
||||
|
||||
return jerry_return (status);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
|
||||
} /* jerry_has_own_property */
|
||||
|
||||
/**
|
||||
@ -2092,6 +2157,15 @@ jerry_delete_property (const jerry_value_t obj_val, /**< object value */
|
||||
ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val),
|
||||
false);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
// TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
|
||||
jcontext_release_exception ();
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_is_value_true (ret_value);
|
||||
} /* jerry_delete_property */
|
||||
|
||||
@ -2118,6 +2192,14 @@ jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value *
|
||||
false);
|
||||
ecma_deref_ecma_string (str_idx_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
// TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
|
||||
jcontext_release_exception ();
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_is_value_true (ret_value);
|
||||
} /* jerry_delete_property_by_index */
|
||||
|
||||
@ -2560,9 +2642,19 @@ jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object val
|
||||
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
if (!ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val),
|
||||
&prop_desc))
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val),
|
||||
&prop_desc);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
// TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
|
||||
jcontext_release_exception ();
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (!ecma_is_value_true (status))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -2803,6 +2895,13 @@ jerry_get_prototype (const jerry_value_t obj_val) /**< object value */
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return jerry_return (ecma_proxy_object_get_prototype_of (obj_p));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (obj_p->u2.prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return ECMA_VALUE_NULL;
|
||||
@ -2834,16 +2933,14 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
|
||||
}
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
if (ecma_is_value_null (proto_obj_val))
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
obj_p->u2.prototype_cp = JMEM_CP_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_SET_NON_NULL_POINTER (obj_p->u2.prototype_cp, ecma_get_object_from_value (proto_obj_val));
|
||||
return jerry_return (ecma_proxy_object_set_prototype_of (obj_p, proto_obj_val));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
return ecma_op_ordinary_object_set_prototype_of (obj_p, proto_obj_val);
|
||||
} /* jerry_set_prototype */
|
||||
|
||||
/**
|
||||
@ -3073,6 +3170,16 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
|
||||
ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (names_p == NULL)
|
||||
{
|
||||
// TODO: Due to Proxies the return value must be changed to jerry_value_t on next release
|
||||
jcontext_release_exception ();
|
||||
return false;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t *buffer_p = names_p->buffer_p;
|
||||
|
||||
ecma_value_t property_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
@ -103,6 +103,10 @@
|
||||
# define JERRY_ES2015_BUILTIN_PROMISE JERRY_ES2015
|
||||
#endif /* !defined (JERRY_ES2015_BUILTIN_PROMISE) */
|
||||
|
||||
#ifndef JERRY_ES2015_BUILTIN_PROXY
|
||||
# define JERRY_ES2015_BUILTIN_PROXY JERRY_ES2015
|
||||
#endif /* !defined (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
#ifndef JERRY_ES2015_BUILTIN_REFLECT
|
||||
# define JERRY_ES2015_BUILTIN_REFLECT JERRY_ES2015
|
||||
#endif /* !defined (JERRY_ES2015_BUILTIN_REFLECT) */
|
||||
@ -543,6 +547,10 @@
|
||||
|| ((JERRY_ES2015_BUILTIN_PROMISE != 0) && (JERRY_ES2015_BUILTIN_PROMISE != 1))
|
||||
# error "Invalid value for JERRY_ES2015_BUILTIN_PROMISE macro."
|
||||
#endif
|
||||
#if !defined (JERRY_ES2015_BUILTIN_PROXY) \
|
||||
|| ((JERRY_ES2015_BUILTIN_PROXY != 0) && (JERRY_ES2015_BUILTIN_PROXY != 1))
|
||||
# error "Invalid value for JERRY_ES2015_BUILTIN_PROXY macro."
|
||||
#endif
|
||||
#if !defined (JERRY_ES2015_BUILTIN_TYPEDARRAY) \
|
||||
|| ((JERRY_ES2015_BUILTIN_TYPEDARRAY != 0) && (JERRY_ES2015_BUILTIN_TYPEDARRAY != 1))
|
||||
# error "Invalid value for JERRY_ES2015_BUILTIN_TYPEDARRAY macro."
|
||||
|
||||
@ -24,7 +24,9 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-property-hashmap.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "jcontext.h"
|
||||
#include "jrt.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
@ -450,6 +452,29 @@ ecma_gc_mark_executable_object (ecma_object_t *object_p) /**< object */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
/**
|
||||
* Mark the objects referenced by a proxy object
|
||||
*/
|
||||
static void
|
||||
ecma_gc_mark_proxy_object (ecma_object_t *object_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (object_p));
|
||||
|
||||
ecma_proxy_object_t *proxy_p = (ecma_proxy_object_t *) object_p;
|
||||
|
||||
if (!ecma_is_value_null (proxy_p->target))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (proxy_p->target));
|
||||
}
|
||||
|
||||
if (!ecma_is_value_null (proxy_p->handler))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (proxy_p->handler));
|
||||
}
|
||||
} /* ecma_gc_mark_proxy_object */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/**
|
||||
* Mark objects as visited starting from specified object as root
|
||||
*/
|
||||
@ -609,6 +634,13 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
ecma_gc_mark_proxy_object (object_p);
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
ecma_gc_mark_bound_function_object (object_p);
|
||||
@ -643,6 +675,23 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
{
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_func_p->u.external_handler_cb == ecma_proxy_revoke_cb)
|
||||
{
|
||||
ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) object_p;
|
||||
|
||||
if (!ecma_is_value_null (rev_proxy_p->proxy))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (rev_proxy_p->proxy));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@ -975,6 +1024,14 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_func_p->u.external_handler_cb == ecma_proxy_revoke_cb)
|
||||
{
|
||||
ext_object_size = sizeof (ecma_revocable_proxy_object_t);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
@ -1138,6 +1195,13 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
|
||||
break;
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
ext_object_size = sizeof (ecma_proxy_object_t);
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
/* Function with byte-code (not a built-in function). */
|
||||
|
||||
@ -614,6 +614,7 @@ typedef enum
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS = 0, /**< no option flags for ecma_op_object_get_property */
|
||||
ECMA_PROPERTY_GET_VALUE = 1u << 0, /**< fill virtual_value field for virtual properties */
|
||||
ECMA_PROPERTY_GET_EXT_REFERENCE = 1u << 1, /**< get extended reference to the property */
|
||||
ECMA_PROPERTY_GET_HAS_OWN_PROP = 1u << 2, /**< internal [[HasOwnProperty]] method */
|
||||
} ecma_property_get_option_bits_t;
|
||||
|
||||
/**
|
||||
@ -625,8 +626,9 @@ typedef enum
|
||||
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
|
||||
ECMA_OBJECT_TYPE_ARRAY = 2, /**< Array object (15.4) */
|
||||
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 3, /**< Array-like object, such as Arguments object (10.6) */
|
||||
ECMA_OBJECT_TYPE_PROXY = 4, /**< Proxy object ECMAScript v6 26.2 */
|
||||
/* Note: these 4 types must be in this order. See IsCallable operation. */
|
||||
ECMA_OBJECT_TYPE_FUNCTION = 4, /**< Function objects (15.3), created through 13.2 routine */
|
||||
ECMA_OBJECT_TYPE_FUNCTION = 5, /**< Function objects (15.3), created through 13.2 routine */
|
||||
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 6, /**< Function objects (15.3), created through 15.3.4.5 routine */
|
||||
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 7, /**< External (host) function object */
|
||||
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
|
||||
@ -837,6 +839,7 @@ typedef struct
|
||||
{
|
||||
ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
|
||||
uint32_t length; /**< length related property (e.g. length of ArrayBuffer) */
|
||||
ecma_value_t target; /**< [[ProxyTarget]] internal property */
|
||||
} u;
|
||||
} class_prop;
|
||||
|
||||
@ -1835,6 +1838,32 @@ do \
|
||||
#define ECMA_CHECK_STACK_USAGE()
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
/**
|
||||
* Invalid object pointer which represents abrupt completion
|
||||
*/
|
||||
#define ECMA_OBJECT_POINTER_ERROR ((ecma_object_t *) 0x01)
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
/**
|
||||
* Description of Proxy objects.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_object_t header; /**< header part */
|
||||
ecma_value_t target; /**< [[ProxyTarget]] internal slot */
|
||||
ecma_value_t handler; /**< [[ProxyHandler]] internal slot */
|
||||
} ecma_proxy_object_t;
|
||||
|
||||
/**
|
||||
* Description of Proxy objects.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_extended_object_t header; /**< header part */
|
||||
ecma_value_t proxy; /**< [[RevocableProxy]] internal slot */
|
||||
} ecma_revocable_proxy_object_t;
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
@ -193,7 +194,8 @@ ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete
|
||||
if (native_pointer_p->next_p == NULL)
|
||||
{
|
||||
/* Only one native pointer property exists, so the property can be deleted as well. */
|
||||
ecma_op_object_delete (obj_p, name_p, false);
|
||||
ecma_op_general_object_delete (obj_p, name_p, false);
|
||||
|
||||
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -179,40 +179,17 @@ ecma_is_lexical_environment (const ecma_object_t *object_p) /**< object or lexic
|
||||
return full_type >= (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_TYPE_START);
|
||||
} /* ecma_is_lexical_environment */
|
||||
|
||||
/**
|
||||
* Get value of [[Extensible]] object's internal property.
|
||||
*
|
||||
* @return true - if object is extensible
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_PURE
|
||||
ecma_get_object_extensible (const ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (object_p));
|
||||
|
||||
return (object_p->type_flags_refs & ECMA_OBJECT_FLAG_EXTENSIBLE) != 0;
|
||||
} /* ecma_get_object_extensible */
|
||||
|
||||
/**
|
||||
* Set value of [[Extensible]] object's internal property.
|
||||
*/
|
||||
inline void
|
||||
ecma_set_object_extensible (ecma_object_t *object_p, /**< object */
|
||||
bool is_extensible) /**< value of [[Extensible]] */
|
||||
ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (object_p));
|
||||
|
||||
if (is_extensible)
|
||||
{
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_EXTENSIBLE);
|
||||
}
|
||||
} /* ecma_set_object_extensible */
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE);
|
||||
} /* ecma_op_ordinary_object_set_extensible */
|
||||
|
||||
/**
|
||||
* Get object's internal implementation-defined type.
|
||||
|
||||
@ -159,6 +159,17 @@ typedef enum
|
||||
#define ECMA_ASSERT_VALUE_IS_SYMBOL(value) (false)
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
* Check whether the given object has [[ProxyHandler]] and [[ProxyTarger]] internal slots
|
||||
*
|
||||
* @param obj_p ecma-object
|
||||
*/
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
#define ECMA_OBJECT_IS_PROXY(obj_p) (JERRY_UNLIKELY (ecma_get_object_type ((obj_p)) == ECMA_OBJECT_TYPE_PROXY))
|
||||
#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
#define ECMA_OBJECT_IS_PROXY(obj_p) (false)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* ecma-helpers-value.c */
|
||||
ecma_type_t JERRY_ATTR_CONST ecma_get_value_type_field (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_direct (ecma_value_t value);
|
||||
@ -367,8 +378,7 @@ ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environmen
|
||||
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p,
|
||||
ecma_lexical_environment_type_t type);
|
||||
bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p);
|
||||
bool JERRY_ATTR_PURE ecma_get_object_extensible (const ecma_object_t *object_p);
|
||||
void ecma_set_object_extensible (ecma_object_t *object_p, bool is_extensible);
|
||||
void ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p);
|
||||
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p);
|
||||
bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p);
|
||||
void ecma_set_object_is_builtin (ecma_object_t *object_p);
|
||||
|
||||
@ -688,7 +688,21 @@ ecma_module_connect_imports (void)
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
if (binding_p != NULL || ecma_op_has_binding (lex_env_p, import_names_p->local_name_p))
|
||||
if (binding_p != NULL)
|
||||
{
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
|
||||
}
|
||||
|
||||
ecma_value_t status = ecma_op_has_binding (lex_env_p, import_names_p->local_name_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_true (status))
|
||||
{
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
|
||||
}
|
||||
|
||||
@ -426,7 +426,7 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
|
||||
|
||||
if (ecma_op_object_is_fast_array (obj_p))
|
||||
{
|
||||
if (!ecma_get_object_extensible (obj_p))
|
||||
if (!ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
ecma_free_value (get_value);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
|
||||
@ -479,7 +479,7 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, /
|
||||
|
||||
if (ecma_op_object_is_fast_array (obj_p))
|
||||
{
|
||||
if (!ecma_get_object_extensible (obj_p))
|
||||
if (!ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
|
||||
}
|
||||
@ -554,7 +554,7 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_get_object_extensible (obj_p))
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
ecma_value_t *buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp);
|
||||
|
||||
@ -592,13 +592,30 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (upper_value))
|
||||
{
|
||||
upper_value = ECMA_VALUE_EMPTY;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* 6.f and 6.g */
|
||||
bool lower_exist = ecma_op_object_has_property (obj_p, lower_str_p);
|
||||
bool upper_exist = ecma_op_object_has_property (obj_p, upper_str_p);
|
||||
ecma_value_t has_lower = ecma_op_object_has_property (obj_p, lower_str_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (has_lower))
|
||||
{
|
||||
goto clean_up;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t has_upper = ecma_op_object_has_property (obj_p, upper_str_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (has_upper))
|
||||
{
|
||||
goto clean_up;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
bool lower_exist = ecma_is_value_true (has_lower);
|
||||
bool upper_exist = ecma_is_value_true (has_upper);
|
||||
|
||||
/* 6.h */
|
||||
if (lower_exist && upper_exist)
|
||||
@ -699,7 +716,7 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_get_object_extensible (obj_p))
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
ecma_value_t *buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp);
|
||||
ecma_value_t ret_value = buffer_p[0];
|
||||
@ -1069,6 +1086,13 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
|
||||
|
||||
ecma_collection_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (array_index_props_p == NULL)
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
uint32_t defined_prop_count = 0;
|
||||
|
||||
ecma_value_t *buffer_p = array_index_props_p->buffer_p;
|
||||
@ -1482,7 +1506,7 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg
|
||||
|
||||
if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE
|
||||
&& len != 0
|
||||
&& ecma_get_object_extensible (obj_p))
|
||||
&& ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
if ((ecma_number_t) (len + args_number) > UINT32_MAX)
|
||||
{
|
||||
@ -2236,12 +2260,8 @@ ecma_builtin_array_prototype_fill (ecma_value_t value, /**< value */
|
||||
/* 11. */
|
||||
while (k < final)
|
||||
{
|
||||
/* 11.a */
|
||||
ecma_string_t *pk = ecma_new_ecma_string_from_number (k);
|
||||
|
||||
/* 11.b */
|
||||
ecma_value_t put_val = ecma_op_object_put (obj_p, pk, value, true);
|
||||
ecma_deref_ecma_string (pk);
|
||||
/* 11.a - 11.b */
|
||||
ecma_value_t put_val = ecma_op_object_put_by_number_index (obj_p, k, value, true);
|
||||
|
||||
/* 11. c */
|
||||
if (ECMA_IS_VALUE_ERROR (put_val))
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jrt.h"
|
||||
#include "ecma-builtin-function-prototype.h"
|
||||
@ -210,11 +211,37 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
|
||||
/* 4. 11. 18. */
|
||||
ecma_object_t *prototype_obj_p;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
prototype_obj_p = ECMA_GET_POINTER (ecma_object_t, this_arg_obj_p->u2.prototype_cp);
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
#if !ENABLED (JERRY_ES2015)
|
||||
prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
#else /* ENABLED (JERRY_ES2015) */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (this_arg_obj_p))
|
||||
{
|
||||
ecma_value_t proto = ecma_proxy_object_get_prototype_of (this_arg_obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (proto))
|
||||
{
|
||||
return proto;
|
||||
}
|
||||
prototype_obj_p = ecma_is_value_null (proto) ? NULL : ecma_get_object_from_value (proto);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (this_arg_obj_p);
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
prototype_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
ecma_ref_object (prototype_obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
prototype_obj_p = NULL;
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
|
||||
ecma_object_t *function_p;
|
||||
ecma_extended_object_t *ext_function_p;
|
||||
@ -267,6 +294,13 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
|
||||
ext_function_p->u.bound_function.args_len_or_this = args_len_or_this;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (prototype_obj_p != NULL)
|
||||
{
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
|
||||
*
|
||||
|
||||
@ -246,6 +246,13 @@ OBJECT_VALUE (LIT_MAGIC_STRING_DATAVIEW_UL,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
/* ECMA-262 v6, 26.2.1 */
|
||||
OBJECT_VALUE (LIT_MAGIC_STRING_PROXY_UL,
|
||||
ECMA_BUILTIN_ID_PROXY,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* Routine properties:
|
||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
||||
|
||||
|
||||
@ -280,26 +280,23 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
|
||||
{
|
||||
JERRY_ASSERT (obj_p != NULL);
|
||||
|
||||
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (props_p == NULL)
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (props_p->item_count == 0)
|
||||
{
|
||||
ecma_collection_destroy (props_p);
|
||||
return new_array;
|
||||
return ecma_op_create_array_object (NULL, 0, false);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_op_object_is_fast_array (new_array_p));
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
ecma_value_t *values_p = ecma_fast_array_extend (new_array_p, props_p->item_count);
|
||||
|
||||
memcpy (values_p, buffer_p, props_p->item_count * sizeof (ecma_value_t));
|
||||
|
||||
ecma_collection_free_objects (props_p);
|
||||
ecma_value_t new_array = ecma_op_create_array_object (props_p->buffer_p, props_p->item_count, false);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return new_array;
|
||||
} /* ecma_builtin_helper_object_get_properties */
|
||||
|
||||
@ -904,6 +904,13 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
|
||||
else
|
||||
{
|
||||
property_keys_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (property_keys_p == NULL)
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
}
|
||||
|
||||
/* 8. */
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-string-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jrt.h"
|
||||
@ -143,7 +144,23 @@ static ecma_value_t
|
||||
ecma_builtin_object_prototype_object_has_own_property (ecma_object_t *obj_p, /**< this argument */
|
||||
ecma_string_t *prop_name_p) /**< first argument */
|
||||
{
|
||||
return ecma_make_boolean_value (ecma_op_object_has_own_property (obj_p, prop_name_p));
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
|
||||
|
||||
if (ecma_is_value_true (status))
|
||||
{
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
|
||||
} /* ecma_builtin_object_prototype_object_has_own_property */
|
||||
|
||||
/**
|
||||
@ -169,7 +186,7 @@ ecma_builtin_object_prototype_object_is_prototype_of (ecma_object_t *obj_p, /**<
|
||||
|
||||
ecma_object_t *v_obj_p = ecma_get_object_from_value (v_obj_value);
|
||||
|
||||
ecma_value_t ret_value = ecma_make_boolean_value (ecma_op_object_is_prototype_of (obj_p, v_obj_p));
|
||||
ecma_value_t ret_value = ecma_op_object_is_prototype_of (obj_p, v_obj_p);
|
||||
|
||||
ecma_deref_object (v_obj_p);
|
||||
|
||||
@ -189,19 +206,19 @@ static ecma_value_t
|
||||
ecma_builtin_object_prototype_object_property_is_enumerable (ecma_object_t *obj_p, /**< this argument */
|
||||
ecma_string_t *prop_name_p) /**< first argument */
|
||||
{
|
||||
/* 3. */
|
||||
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
|
||||
prop_name_p,
|
||||
NULL,
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS);
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
|
||||
|
||||
/* 4. */
|
||||
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
|
||||
if (!ecma_is_value_true (status))
|
||||
{
|
||||
return ecma_make_boolean_value (ecma_is_property_enumerable (property));
|
||||
return status;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_FALSE;
|
||||
bool is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
return ecma_make_boolean_value (is_enumerable);
|
||||
} /* ecma_builtin_object_prototype_object_property_is_enumerable */
|
||||
|
||||
/**
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "jrt.h"
|
||||
#include "ecma-builtin-object.h"
|
||||
@ -136,11 +137,18 @@ ecma_builtin_object_dispatch_construct (const ecma_value_t *arguments_list_p, /*
|
||||
ecma_value_t
|
||||
ecma_builtin_object_object_get_prototype_of (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
jmem_cpointer_t prototype_cp = obj_p->u2.prototype_cp;
|
||||
|
||||
if (prototype_cp != JMEM_CP_NULL)
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp);
|
||||
return ecma_proxy_object_get_prototype_of (obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (obj_p);
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
ecma_ref_object (prototype_p);
|
||||
return ecma_make_object_value (prototype_p);
|
||||
}
|
||||
@ -149,77 +157,6 @@ ecma_builtin_object_object_get_prototype_of (ecma_object_t *obj_p) /**< routine'
|
||||
} /* ecma_builtin_object_object_get_prototype_of */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/**
|
||||
* [[SetPrototypeOf]]
|
||||
*
|
||||
* See also:
|
||||
* ES2015 9.1.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_set_prototype_of (ecma_value_t o_value, /**< O */
|
||||
ecma_value_t v_value) /**< V */
|
||||
{
|
||||
/* 1. */
|
||||
JERRY_ASSERT (ecma_is_value_object (o_value));
|
||||
JERRY_ASSERT (ecma_is_value_object (v_value) || ecma_is_value_null (v_value));
|
||||
|
||||
ecma_object_t *o_p = ecma_get_object_from_value (o_value);
|
||||
|
||||
jmem_cpointer_t v_cp;
|
||||
|
||||
if (ecma_is_value_null (v_value))
|
||||
{
|
||||
v_cp = JMEM_CP_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_SET_NON_NULL_POINTER (v_cp, ecma_get_object_from_value (v_value));
|
||||
}
|
||||
|
||||
/* 3., 4. */
|
||||
if (v_cp == o_p->u2.prototype_cp)
|
||||
{
|
||||
ecma_ref_object (o_p);
|
||||
return ecma_make_object_value (o_p);
|
||||
}
|
||||
|
||||
/* 2., 5. */
|
||||
if (!ecma_get_object_extensible (o_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("cannot set prototype."));
|
||||
}
|
||||
|
||||
/* 6., 7., 8. */
|
||||
jmem_cpointer_t p_cp = v_cp;
|
||||
while (p_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *p_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, p_cp);
|
||||
|
||||
/* b. */
|
||||
if (p_p == o_p)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("cannot set prototype."));
|
||||
}
|
||||
|
||||
/* c.i. TODO: es2015-subset profile does not support having a different
|
||||
* [[GetPrototypeOf]] internal method */
|
||||
|
||||
/* c.ii. */
|
||||
p_cp = p_p->u2.prototype_cp;
|
||||
}
|
||||
|
||||
/* 9. */
|
||||
o_p->u2.prototype_cp = v_cp;
|
||||
|
||||
/* 10. */
|
||||
ecma_ref_object (o_p);
|
||||
return ecma_make_object_value (o_p);
|
||||
} /* ecma_set_prototype_of */
|
||||
|
||||
/**
|
||||
* The Object object's 'setPrototypeOf' routine
|
||||
*
|
||||
@ -251,11 +188,37 @@ ecma_builtin_object_object_set_prototype_of (ecma_value_t arg1, /**< routine's f
|
||||
return ecma_copy_value (arg1);
|
||||
}
|
||||
|
||||
/* 6. TODO: es2015-subset profile does not support having a different
|
||||
* [[SetPrototypeOf]] internal method */
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (arg1);
|
||||
ecma_value_t status;
|
||||
|
||||
/* 5-8. */
|
||||
return ecma_set_prototype_of (arg1, arg2);
|
||||
/* 5. */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
status = ecma_proxy_object_set_prototype_of (obj_p, arg2);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
status = ecma_op_ordinary_object_set_prototype_of (obj_p, arg2);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot set [[Prototype]]."));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (status));
|
||||
ecma_ref_object (obj_p);
|
||||
|
||||
return arg1;
|
||||
} /* ecma_builtin_object_object_set_prototype_of */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
@ -294,6 +257,150 @@ ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**<
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
* SetIntegrityLevel operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 7.3.14
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation raised an error
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the integrity level has been set sucessfully
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_set_integrity_level (ecma_object_t *obj_p, /**< object */
|
||||
bool is_seal) /**< true - set "sealed"
|
||||
* false - set "frozen" */
|
||||
{
|
||||
/* 3. */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_value_t status = ecma_proxy_object_prevent_extensions (obj_p);
|
||||
|
||||
if (!ecma_is_value_true (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
ecma_op_ordinary_object_prevent_extensions (obj_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* 6. */
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (props_p == NULL)
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
if (is_seal)
|
||||
{
|
||||
/* 8.a */
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 8.a.i */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
/* 8.a.ii */
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 9.a */
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 9.1 */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 9.2 */
|
||||
if ((prop_desc.flags & (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
== (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_WRITABLE;
|
||||
}
|
||||
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 9.3 */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
/* 9.4 */
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_builtin_object_set_integrity_level */
|
||||
|
||||
/**
|
||||
* The Object object's 'seal' routine
|
||||
*
|
||||
@ -306,46 +413,19 @@ ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**<
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
ecma_value_t status = ecma_builtin_object_set_integrity_level (obj_p, true);
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 2.b */
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 2.c */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
return status;
|
||||
}
|
||||
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Object cannot be sealed."));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* 4. */
|
||||
ecma_ref_object (obj_p);
|
||||
@ -364,53 +444,19 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument *
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
ecma_value_t status = ecma_builtin_object_set_integrity_level (obj_p, false);
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
if (!ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 2.b */
|
||||
if ((prop_desc.flags & (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
== (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_WRITABLE;
|
||||
}
|
||||
|
||||
/* 2.c */
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 2.d */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
return status;
|
||||
}
|
||||
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Object cannot be frozen."));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* 4. */
|
||||
ecma_ref_object (obj_p);
|
||||
@ -429,7 +475,30 @@ ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument
|
||||
ecma_value_t
|
||||
ecma_builtin_object_object_prevent_extensions (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_value_t status = ecma_proxy_object_prevent_extensions (obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot set [[Extensible]] property of the object."));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (status));
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
ecma_op_ordinary_object_prevent_extensions (obj_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
ecma_ref_object (obj_p);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
@ -446,13 +515,34 @@ ecma_builtin_object_object_prevent_extensions (ecma_object_t *obj_p) /**< routin
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine's argument */
|
||||
int mode) /**< routine mode */
|
||||
ecma_builtin_object_test_integrity_level (ecma_object_t *obj_p, /**< routine's argument */
|
||||
int mode) /**< routine mode */
|
||||
{
|
||||
JERRY_ASSERT (mode == ECMA_OBJECT_ROUTINE_IS_FROZEN || mode == ECMA_OBJECT_ROUTINE_IS_SEALED);
|
||||
|
||||
/* 3. */
|
||||
if (ecma_get_object_extensible (obj_p))
|
||||
bool is_extensible;
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
ecma_value_t status = ecma_proxy_object_is_extensible (obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
is_extensible = ecma_is_value_true (status);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
is_extensible = ecma_op_ordinary_object_is_extensible (obj_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (is_extensible)
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
@ -463,6 +553,13 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
/* 2. */
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (props_p == NULL)
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
@ -470,22 +567,32 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
|
||||
property_name_p,
|
||||
NULL,
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS);
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, property_name_p, &prop_desc);
|
||||
|
||||
/* 2.b for isFrozen */
|
||||
if (mode == ECMA_OBJECT_ROUTINE_IS_FROZEN
|
||||
&& ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|
||||
&& ecma_is_property_writable (property))
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
ret_value = ECMA_VALUE_FALSE;
|
||||
ret_value = status;
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_writable_data = ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
== (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE));
|
||||
bool is_configurable = (prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
/* 2.b for isFrozen */
|
||||
/* 2.b for isSealed, 2.c for isFrozen */
|
||||
if (ecma_is_property_configurable (property))
|
||||
if ((mode == ECMA_OBJECT_ROUTINE_IS_FROZEN && is_writable_data)
|
||||
|| is_configurable)
|
||||
{
|
||||
ret_value = ECMA_VALUE_FALSE;
|
||||
break;
|
||||
@ -495,7 +602,7 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_object_frozen_or_sealed_helper */
|
||||
} /* ecma_builtin_object_test_integrity_level */
|
||||
|
||||
/**
|
||||
* The Object object's 'isExtensible' routine
|
||||
@ -509,7 +616,14 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
ecma_value_t
|
||||
ecma_builtin_object_object_is_extensible (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
return ecma_make_boolean_value (ecma_get_object_extensible (obj_p));
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_proxy_object_is_extensible (obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_make_boolean_value (ecma_op_ordinary_object_is_extensible (obj_p));
|
||||
} /* ecma_builtin_object_object_is_extensible */
|
||||
|
||||
/**
|
||||
@ -543,7 +657,16 @@ ecma_builtin_object_object_get_own_property_descriptor (ecma_object_t *obj_p, /*
|
||||
/* 3. */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
if (ecma_op_object_get_own_property_descriptor (obj_p, name_str_p, &prop_desc))
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, name_str_p, &prop_desc);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_true (status))
|
||||
{
|
||||
/* 4. */
|
||||
ecma_object_t *desc_obj_p = ecma_op_from_property_descriptor (&prop_desc);
|
||||
@ -583,6 +706,14 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
ecma_value_t ret_value = ECMA_VALUE_ERROR;
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (prop_names_p == NULL)
|
||||
{
|
||||
ecma_deref_object (props_p);
|
||||
return ret_value;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t *buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
/* 4. */
|
||||
@ -783,6 +914,13 @@ ecma_builtin_object_object_assign (ecma_object_t *target_p, /**< target object *
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE
|
||||
| ECMA_LIST_SYMBOLS);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (props_p == NULL)
|
||||
{
|
||||
ecma_deref_object (from_obj_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
@ -792,8 +930,17 @@ ecma_builtin_object_object_assign (ecma_object_t *target_p, /**< target object *
|
||||
|
||||
/* 5.c.i-ii */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
ecma_value_t desc_status = ecma_op_object_get_own_property_descriptor (from_obj_p, property_name_p, &prop_desc);
|
||||
|
||||
if (!ecma_op_object_get_own_property_descriptor (from_obj_p, property_name_p, &prop_desc))
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (desc_status))
|
||||
{
|
||||
ret_value = desc_status;
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (desc_status))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1056,8 +1203,7 @@ ecma_builtin_object_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
|
||||
case ECMA_OBJECT_ROUTINE_IS_SEALED:
|
||||
case ECMA_OBJECT_ROUTINE_IS_FROZEN:
|
||||
{
|
||||
return ecma_builtin_object_frozen_or_sealed_helper (obj_p,
|
||||
builtin_routine_id);
|
||||
return ecma_builtin_object_test_integrity_level (obj_p, builtin_routine_id);
|
||||
}
|
||||
case ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE:
|
||||
{
|
||||
|
||||
120
jerry-core/ecma/builtin-objects/ecma-builtin-proxy.c
Normal file
120
jerry-core/ecma/builtin-objects/ecma-builtin-proxy.c
Normal file
@ -0,0 +1,120 @@
|
||||
/* 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 "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "jrt.h"
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
|
||||
#define ECMA_BUILTINS_INTERNAL
|
||||
#include "ecma-builtins-internal.h"
|
||||
|
||||
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-proxy.inc.h"
|
||||
#define BUILTIN_UNDERSCORED_ID proxy
|
||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmabuiltins
|
||||
* @{
|
||||
*
|
||||
* \addtogroup proxy ECMA Proxy object built-in
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Proxy object's 'revocable' routine
|
||||
*
|
||||
* See also:
|
||||
* ES2015 26.2.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_proxy_object_revocable (ecma_value_t this_arg, /**< 'this' argument */
|
||||
ecma_value_t target, /**< target argument */
|
||||
ecma_value_t handler) /**< handler argument */
|
||||
{
|
||||
JERRY_UNUSED (this_arg);
|
||||
|
||||
ecma_object_t *rev_proxy_p = ecma_proxy_create_revocable (target, handler);
|
||||
|
||||
if (JERRY_UNLIKELY (rev_proxy_p == NULL))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
return ecma_make_object_value (rev_proxy_p);
|
||||
} /* ecma_builtin_proxy_object_revocable */
|
||||
|
||||
/**
|
||||
* Handle calling [[Call]] of built-in Proxy object
|
||||
*
|
||||
* See also:
|
||||
* ES2015 26.2.2
|
||||
*
|
||||
* @return raised error
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_proxy_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
/* 1. */
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Constructor Proxy requires 'new'"));
|
||||
} /* ecma_builtin_proxy_dispatch_call */
|
||||
|
||||
/**
|
||||
* Handle calling [[Construct]] of built-in proxy object
|
||||
*
|
||||
* See also:
|
||||
* ES2015 26.2.2
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* new proxy object - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_proxy_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
/* 2. */
|
||||
ecma_object_t *proxy_p = ecma_proxy_create (arguments_list_len > 0 ? arguments_list_p[0] : ECMA_VALUE_UNDEFINED,
|
||||
arguments_list_len > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED);
|
||||
|
||||
if (JERRY_UNLIKELY (proxy_p == NULL))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
return ecma_make_object_value (proxy_p);
|
||||
} /* ecma_builtin_proxy_dispatch_construct */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
38
jerry-core/ecma/builtin-objects/ecma-builtin-proxy.inc.h
Normal file
38
jerry-core/ecma/builtin-objects/ecma-builtin-proxy.inc.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Proxy object built-in description
|
||||
*/
|
||||
|
||||
#include "ecma-builtin-helpers-macro-defines.inc.h"
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
|
||||
/* Number properties:
|
||||
* (property name, number value, writable, enumerable, configurable) */
|
||||
|
||||
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
|
||||
2,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* Routine properties:
|
||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
||||
|
||||
ROUTINE (LIT_MAGIC_STRING_REVOCABLE, ecma_builtin_proxy_object_revocable, 2, 2)
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
||||
@ -124,7 +124,7 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i
|
||||
|
||||
case ECMA_REFLECT_OBJECT_HAS:
|
||||
{
|
||||
ret_value = ecma_make_boolean_value (ecma_op_object_has_property (target_p, name_str_p));
|
||||
ret_value = ecma_op_object_has_property (target_p, name_str_p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -384,7 +384,14 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ext_object_size, obj_type);
|
||||
|
||||
ecma_set_object_extensible (obj_p, (obj_builtin_id != ECMA_BUILTIN_ID_TYPE_ERROR_THROWER));
|
||||
if (JERRY_UNLIKELY (obj_builtin_id == ECMA_BUILTIN_ID_TYPE_ERROR_THROWER))
|
||||
{
|
||||
ecma_op_ordinary_object_prevent_extensions (obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_op_ordinary_object_set_extensible (obj_p);
|
||||
}
|
||||
|
||||
/*
|
||||
* [[Class]] property of built-in object is not stored explicitly.
|
||||
@ -986,7 +993,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
|
||||
uint32_t bit_for_index = (uint32_t) 1u << index;
|
||||
|
||||
if (!(*bitset_p & bit_for_index) || ecma_op_object_has_own_property (object_p, name_p))
|
||||
if (!(*bitset_p & bit_for_index) || ecma_op_ordinary_object_has_own_property (object_p, name_p))
|
||||
{
|
||||
ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id);
|
||||
|
||||
|
||||
@ -507,6 +507,15 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_WEAKSET,
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
/* The Proxy routine (ECMA-262 v6, 26.2.1) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_PROXY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
|
||||
true,
|
||||
proxy)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/* Intrinsic hidden builtin object */
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-objects-arguments.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
@ -75,6 +76,13 @@ ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_op_is_callable (((ecma_proxy_object_t *) obj_p)->target);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
return ecma_get_object_type (obj_p) >= ECMA_OBJECT_TYPE_FUNCTION;
|
||||
} /* ecma_op_object_is_callable */
|
||||
|
||||
@ -104,6 +112,13 @@ ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_is_constructor (((ecma_proxy_object_t *) obj_p)->target);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||
|
||||
if (type == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
@ -523,7 +538,27 @@ ecma_op_implicit_class_constructor_has_instance (ecma_object_t *func_obj_p, /**<
|
||||
|
||||
while (true)
|
||||
{
|
||||
jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp;
|
||||
jmem_cpointer_t v_obj_cp;
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (v_obj_p))
|
||||
{
|
||||
ecma_value_t parent = ecma_proxy_object_get_prototype_of (v_obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (parent))
|
||||
{
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
return parent;
|
||||
}
|
||||
|
||||
v_obj_cp = ecma_proxy_object_prototype_to_cp (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
v_obj_cp = ecma_op_ordinary_object_get_prototype_of (v_obj_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (v_obj_cp == JMEM_CP_NULL)
|
||||
{
|
||||
@ -611,14 +646,40 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
|
||||
ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
|
||||
JERRY_ASSERT (prototype_obj_p != NULL);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
ecma_value_t result = ECMA_VALUE_ERROR;
|
||||
#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
ecma_value_t result = ECMA_VALUE_FALSE;
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
while (true)
|
||||
{
|
||||
jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp;
|
||||
jmem_cpointer_t v_obj_cp;
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (v_obj_p))
|
||||
{
|
||||
ecma_value_t parent = ecma_proxy_object_get_prototype_of (v_obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (parent))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v_obj_cp = ecma_proxy_object_prototype_to_cp (parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
v_obj_cp = ecma_op_ordinary_object_get_prototype_of (v_obj_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (v_obj_cp == JMEM_CP_NULL)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
result = ECMA_VALUE_FALSE;
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1119,7 +1180,17 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
{
|
||||
JERRY_ASSERT (func_obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (func_obj_p));
|
||||
JERRY_ASSERT (ecma_op_is_callable (ecma_make_object_value (func_obj_p)));
|
||||
JERRY_ASSERT (ecma_op_object_is_callable (func_obj_p));
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (func_obj_p))
|
||||
{
|
||||
return ecma_proxy_object_call (func_obj_p,
|
||||
this_arg_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|
||||
@ -1275,6 +1346,16 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
JERRY_ASSERT (ecma_is_value_object (this_arg_value)
|
||||
|| this_arg_value == ECMA_VALUE_UNDEFINED);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (func_obj_p))
|
||||
{
|
||||
return ecma_proxy_object_construct (func_obj_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len,
|
||||
ecma_make_object_value (func_obj_p));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_object_t *target_func_obj_p = NULL;
|
||||
|
||||
while (JERRY_UNLIKELY (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
|
||||
|
||||
@ -90,6 +90,11 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
|
||||
ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ecma_is_value_found (result))
|
||||
{
|
||||
*ref_base_lex_env_p = lex_env_p;
|
||||
@ -272,7 +277,16 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
if (ecma_op_object_has_property (binding_obj_p, name_p))
|
||||
ecma_value_t has_property = ecma_op_object_has_property (binding_obj_p, name_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (has_property))
|
||||
{
|
||||
return has_property;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_true (has_property))
|
||||
{
|
||||
ecma_value_t completion = ecma_op_object_put (binding_obj_p,
|
||||
name_p,
|
||||
|
||||
@ -124,7 +124,7 @@ ecma_get_global_scope (void)
|
||||
*
|
||||
* @return true / false
|
||||
*/
|
||||
bool
|
||||
ecma_value_t
|
||||
ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *name_p) /**< argument N */
|
||||
{
|
||||
@ -137,16 +137,14 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
{
|
||||
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
|
||||
|
||||
return (property_p != NULL);
|
||||
return ecma_make_boolean_value (property_p != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
|
||||
return ecma_op_object_has_property (binding_obj_p, name_p);
|
||||
}
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
return ecma_op_object_has_property (binding_obj_p, name_p);
|
||||
} /* ecma_op_has_binding */
|
||||
|
||||
/**
|
||||
@ -186,7 +184,7 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
if (!ecma_get_object_extensible (binding_obj_p))
|
||||
if (!ecma_op_ordinary_object_is_extensible (binding_obj_p))
|
||||
{
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
@ -299,6 +297,11 @@ ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
|
||||
ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!ecma_is_value_found (result))
|
||||
{
|
||||
if (is_strict)
|
||||
@ -321,8 +324,8 @@ ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
* See also: ECMA-262 v5, 10.2.1
|
||||
*
|
||||
* @return ecma value
|
||||
* Return value is simple and so need not be freed.
|
||||
* However, ecma_free_value may be called for it, but it is a no-op.
|
||||
* Return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the binding can be deleted
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
|
||||
@ -55,7 +55,7 @@ ecma_value_t ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, ecma_stri
|
||||
bool is_strict, ecma_value_t value);
|
||||
|
||||
/* ECMA-262 v5, Table 17. Abstract methods of Environment Records */
|
||||
bool ecma_op_has_binding (ecma_object_t *lex_env_p, ecma_string_t *name_p);
|
||||
ecma_value_t ecma_op_has_binding (ecma_object_t *lex_env_p, ecma_string_t *name_p);
|
||||
ecma_value_t ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, ecma_string_t *name_p, bool is_deletable);
|
||||
ecma_value_t ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, ecma_string_t *name_p, ecma_value_t value,
|
||||
bool is_strict);
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
@ -362,6 +363,13 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< property
|
||||
* descriptor */
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_define_own_property (object_p, property_name_p, property_desc_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p));
|
||||
@ -403,7 +411,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
if (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND || current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
|
||||
{
|
||||
/* 3. */
|
||||
if (!ecma_get_object_extensible (object_p))
|
||||
if (!ecma_op_ordinary_object_is_extensible (object_p))
|
||||
{
|
||||
/* 2. */
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "ecma-objects-arguments.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
@ -75,8 +76,13 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
JERRY_ASSERT (options == ECMA_PROPERTY_GET_NO_OPTIONS || property_ref_p != NULL);
|
||||
JERRY_ASSERT (options == ECMA_PROPERTY_GET_NO_OPTIONS
|
||||
|| options == ECMA_PROPERTY_GET_HAS_OWN_PROP
|
||||
|| property_ref_p != NULL);
|
||||
|
||||
ecma_object_type_t type = ecma_get_object_type (object_p);
|
||||
|
||||
@ -287,7 +293,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
||||
}
|
||||
}
|
||||
else if (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY
|
||||
&& property_ref_p != NULL)
|
||||
&& (options & ECMA_PROPERTY_GET_HAS_OWN_PROP))
|
||||
{
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
@ -378,39 +384,43 @@ ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */
|
||||
} /* ecma_op_object_get_property */
|
||||
|
||||
/**
|
||||
* Checks whether an object (excluding prototypes) has a named property
|
||||
* Generic [[HasProperty]] operation
|
||||
*
|
||||
* @return true - if property is found
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
ecma_property_ref_t property_ref;
|
||||
ecma_property_t property = ecma_op_object_get_own_property (object_p,
|
||||
property_name_p,
|
||||
&property_ref,
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS);
|
||||
|
||||
return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
|
||||
} /* ecma_op_object_has_own_property */
|
||||
|
||||
/**
|
||||
* Checks whether an object (including prototypes) has a named property
|
||||
* See also:
|
||||
* ECMAScript v6, 9.1.7.1
|
||||
*
|
||||
* @return true - if property is found
|
||||
* false - otherwise
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE_FALSE} - whether the property is found
|
||||
*/
|
||||
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
ecma_property_t property = ecma_op_object_get_property (object_p,
|
||||
property_name_p,
|
||||
NULL,
|
||||
ECMA_PROPERTY_GET_NO_OPTIONS);
|
||||
return property != ECMA_PROPERTY_TYPE_NOT_FOUND;
|
||||
while (true)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_has (object_p, property_name_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* 2 - 3. */
|
||||
if (ecma_op_ordinary_object_has_own_property (object_p, property_name_p))
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p);
|
||||
|
||||
/* 7. */
|
||||
if (proto_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
}
|
||||
} /* ecma_op_object_has_property */
|
||||
|
||||
/**
|
||||
@ -430,6 +440,7 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
|
||||
ecma_object_type_t type = ecma_get_object_type (object_p);
|
||||
|
||||
@ -705,6 +716,13 @@ ecma_op_object_find (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
while (true)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_find (object_p, property_name_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p);
|
||||
|
||||
if (ecma_is_value_found (value))
|
||||
@ -770,30 +788,11 @@ ecma_op_object_get_own_data_prop (ecma_object_t *object_p, /**< the object */
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_object_get (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
ecma_value_t base_value = ecma_make_object_value (object_p);
|
||||
|
||||
while (true)
|
||||
{
|
||||
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p);
|
||||
|
||||
if (ecma_is_value_found (value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (object_p->u2.prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp);
|
||||
}
|
||||
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
return ecma_op_object_get_with_receiver (object_p, property_name_p, ecma_make_object_value (object_p));
|
||||
} /* ecma_op_object_get */
|
||||
|
||||
/**
|
||||
@ -817,6 +816,13 @@ ecma_op_object_get_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_get (object_p, property_name_p, receiver);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t value = ecma_op_object_find_own (receiver, object_p, property_name_p);
|
||||
|
||||
if (ecma_is_value_found (value))
|
||||
@ -824,12 +830,14 @@ ecma_op_object_get_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
return value;
|
||||
}
|
||||
|
||||
if (object_p->u2.prototype_cp == JMEM_CP_NULL)
|
||||
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p);
|
||||
|
||||
if (proto_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp);
|
||||
object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
}
|
||||
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
@ -1149,6 +1157,13 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_set (object_p, property_name_p, value, receiver);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_object_type_t type = ecma_get_object_type (object_p);
|
||||
|
||||
switch (type)
|
||||
@ -1169,7 +1184,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p)))
|
||||
{
|
||||
if (JERRY_UNLIKELY (!ecma_get_object_extensible (object_p)))
|
||||
if (JERRY_UNLIKELY (!ecma_op_ordinary_object_is_extensible (object_p)))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
@ -1354,10 +1369,12 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
bool create_new_property = true;
|
||||
|
||||
if (object_p->u2.prototype_cp != JMEM_CP_NULL)
|
||||
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p);
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_ref_t property_ref = { NULL };
|
||||
ecma_object_t *proto_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp);
|
||||
ecma_object_t *proto_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
|
||||
ecma_property_t inherited_property = ecma_op_object_get_property (proto_p,
|
||||
property_name_p,
|
||||
@ -1379,7 +1396,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
}
|
||||
|
||||
if (create_new_property
|
||||
&& ecma_get_object_extensible (object_p))
|
||||
&& ecma_op_ordinary_object_is_extensible (object_p))
|
||||
{
|
||||
const ecma_object_type_t obj_type = ecma_get_object_type (object_p);
|
||||
|
||||
@ -1526,6 +1543,13 @@ ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_proxy_object_delete_property (obj_p, property_name_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p));
|
||||
|
||||
return ecma_op_general_object_delete (obj_p,
|
||||
@ -1591,6 +1615,13 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
|
||||
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
@ -1691,11 +1722,18 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
* @return true - if property found
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_value_t
|
||||
ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (object_p))
|
||||
{
|
||||
return ecma_proxy_object_get_own_property_descriptor (object_p, property_name_p, prop_desc_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_property_ref_t property_ref;
|
||||
|
||||
ecma_property_t property = ecma_op_object_get_own_property (object_p,
|
||||
@ -1705,7 +1743,7 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob
|
||||
|
||||
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
|
||||
{
|
||||
return false;
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
*prop_desc_p = ecma_make_empty_property_descriptor ();
|
||||
@ -1760,7 +1798,7 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_op_object_get_own_property_descriptor */
|
||||
|
||||
/**
|
||||
@ -1795,27 +1833,46 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.2.4.6; 3
|
||||
*
|
||||
* @return true - if the target object is prototype of the base object
|
||||
* false - if the target object is not prototype of the base object
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_TRUE - if the target object is prototype of the base object
|
||||
* ECMA_VALUE_FALSE - if the target object is not prototype of the base object
|
||||
*/
|
||||
bool
|
||||
ecma_value_t
|
||||
ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */
|
||||
ecma_object_t *target_p) /**< target object */
|
||||
{
|
||||
do
|
||||
{
|
||||
jmem_cpointer_t target_cp = target_p->u2.prototype_cp;
|
||||
jmem_cpointer_t target_cp;
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (target_p))
|
||||
{
|
||||
ecma_value_t target_proto = ecma_proxy_object_get_prototype_of (target_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (target_proto))
|
||||
{
|
||||
return target_proto;
|
||||
}
|
||||
target_cp = ecma_proxy_object_prototype_to_cp (target_proto);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
target_cp = ecma_op_ordinary_object_get_prototype_of (target_p);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (target_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return false;
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
target_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, target_cp);
|
||||
|
||||
if (target_p == base_p)
|
||||
{
|
||||
return true;
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
} while (true);
|
||||
} /* ecma_op_object_is_prototype_of */
|
||||
@ -1832,7 +1889,8 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */
|
||||
* property list, and the list is not reordered (in other words, properties are stored in order that is reversed
|
||||
* to the properties' addition order).
|
||||
*
|
||||
* @return collection of strings - property names
|
||||
* @return NULL - if the Proxy.[[OwnPropertyKeys]] operation raises error
|
||||
* collection of property names - otherwise
|
||||
*/
|
||||
ecma_collection_t *
|
||||
ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
@ -1841,6 +1899,13 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
||||
JERRY_ASSERT (obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (obj_p));
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_proxy_object_own_property_keys (obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_op_object_is_fast_array (obj_p))
|
||||
{
|
||||
return ecma_fast_array_get_property_names (obj_p, opts);
|
||||
@ -2480,7 +2545,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL);
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL || type == ECMA_OBJECT_TYPE_PROXY);
|
||||
|
||||
if (ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
@ -2524,6 +2589,12 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
return LIT_MAGIC_STRING_ERROR_UL;
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
case ECMA_BUILTIN_ID_PROXY:
|
||||
{
|
||||
return LIT_MAGIC_STRING_FUNCTION_UL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ecma_object_check_class_name_is_object (obj_p));
|
||||
@ -2766,6 +2837,142 @@ ecma_op_invoke (ecma_value_t object, /**< Object value */
|
||||
return call_result;
|
||||
} /* ecma_op_invoke */
|
||||
|
||||
/**
|
||||
* Ordinary object [[GetPrototypeOf]] operation
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.1.1
|
||||
*
|
||||
* @return the value of the [[Prototype]] internal slot of the given object.
|
||||
*/
|
||||
inline jmem_cpointer_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_ordinary_object_get_prototype_of (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
|
||||
return obj_p->u2.prototype_cp;
|
||||
} /* ecma_op_ordinary_object_get_prototype_of */
|
||||
|
||||
/**
|
||||
* Ordinary object [[SetPrototypeOf]] operation
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.1.2
|
||||
*
|
||||
* @return ECMA_VALUE_FALSE - if the operation fails
|
||||
* ECMA_VALUE_TRUE - otherwise
|
||||
*/
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_ordinary_object_set_prototype_of (ecma_object_t *obj_p, /**< base object */
|
||||
ecma_value_t proto) /**< prototype object */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
|
||||
/* 1. */
|
||||
JERRY_ASSERT (ecma_is_value_object (proto) || ecma_is_value_null (proto));
|
||||
|
||||
/* 3. */
|
||||
ecma_object_t *current_proto_p = ECMA_GET_POINTER (ecma_object_t, ecma_op_ordinary_object_get_prototype_of (obj_p));
|
||||
ecma_object_t *new_proto_p = ecma_is_value_null (proto) ? NULL : ecma_get_object_from_value (proto);
|
||||
|
||||
/* 4. */
|
||||
if (new_proto_p == current_proto_p)
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
/* 2 - 5. */
|
||||
if (!ecma_op_ordinary_object_is_extensible (obj_p))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
ecma_object_t *iter_p = new_proto_p;
|
||||
|
||||
/* 7 - 8. */
|
||||
while (true)
|
||||
{
|
||||
/* 8.a */
|
||||
if (iter_p == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* 8.b */
|
||||
if (obj_p == iter_p)
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
/* 8.c.i */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (iter_p))
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/* 8.c.ii */
|
||||
iter_p = ECMA_GET_POINTER (ecma_object_t, ecma_op_ordinary_object_get_prototype_of (iter_p));
|
||||
}
|
||||
|
||||
/* 9. */
|
||||
ECMA_SET_POINTER (obj_p->u2.prototype_cp, new_proto_p);
|
||||
|
||||
/* 10. */
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_op_ordinary_object_set_prototype_of */
|
||||
|
||||
/**
|
||||
* [[IsExtensible]] operation for Ordinary object.
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.1.2
|
||||
*
|
||||
* @return true - if object is extensible
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_PURE
|
||||
ecma_op_ordinary_object_is_extensible (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
|
||||
return (object_p->type_flags_refs & ECMA_OBJECT_FLAG_EXTENSIBLE) != 0;
|
||||
} /* ecma_op_ordinary_object_is_extensible */
|
||||
|
||||
/**
|
||||
* Set value of [[Extensible]] object's internal property.
|
||||
*/
|
||||
void JERRY_ATTR_NOINLINE
|
||||
ecma_op_ordinary_object_prevent_extensions (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_EXTENSIBLE);
|
||||
} /* ecma_op_ordinary_object_prevent_extensions */
|
||||
|
||||
/**
|
||||
* Checks whether an object (excluding prototypes) has a named property
|
||||
*
|
||||
* @return true - if property is found
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p) /**< property name */
|
||||
{
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
|
||||
ecma_property_t property = ecma_op_object_get_own_property (object_p,
|
||||
property_name_p,
|
||||
NULL,
|
||||
ECMA_PROPERTY_GET_HAS_OWN_PROP);
|
||||
|
||||
return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
|
||||
} /* ecma_op_ordinary_object_has_own_property */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
|
||||
ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_ref_t *property_ref_p, uint32_t options);
|
||||
bool ecma_op_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
bool ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
bool ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, uint32_t index);
|
||||
@ -52,6 +52,8 @@ ecma_value_t ecma_op_object_put_with_receiver (ecma_object_t *object_p, ecma_str
|
||||
ecma_value_t value, ecma_value_t receiver, bool is_throw);
|
||||
ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value,
|
||||
bool is_throw);
|
||||
ecma_value_t ecma_op_object_put_with_receiver (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_value_t value, ecma_value_t receiver, bool is_throw);
|
||||
ecma_value_t ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, uint32_t index,
|
||||
ecma_value_t value, bool is_throw);
|
||||
ecma_value_t ecma_op_object_put_by_number_index (ecma_object_t *object_p, ecma_number_t index,
|
||||
@ -62,10 +64,10 @@ ecma_value_t ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, ecma_n
|
||||
ecma_value_t ecma_op_object_default_value (ecma_object_t *obj_p, ecma_preferred_type_hint_t hint);
|
||||
ecma_value_t ecma_op_object_define_own_property (ecma_object_t *obj_p, ecma_string_t *property_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
bool ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_descriptor_t *prop_desc_p);
|
||||
ecma_value_t ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_descriptor_t *prop_desc_p);
|
||||
ecma_value_t ecma_op_object_has_instance (ecma_object_t *obj_p, ecma_value_t value);
|
||||
bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
|
||||
ecma_value_t ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
|
||||
ecma_collection_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
|
||||
|
||||
lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
|
||||
@ -81,6 +83,11 @@ ecma_value_t ecma_op_invoke (ecma_value_t object, ecma_string_t *property_name_p
|
||||
ecma_value_t ecma_op_invoke_by_magic_id (ecma_value_t object, lit_magic_string_id_t magic_string_id,
|
||||
ecma_value_t *args_p, ecma_length_t args_len);
|
||||
|
||||
jmem_cpointer_t ecma_op_ordinary_object_get_prototype_of (ecma_object_t *obj_p);
|
||||
ecma_value_t ecma_op_ordinary_object_set_prototype_of (ecma_object_t *base_p, ecma_value_t proto);
|
||||
bool JERRY_ATTR_PURE ecma_op_ordinary_object_is_extensible (ecma_object_t *object_p);
|
||||
void ecma_op_ordinary_object_prevent_extensions (ecma_object_t *object_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
552
jerry-core/ecma/operations/ecma-proxy-object.c
Normal file
552
jerry-core/ecma/operations/ecma-proxy-object.c
Normal file
@ -0,0 +1,552 @@
|
||||
/* 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 "ecma-alloc.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-proxy-object.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaproxyobject ECMA Proxy object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
/**
|
||||
* Check whether the argument satifies the requrements of [[ProxyTarget]] or [[ProxyHandler]]
|
||||
*
|
||||
* See also:
|
||||
* ES2015 9.5.15.1-2
|
||||
* ES2015 9.5.15.3-4
|
||||
*
|
||||
* @return true - if the arguments can be a valid [[ProxyTarget]] or [[ProxyHandler]]
|
||||
* false - otherwise
|
||||
*/
|
||||
static bool
|
||||
ecma_proxy_validate (ecma_value_t argument) /**< argument to validate */
|
||||
{
|
||||
if (ecma_is_value_object (argument))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (argument);
|
||||
|
||||
return (!ECMA_OBJECT_IS_PROXY (obj_p)
|
||||
|| !ecma_is_value_null (((ecma_proxy_object_t *) obj_p)->handler));
|
||||
}
|
||||
|
||||
return false;
|
||||
} /* ecma_proxy_validate */
|
||||
|
||||
/**
|
||||
* ProxyCreate operation for create a new proxy object
|
||||
*
|
||||
* See also:
|
||||
* ES2015 9.5.15
|
||||
*
|
||||
* @return created Proxy object as an ecma-value - if success
|
||||
* raised error - otherwise
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_proxy_create (ecma_value_t target, /**< proxy target */
|
||||
ecma_value_t handler) /**< proxy handler */
|
||||
{
|
||||
/* 1 - 4. */
|
||||
if (!ecma_proxy_validate (target) || !ecma_proxy_validate (handler))
|
||||
{
|
||||
ecma_raise_type_error (ECMA_ERR_MSG ("Cannot create proxy with a non-object target or handler"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 5 - 6. */
|
||||
ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
|
||||
sizeof (ecma_proxy_object_t),
|
||||
ECMA_OBJECT_TYPE_PROXY);
|
||||
|
||||
ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
|
||||
|
||||
/* 8. */
|
||||
proxy_obj_p->target = target;
|
||||
/* 9. */
|
||||
proxy_obj_p->handler = handler;
|
||||
|
||||
/* 10. */
|
||||
return obj_p;
|
||||
} /* ecma_proxy_create */
|
||||
|
||||
/**
|
||||
* Definition of Proxy Revocation Function
|
||||
*
|
||||
* See also:
|
||||
* ES2015 26.2.2.1.1
|
||||
*
|
||||
* @return ECMA_VALUE_UNDEFINED
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_revoke_cb (const ecma_value_t function_obj, /**< the function itself */
|
||||
const ecma_value_t this_val, /**< this_arg of the function */
|
||||
const ecma_value_t args_p[], /**< argument list */
|
||||
const ecma_length_t args_count) /**< argument number */
|
||||
{
|
||||
JERRY_UNUSED_3 (this_val, args_p, args_count);
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (function_obj);
|
||||
|
||||
/* 1. */
|
||||
ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
|
||||
|
||||
/* 2. */
|
||||
if (ecma_is_value_null (rev_proxy_p->proxy))
|
||||
{
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
ecma_proxy_object_t *proxy_p = (ecma_proxy_object_t *) ecma_get_object_from_value (rev_proxy_p->proxy);
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY ((ecma_object_t *) proxy_p));
|
||||
|
||||
/* 3. */
|
||||
rev_proxy_p->proxy = ECMA_VALUE_NULL;
|
||||
|
||||
/* 5. */
|
||||
proxy_p->target = ECMA_VALUE_NULL;
|
||||
|
||||
/* 6. */
|
||||
proxy_p->handler = ECMA_VALUE_NULL;
|
||||
|
||||
/* 7. */
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
} /* ecma_proxy_revoke_cb */
|
||||
|
||||
/**
|
||||
* Proxy.revocable operation for create a new revocable proxy object
|
||||
*
|
||||
* See also:
|
||||
* ES2015 26.2.2.1
|
||||
*
|
||||
* @return NULL - if the operation fails
|
||||
* pointer to the newly created revocable proxy object - otherwise
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_proxy_create_revocable (ecma_value_t target, /**< target argument */
|
||||
ecma_value_t handler) /**< handler argument */
|
||||
{
|
||||
/* 1. */
|
||||
ecma_object_t *proxy_p = ecma_proxy_create (target, handler);
|
||||
|
||||
/* 2. */
|
||||
if (proxy_p == NULL)
|
||||
{
|
||||
return proxy_p;
|
||||
}
|
||||
|
||||
ecma_value_t proxy_value = ecma_make_object_value (proxy_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_object_t *func_obj_p;
|
||||
func_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
|
||||
sizeof (ecma_revocable_proxy_object_t),
|
||||
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
|
||||
ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
|
||||
rev_proxy_p->header.u.external_handler_cb = ecma_proxy_revoke_cb;
|
||||
/* 4. */
|
||||
rev_proxy_p->proxy = proxy_value;
|
||||
|
||||
ecma_property_value_t *prop_value_p;
|
||||
ecma_value_t revoker = ecma_make_object_value (func_obj_p);
|
||||
|
||||
/* 5. */
|
||||
ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
|
||||
0,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
/* 6. */
|
||||
prop_value_p = ecma_create_named_data_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_PROXY),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
prop_value_p->value = proxy_value;
|
||||
|
||||
/* 7. */
|
||||
prop_value_p = ecma_create_named_data_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_REVOKE),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
prop_value_p->value = revoker;
|
||||
|
||||
ecma_deref_object (proxy_p);
|
||||
ecma_deref_object (func_obj_p);
|
||||
|
||||
/* 8. */
|
||||
return obj_p;
|
||||
} /* ecma_proxy_create_revocable */
|
||||
|
||||
/**
|
||||
* Internal find property operation for Proxy object
|
||||
*
|
||||
* Note: Returned value must be freed with ecma_free_value.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_NOT_FOUND - if the property is not found
|
||||
* value of the property - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_find (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p) /**< property name */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
|
||||
ecma_value_t has_result = ecma_proxy_object_has (obj_p, prop_name_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (has_result))
|
||||
{
|
||||
return has_result;
|
||||
}
|
||||
|
||||
if (ecma_is_value_false (has_result))
|
||||
{
|
||||
return ECMA_VALUE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ecma_proxy_object_get (obj_p, prop_name_p, ecma_make_object_value (obj_p));
|
||||
} /* ecma_proxy_object_find */
|
||||
|
||||
/**
|
||||
* Convert the result of the ecma_proxy_object_get_prototype_of to compressed pointer
|
||||
*
|
||||
* Note: if `proto` is non-null, the reference from the object is released
|
||||
*
|
||||
* @return compressed pointer to the `proto` value
|
||||
*/
|
||||
jmem_cpointer_t
|
||||
ecma_proxy_object_prototype_to_cp (ecma_value_t proto) /**< ECMA_VALUE_NULL or object */
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_null (proto) || ecma_is_value_object (proto));
|
||||
|
||||
if (ecma_is_value_null (proto))
|
||||
{
|
||||
return JMEM_CP_NULL;
|
||||
}
|
||||
|
||||
jmem_cpointer_t proto_cp;
|
||||
ecma_object_t *proto_obj_p = ecma_get_object_from_value (proto);
|
||||
ECMA_SET_POINTER (proto_cp, proto_obj_p);
|
||||
ecma_deref_object (proto_obj_p);
|
||||
|
||||
return proto_cp;
|
||||
} /* ecma_proxy_object_prototype_to_cp */
|
||||
|
||||
/* Interal operations */
|
||||
|
||||
/**
|
||||
* The Proxy object [[GetPrototypeOf]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.1
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_NULL or valid object (prototype) otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get_prototype_of (ecma_object_t *obj_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED (obj_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[GetPrototypeOf]]"));
|
||||
} /* ecma_proxy_object_get_prototype_of */
|
||||
|
||||
/**
|
||||
* The Proxy object [[SetPrototypeOf]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.2
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the new prototype can be set for the given object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_set_prototype_of (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_value_t proto) /**< new prototype object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_ASSERT (ecma_is_value_object (proto) || ecma_is_value_null (proto));
|
||||
JERRY_UNUSED_2 (obj_p, proto);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[SetPrototypeOf]]"));
|
||||
} /* ecma_proxy_object_set_prototype_of */
|
||||
|
||||
/**
|
||||
* The Proxy object [[isExtensible]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.3
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the object is extensible
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_is_extensible (ecma_object_t *obj_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED (obj_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[IsExtensible]]"));
|
||||
} /* ecma_proxy_object_is_extensible */
|
||||
|
||||
/**
|
||||
* The Proxy object [[PreventExtensions]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.4
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the object can be set as inextensible
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_prevent_extensions (ecma_object_t *obj_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED (obj_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[PreventExtensions]]"));
|
||||
} /* ecma_proxy_object_prevent_extensions */
|
||||
|
||||
/**
|
||||
* The Proxy object [[GetOwnProperty]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.5
|
||||
*
|
||||
* Note: - Returned value is always a simple value so freeing it is unnecessary.
|
||||
* - If the operation does not fail, freeing the filled property descriptor is the caller's responsibility
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE_FALSE} - depends on whether object has property with the given name
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get_own_property_descriptor (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
ecma_property_descriptor_t *prop_desc_p) /**< [out] property
|
||||
* descriptor */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_3 (obj_p, prop_name_p, prop_desc_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[GetOwnProperty]]"));
|
||||
} /* ecma_proxy_object_get_own_property_descriptor */
|
||||
|
||||
/**
|
||||
* The Proxy object [[DefineOwnProperty]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.6
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE_FALSE} - depends on whether the property can be defined for the given object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_define_own_property (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_3 (obj_p, prop_name_p, prop_desc_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[DefineOwnProperty]]"));
|
||||
} /* ecma_proxy_object_define_own_property */
|
||||
|
||||
/**
|
||||
* The Proxy object [[HasProperty]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.7
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE_FALSE} - depends on whether the property is found
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_has (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p) /**< property name */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_2 (obj_p, prop_name_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[HasProperty]]"));
|
||||
} /* ecma_proxy_object_has */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Get]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.8
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* value of the given nameddata property or the result of the getter function call - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
ecma_value_t receiver) /**< receiver to invoke getter function */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_3 (obj_p, prop_name_p, receiver);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Get]]"));
|
||||
} /* ecma_proxy_object_get */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Set]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.9
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the propety can be set to the given object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_set (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
ecma_value_t value, /**< value to set */
|
||||
ecma_value_t receiver) /**< receiver to invoke setter function */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_4 (obj_p, prop_name_p, value, receiver);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Set]]"));
|
||||
} /* ecma_proxy_object_set */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Delete]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.10
|
||||
*
|
||||
* Note: Returned value is always a simple value so freeing it is unnecessary.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_{TRUE/FALSE} - depends on whether the propety can be deleted
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_delete_property (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_string_t *prop_name_p) /**< property name */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_2 (obj_p, prop_name_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Delete]]"));
|
||||
} /* ecma_proxy_object_delete_property */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Enumerate]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.11
|
||||
*
|
||||
* Note: Returned value must be freed with ecma_free_value.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ecma-object - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_enumerate (ecma_object_t *obj_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED (obj_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Enumerate]]"));
|
||||
} /* ecma_proxy_object_enumerate */
|
||||
|
||||
/**
|
||||
* The Proxy object [[OwnPropertyKeys]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.12
|
||||
*
|
||||
* Note: If the returned collection is not NULL, it must be freed with
|
||||
* ecma_collection_free if it is no longer needed
|
||||
*
|
||||
* @return NULL - if the operation fails
|
||||
* pointer to a newly allocated list of property names - otherwise
|
||||
*/
|
||||
ecma_collection_t *
|
||||
ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED (obj_p);
|
||||
ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[OwnPropertyKeys]]"));
|
||||
return NULL;
|
||||
} /* ecma_proxy_object_own_property_keys */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Call]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.13
|
||||
*
|
||||
* Note: Returned value must be freed with ecma_free_value.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* result of the function call - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_call (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_value_t this_argument, /**< this argument to invoke the function */
|
||||
const ecma_value_t *args_p, /**< argument list */
|
||||
ecma_length_t argc) /**< number of arguments */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_4 (obj_p, this_argument, args_p, argc);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Call]]"));
|
||||
} /* ecma_proxy_object_call */
|
||||
|
||||
/**
|
||||
* The Proxy object [[Construct]] internal routine
|
||||
*
|
||||
* See also:
|
||||
* ECMAScript v6, 9.5.14
|
||||
*
|
||||
* Note: Returned value must be freed with ecma_free_value.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* result of the construct call - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_proxy_object_construct (ecma_object_t *obj_p, /**< proxy object */
|
||||
const ecma_value_t *args_p, /**< argument list */
|
||||
ecma_length_t argc, /**< number of arguments */
|
||||
ecma_value_t new_target) /**< this argument to invoke the function */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
JERRY_UNUSED_4 (obj_p, args_p, argc, new_target);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Construct]]"));
|
||||
} /* ecma_proxy_object_construct */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
120
jerry-core/ecma/operations/ecma-proxy-object.h
Normal file
120
jerry-core/ecma/operations/ecma-proxy-object.h
Normal file
@ -0,0 +1,120 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef ECMA_PROXY_OBJECT_H
|
||||
#define ECMA_PROXY_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaproxyobject ECMA Proxy object related routines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
|
||||
ecma_object_t *
|
||||
ecma_proxy_create (ecma_value_t target,
|
||||
ecma_value_t handler);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_proxy_create_revocable (ecma_value_t target,
|
||||
ecma_value_t handler);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_revoke_cb (const ecma_value_t function_obj,
|
||||
const ecma_value_t this_val,
|
||||
const ecma_value_t args_p[],
|
||||
const ecma_length_t args_count);
|
||||
|
||||
jmem_cpointer_t
|
||||
ecma_proxy_object_prototype_to_cp (ecma_value_t proto);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_find (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p);
|
||||
|
||||
/* Interal operations */
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get_prototype_of (ecma_object_t *obj_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_set_prototype_of (ecma_object_t *obj_p,
|
||||
ecma_value_t proto);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_is_extensible (ecma_object_t *obj_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_prevent_extensions (ecma_object_t *obj_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get_own_property_descriptor (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p,
|
||||
ecma_property_descriptor_t *prop_desc_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_define_own_property (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p,
|
||||
const ecma_property_descriptor_t *prop_desc_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_has (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_get (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p,
|
||||
ecma_value_t receiver);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_set (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p,
|
||||
ecma_value_t name,
|
||||
ecma_value_t receiver);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_delete_property (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_enumerate (ecma_object_t *obj_p);
|
||||
|
||||
ecma_collection_t *
|
||||
ecma_proxy_object_own_property_keys (ecma_object_t *obj_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_call (ecma_object_t *obj_p,
|
||||
ecma_value_t this_argument,
|
||||
const ecma_value_t *args_p,
|
||||
ecma_length_t argc);
|
||||
|
||||
ecma_value_t
|
||||
ecma_proxy_object_construct (ecma_object_t *obj_p,
|
||||
const ecma_value_t *args_p,
|
||||
ecma_length_t argc,
|
||||
ecma_value_t new_target);
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* !ECMA_PROXY_OBJECT_H */
|
||||
@ -34,9 +34,9 @@
|
||||
/**
|
||||
* Resolve syntactic reference.
|
||||
*
|
||||
* @return if reference was resolved successfully,
|
||||
* pointer to lexical environment - reference's base,
|
||||
* else - NULL.
|
||||
* @return ECMA_OBJECT_POINTER_ERROR - if the operation fails
|
||||
* pointer to lexical environment - if the reference's base is resolved sucessfully,
|
||||
* NULL - otherwise.
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical environment */
|
||||
@ -54,7 +54,16 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (ecma_op_has_binding (lex_env_p, name_p))
|
||||
ecma_value_t has_binding = ecma_op_has_binding (lex_env_p, name_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (has_binding))
|
||||
{
|
||||
return ECMA_OBJECT_POINTER_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_true (has_binding))
|
||||
{
|
||||
return lex_env_p;
|
||||
}
|
||||
@ -221,6 +230,11 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
|
||||
ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (prop_value))
|
||||
{
|
||||
return prop_value;
|
||||
}
|
||||
|
||||
if (ecma_is_value_found (prop_value))
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
@ -99,6 +99,7 @@ typedef enum
|
||||
JERRY_FEATURE_LOGGING, /**< logging */
|
||||
JERRY_FEATURE_SYMBOL, /**< symbol support */
|
||||
JERRY_FEATURE_DATAVIEW, /**< DataView support */
|
||||
JERRY_FEATURE_PROXY, /**< Proxy support */
|
||||
JERRY_FEATURE__COUNT /**< number of features. NOTE: must be at the end of the list */
|
||||
} jerry_feature_t;
|
||||
|
||||
@ -379,6 +380,7 @@ bool jerry_value_is_number (const jerry_value_t value);
|
||||
bool jerry_value_is_null (const jerry_value_t value);
|
||||
bool jerry_value_is_object (const jerry_value_t value);
|
||||
bool jerry_value_is_promise (const jerry_value_t value);
|
||||
bool jerry_value_is_proxy (const jerry_value_t value);
|
||||
bool jerry_value_is_string (const jerry_value_t value);
|
||||
bool jerry_value_is_symbol (const jerry_value_t value);
|
||||
bool jerry_value_is_undefined (const jerry_value_t value);
|
||||
@ -493,6 +495,7 @@ jerry_value_t jerry_create_number_nan (void);
|
||||
jerry_value_t jerry_create_null (void);
|
||||
jerry_value_t jerry_create_object (void);
|
||||
jerry_value_t jerry_create_promise (void);
|
||||
jerry_value_t jerry_create_proxy (const jerry_value_t target, const jerry_value_t handler);
|
||||
jerry_value_t jerry_create_regexp (const jerry_char_t *pattern, uint16_t flags);
|
||||
jerry_value_t jerry_create_regexp_sz (const jerry_char_t *pattern, jerry_size_t pattern_size, uint16_t flags);
|
||||
jerry_value_t jerry_create_string_from_utf8 (const jerry_char_t *str_p);
|
||||
|
||||
@ -195,6 +195,11 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARRAY_UL, "Array")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ERROR_UL, "Error")
|
||||
#if ENABLED (JERRY_BUILTIN_MATH)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LOG2E_U, "LOG2E")
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PROXY_UL, "Proxy")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_MATH)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SQRT2_U, "SQRT2")
|
||||
#endif
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_APPLY, "apply")
|
||||
@ -232,6 +237,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MATCH, "match")
|
||||
|| ENABLED (JERRY_BUILTIN_JSON)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PARSE, "parse")
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PROXY, "proxy")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_MATH)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ROUND, "round")
|
||||
#endif
|
||||
@ -327,6 +335,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REPEAT, "repeat")
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RETURN, "return")
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REVOKE, "revoke")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_BUILTIN_STRING) \
|
||||
|| ENABLED (JERRY_ES2015)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SEARCH, "search")
|
||||
@ -560,6 +571,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LASTINDEX_UL, "lastIndex")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MULTILINE, "multiline")
|
||||
#endif
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PROTOTYPE, "prototype")
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REVOCABLE, "revocable")
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UINT16_UL, "setUint16")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UINT32_UL, "setUint32")
|
||||
|
||||
@ -93,6 +93,7 @@ LIT_MAGIC_STRING_TRIM = "trim"
|
||||
LIT_MAGIC_STRING_TRUE = "true"
|
||||
LIT_MAGIC_STRING_ARRAY_UL = "Array"
|
||||
LIT_MAGIC_STRING_ERROR_UL = "Error"
|
||||
LIT_MAGIC_STRING_PROXY_UL = "Proxy"
|
||||
LIT_MAGIC_STRING_LOG2E_U = "LOG2E"
|
||||
LIT_MAGIC_STRING_SQRT2_U = "SQRT2"
|
||||
LIT_MAGIC_STRING_APPLY = "apply"
|
||||
@ -108,6 +109,7 @@ LIT_MAGIC_STRING_INPUT = "input"
|
||||
LIT_MAGIC_STRING_IS_NAN = "isNaN"
|
||||
LIT_MAGIC_STRING_MATCH = "match"
|
||||
LIT_MAGIC_STRING_PARSE = "parse"
|
||||
LIT_MAGIC_STRING_PROXY = "proxy"
|
||||
LIT_MAGIC_STRING_ROUND = "round"
|
||||
LIT_MAGIC_STRING_SHIFT = "shift"
|
||||
LIT_MAGIC_STRING_SLICE = "slice"
|
||||
@ -144,6 +146,7 @@ LIT_MAGIC_STRING_RANDOM = "random"
|
||||
LIT_MAGIC_STRING_REDUCE = "reduce"
|
||||
LIT_MAGIC_STRING_REJECT = "reject"
|
||||
LIT_MAGIC_STRING_REPEAT = "repeat"
|
||||
LIT_MAGIC_STRING_REVOKE = "revoke"
|
||||
LIT_MAGIC_STRING_RETURN = "return"
|
||||
LIT_MAGIC_STRING_SEARCH = "search"
|
||||
LIT_MAGIC_STRING_SOURCE = "source"
|
||||
@ -233,6 +236,7 @@ LIT_MAGIC_STRING_GET_UINT32_UL = "getUint32"
|
||||
LIT_MAGIC_STRING_LASTINDEX_UL = "lastIndex"
|
||||
LIT_MAGIC_STRING_MULTILINE = "multiline"
|
||||
LIT_MAGIC_STRING_PROTOTYPE = "prototype"
|
||||
LIT_MAGIC_STRING_REVOCABLE = "revocable"
|
||||
LIT_MAGIC_STRING_STRINGIFY = "stringify"
|
||||
LIT_MAGIC_STRING_SET_UINT16_UL = "setUint16"
|
||||
LIT_MAGIC_STRING_SET_UINT32_UL = "setUint32"
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
|
||||
/* \addtogroup parser Parser
|
||||
* @{
|
||||
@ -126,7 +127,7 @@ parser_tagged_template_literal_freeze_array (ecma_object_t *obj_p)
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
ecma_op_ordinary_object_prevent_extensions (obj_p);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
uint8_t new_prop_value = (uint8_t) (ext_obj_p->u.array.u.length_prop & ~ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
ext_obj_p->u.array.u.length_prop = new_prop_value;
|
||||
|
||||
@ -167,8 +167,7 @@ opfunc_in (ecma_value_t left_value, /**< left value */
|
||||
}
|
||||
|
||||
ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value);
|
||||
ecma_value_t result = ecma_make_boolean_value (ecma_op_object_has_property (right_value_obj_p,
|
||||
property_name_p));
|
||||
ecma_value_t result = ecma_op_object_has_property (right_value_obj_p, property_name_p);
|
||||
ecma_deref_ecma_string (property_name_p);
|
||||
return result;
|
||||
} /* opfunc_in */
|
||||
|
||||
@ -44,13 +44,25 @@
|
||||
* 'Variable declaration' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.5 - Declaration binding instantiation (block 8).
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if no the operation fails
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
vm_var_decl (ecma_object_t *lex_env_p, /**< target lexical environment */
|
||||
ecma_string_t *var_name_str_p, /**< variable name */
|
||||
bool is_configurable_bindings) /**< true if the binding can be deleted */
|
||||
{
|
||||
if (!ecma_op_has_binding (lex_env_p, var_name_str_p))
|
||||
ecma_value_t has_binding = ecma_op_has_binding (lex_env_p, var_name_str_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (has_binding))
|
||||
{
|
||||
return has_binding;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_false (has_binding))
|
||||
{
|
||||
ecma_value_t completion_value = ecma_op_create_mutable_binding (lex_env_p,
|
||||
var_name_str_p,
|
||||
@ -65,12 +77,17 @@ vm_var_decl (ecma_object_t *lex_env_p, /**< target lexical environment */
|
||||
var_name_str_p,
|
||||
vm_is_strict_mode ())));
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* vm_var_decl */
|
||||
|
||||
/**
|
||||
* Set var binding to a function literal value.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if no the operation fails
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
vm_set_var (ecma_object_t *lex_env_p, /**< target lexical environment */
|
||||
ecma_string_t *var_name_str_p, /**< variable name */
|
||||
bool is_strict, /**< true, if the engine is in strict mode */
|
||||
@ -83,12 +100,9 @@ vm_set_var (ecma_object_t *lex_env_p, /**< target lexical environment */
|
||||
|| ecma_is_value_empty (put_value_result)
|
||||
|| ECMA_IS_VALUE_ERROR (put_value_result));
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (put_value_result))
|
||||
{
|
||||
jcontext_release_exception ();
|
||||
}
|
||||
|
||||
ecma_free_value (lit_value);
|
||||
|
||||
return put_value_result;
|
||||
} /* vm_set_var */
|
||||
|
||||
/**
|
||||
@ -206,7 +220,7 @@ vm_op_delete_prop (ecma_value_t object, /**< base object */
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||
|
||||
ecma_value_t delete_op_ret = ecma_op_object_delete (obj_p, name_string_p, is_strict);
|
||||
JERRY_ASSERT (ecma_is_value_boolean (delete_op_ret) || (is_strict == true && ECMA_IS_VALUE_ERROR (delete_op_ret)));
|
||||
JERRY_ASSERT (ecma_is_value_boolean (delete_op_ret) || ECMA_IS_VALUE_ERROR (delete_op_ret));
|
||||
ecma_deref_object (obj_p);
|
||||
ecma_deref_ecma_string (name_string_p);
|
||||
|
||||
@ -229,6 +243,13 @@ vm_op_delete_var (ecma_value_t name_literal, /**< name literal */
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (lex_env_p, var_name_str_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (JERRY_UNLIKELY (ref_base_lex_env_p == ECMA_OBJECT_POINTER_ERROR))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ref_base_lex_env_p == NULL)
|
||||
{
|
||||
completion_value = ECMA_VALUE_TRUE;
|
||||
@ -267,6 +288,9 @@ opfunc_for_in (ecma_value_t left_value, /**< left value */
|
||||
/* ecma_op_to_object will only raise error on null/undefined values but those are handled above. */
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_expr_value));
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
|
||||
if (prop_names_p->item_count != 0)
|
||||
|
||||
@ -56,10 +56,10 @@ typedef enum
|
||||
*/
|
||||
#define OPFUNC_HAS_SPREAD_ELEMENT (1 << 8)
|
||||
|
||||
void
|
||||
ecma_value_t
|
||||
vm_var_decl (ecma_object_t *lex_env_p, ecma_string_t *var_name_str_p, bool is_configurable_bindings);
|
||||
|
||||
void
|
||||
ecma_value_t
|
||||
vm_set_var (ecma_object_t *lex_env_p, ecma_string_t *var_name_str_p, bool is_strict, ecma_value_t lit_value);
|
||||
|
||||
ecma_value_t
|
||||
|
||||
@ -185,7 +185,7 @@ vm_op_set_value (ecma_value_t object, /**< base object */
|
||||
}
|
||||
|
||||
object_p = ecma_get_object_from_value (to_object);
|
||||
ecma_set_object_extensible (object_p, false);
|
||||
ecma_op_ordinary_object_prevent_extensions (object_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1321,11 +1321,21 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) && !JERRY_NDEBUG */
|
||||
|
||||
vm_var_decl (lex_env_p, name_p, frame_ctx_p->is_eval_code);
|
||||
result = vm_var_decl (lex_env_p, name_p, frame_ctx_p->is_eval_code);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (lit_value != ECMA_VALUE_UNDEFINED)
|
||||
{
|
||||
vm_set_var (lex_env_p, name_p, is_strict, lit_value);
|
||||
result = vm_set_var (lex_env_p, name_p, is_strict, lit_value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
@ -1423,7 +1433,22 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
if (binding_p != NULL || ecma_op_has_binding (lex_env_p, literal_name_p))
|
||||
if (binding_p != NULL)
|
||||
{
|
||||
result = ecma_raise_syntax_error (ECMA_ERR_MSG ("Local variable is redeclared."));
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = ecma_op_has_binding (lex_env_p, literal_name_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
if (ecma_is_value_true (result))
|
||||
{
|
||||
result = ecma_raise_syntax_error (ECMA_ERR_MSG ("Local variable is redeclared."));
|
||||
goto error;
|
||||
@ -1486,7 +1511,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) && !JERRY_NDEBUG */
|
||||
|
||||
vm_set_var (lex_env_p, name_p, is_strict, left_value);
|
||||
result = vm_set_var (lex_env_p, name_p, is_strict, left_value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
case VM_OC_CLONE_CONTEXT:
|
||||
@ -3421,6 +3452,20 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
JERRY_ASSERT (VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ecma_is_value_object (value)
|
||||
&& ECMA_OBJECT_IS_PROXY (ecma_get_object_from_value (value)))
|
||||
{
|
||||
/* Note: - For proxy objects we should create a new object which implements the iterable protocol,
|
||||
and iterates through the enumerated collection below.
|
||||
- This inkoves that the VM context type should be adjusted and checked in all FOR-IN related
|
||||
instruction.
|
||||
- For other objects we should keep the current implementation due to performance reasons.*/
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy support in for-in."));
|
||||
goto error;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t expr_obj_value = ECMA_VALUE_UNDEFINED;
|
||||
ecma_collection_t *prop_names_p = opfunc_for_in (value, &expr_obj_value);
|
||||
ecma_free_value (value);
|
||||
@ -3478,12 +3523,17 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[-4]);
|
||||
uint32_t index = stack_top_p[-3];
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
while (index < collection_p->item_count)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[index]);
|
||||
|
||||
if (JERRY_LIKELY (ecma_op_object_has_property (object_p, prop_name_p)))
|
||||
result = ecma_op_object_has_property (object_p, prop_name_p);
|
||||
|
||||
if (JERRY_LIKELY (ecma_is_value_true (result)))
|
||||
{
|
||||
byte_code_p = byte_code_start_p + branch_offset;
|
||||
break;
|
||||
@ -4088,7 +4138,8 @@ error:
|
||||
/**
|
||||
* Initialize code block execution
|
||||
*
|
||||
* @return ecma value
|
||||
* @return ECMA_VALUE_ERROR - if the initialization fails
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static void JERRY_ATTR_NOINLINE
|
||||
vm_init_exec (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
40
tests/jerry/es2015/proxy_call.js
Normal file
40
tests/jerry/es2015/proxy_call.js
Normal file
@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = function () {};
|
||||
var handler = { apply (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// opfunc_call
|
||||
proxy(5)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
var revocable = Proxy.revokable(function() {}, {});
|
||||
proxy = new Proxy(revocable.proxy, {})
|
||||
revocable.revoke();
|
||||
proxy(5)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
38
tests/jerry/es2015/proxy_construct.js
Normal file
38
tests/jerry/es2015/proxy_construct.js
Normal file
@ -0,0 +1,38 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = function () {};
|
||||
var handler = { construct (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// opfunc_call
|
||||
new proxy(5)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 22.1.2.3.4.a
|
||||
Array.of.call(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
65
tests/jerry/es2015/proxy_create.js
Normal file
65
tests/jerry/es2015/proxy_create.js
Normal file
@ -0,0 +1,65 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {}
|
||||
var handler = {};
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
var revocable = Proxy.revocable(target, handler);
|
||||
revocable.revoke();
|
||||
var rev_proxy = revocable.proxy;
|
||||
|
||||
try {
|
||||
Proxy(target, handler);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
proxy.a;
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy(undefined, undefined);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy(rev_proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy({}, rev_proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
new Proxy(rev_proxy, {});
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
32
tests/jerry/es2015/proxy_define_own_property.js
Normal file
32
tests/jerry/es2015/proxy_define_own_property.js
Normal file
@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = function () {};
|
||||
var handler = { defineProperty (target) {
|
||||
throw 42;
|
||||
}, construct () {
|
||||
return {};
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 22.1.2.3.8.c
|
||||
Array.of.call(proxy, 5)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
46
tests/jerry/es2015/proxy_delete.js
Normal file
46
tests/jerry/es2015/proxy_delete.js
Normal file
@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { deleteProperty (target) {
|
||||
throw 42;
|
||||
}, get (object, propName) {
|
||||
if (propName == "length") {
|
||||
return 5;
|
||||
}
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
var a = 5;
|
||||
|
||||
try {
|
||||
// ecma_op_delete_binding
|
||||
with (proxy) {
|
||||
delete a
|
||||
}
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 22.1.3.16.6.e
|
||||
Array.prototype.pop.call(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
46
tests/jerry/es2015/proxy_get.js
Normal file
46
tests/jerry/es2015/proxy_get.js
Normal file
@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { get (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// vm_op_get_value
|
||||
proxy.a
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// ecma_op_get_value_object_base
|
||||
proxy[2];
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// @@toPrimitive symbol
|
||||
proxy + "foo";
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
80
tests/jerry/es2015/proxy_get_own_property_descriptor.js
Normal file
80
tests/jerry/es2015/proxy_get_own_property_descriptor.js
Normal file
@ -0,0 +1,80 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { getOwnPropertyDescriptor (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 19.1.3.2.5
|
||||
Object.prototype.hasOwnProperty.call(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.3.4
|
||||
Object.prototype.propertyIsEnumerable.call(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.1.5.b.iii
|
||||
Object.assign({}, proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.6.5
|
||||
Object.getOwnPropertyDescriptor(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
/* TODO: enable these test when Proxy.[[isExtensible]] has been implemted
|
||||
try {
|
||||
// 19.1.2.5.2.9.a.i
|
||||
Object.freeze(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.12.2.7
|
||||
Object.isFrozen(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.13.2.7
|
||||
Object.isSealed(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
*/
|
||||
70
tests/jerry/es2015/proxy_get_prototoype_of.js
Normal file
70
tests/jerry/es2015/proxy_get_prototoype_of.js
Normal file
@ -0,0 +1,70 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { getPrototypeOf (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 19.1.2.9.2
|
||||
Object.getPrototypeOf(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.3.3
|
||||
Object.prototype.isPrototypeOf(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
(function () {
|
||||
class e extends Array {};
|
||||
function f () {};
|
||||
function g () {};
|
||||
|
||||
Object.setPrototypeOf(g, proxy);
|
||||
|
||||
// 7.3.19.7.b
|
||||
try {
|
||||
g instanceof f;
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
// ecma_op_implicit_class_constructor_has_instance [[GetPrototypeOf]]
|
||||
try {
|
||||
g instanceof e;
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
})();
|
||||
|
||||
try {
|
||||
// 9.4.1.3.3
|
||||
Function.prototype.bind.call(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
52
tests/jerry/es2015/proxy_has.js
Normal file
52
tests/jerry/es2015/proxy_has.js
Normal file
@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { has (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 12.9.3
|
||||
"foo" in proxy;
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 8.1.1.2.1
|
||||
with (proxy) {
|
||||
p;
|
||||
assert(false);
|
||||
}
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// ecma_op_put_value_lex_env_base/[[HasProperty]]
|
||||
with (proxy) {
|
||||
function a (){}
|
||||
assert(false);
|
||||
}
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
46
tests/jerry/es2015/proxy_is_extensible.js
Normal file
46
tests/jerry/es2015/proxy_is_extensible.js
Normal file
@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { isExtensible (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 7.3.15
|
||||
Object.isFrozen(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 7.3.15
|
||||
Object.isSealed(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 7.2.5
|
||||
Object.isExtensible(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
54
tests/jerry/es2015/proxy_own_keys.js
Normal file
54
tests/jerry/es2015/proxy_own_keys.js
Normal file
@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { ownKeys (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// Array.prototype.sort
|
||||
Array.prototype.sort.call(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.14.4
|
||||
Object.keys(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.7.1
|
||||
Object.getOwnPropertyNames(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 19.1.2.8.1
|
||||
Object.getOwnPropertySymbols(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
39
tests/jerry/es2015/proxy_prevent_extensions.js
Normal file
39
tests/jerry/es2015/proxy_prevent_extensions.js
Normal file
@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { preventExtensions (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 7.3.14
|
||||
Object.freeze(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 7.3.14
|
||||
Object.seal(proxy)
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
69
tests/jerry/es2015/proxy_revocable.js
Normal file
69
tests/jerry/es2015/proxy_revocable.js
Normal file
@ -0,0 +1,69 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = function () {};
|
||||
var handler = { get (name) {
|
||||
return 5;
|
||||
}};
|
||||
|
||||
var revocable = Proxy.revocable(target, handler);
|
||||
|
||||
var proxy = revocable.proxy;
|
||||
|
||||
try {
|
||||
proxy.a; // FIXME: this should return 5 when proxy.[[Get]] has been implemted
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
revocable.revoke();
|
||||
|
||||
try {
|
||||
proxy.a;
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
Proxy.revocable();
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
Proxy.revocable(proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
Proxy.revocable({}, proxy);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
Proxy.revocable(proxy, {});
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
38
tests/jerry/es2015/proxy_set.js
Normal file
38
tests/jerry/es2015/proxy_set.js
Normal file
@ -0,0 +1,38 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { set (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// vm_op_set_value
|
||||
proxy.a = 5
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
|
||||
try {
|
||||
// 22.1.3.6.11.b
|
||||
Array.prototype.fill.call(proxy, 'foo', 0, 5);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
30
tests/jerry/es2015/proxy_set_prototoype_of.js
Normal file
30
tests/jerry/es2015/proxy_set_prototoype_of.js
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
// TODO: Update these tests when the internal routine has been implemented
|
||||
|
||||
var target = {};
|
||||
var handler = { setPrototypeOf (target) {
|
||||
throw 42;
|
||||
}};
|
||||
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
try {
|
||||
// 19.1.2.18
|
||||
Object.setPrototypeOf(proxy, {});
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError);
|
||||
}
|
||||
@ -64,10 +64,25 @@ main (void)
|
||||
TEST_ASSERT (jerry_value_is_undefined (prop_desc.getter));
|
||||
TEST_ASSERT (prop_desc.is_set_defined == false);
|
||||
TEST_ASSERT (jerry_value_is_undefined (prop_desc.setter));
|
||||
jerry_release_value (prop_name);
|
||||
jerry_release_value (global_obj_val);
|
||||
jerry_free_property_descriptor_fields (&prop_desc);
|
||||
|
||||
jerry_release_value (global_obj_val);
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_PROXY))
|
||||
{
|
||||
/* Note: update this test when the internal method is implemented */
|
||||
jerry_value_t target = jerry_create_object ();
|
||||
jerry_value_t handler = jerry_create_object ();
|
||||
jerry_value_t proxy = jerry_create_proxy (target, handler);
|
||||
|
||||
jerry_release_value (target);
|
||||
jerry_release_value (handler);
|
||||
is_ok = jerry_get_own_property_descriptor (proxy, prop_name, &prop_desc);
|
||||
TEST_ASSERT (!is_ok);
|
||||
jerry_release_value (proxy);
|
||||
}
|
||||
|
||||
jerry_release_value (prop_name);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
return 0;
|
||||
|
||||
@ -695,6 +695,23 @@ main (void)
|
||||
jerry_release_value (proto_val);
|
||||
jerry_release_value (obj_val);
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_PROXY))
|
||||
{
|
||||
/* Note: update this test when the internal method is implemented */
|
||||
jerry_value_t target = jerry_create_object ();
|
||||
jerry_value_t handler = jerry_create_object ();
|
||||
jerry_value_t proxy = jerry_create_proxy (target, handler);
|
||||
|
||||
jerry_release_value (target);
|
||||
jerry_release_value (handler);
|
||||
proto_val = jerry_get_prototype (proxy);
|
||||
TEST_ASSERT (jerry_value_is_error (proto_val));
|
||||
error = jerry_get_value_from_error (proto_val, true);
|
||||
TEST_ASSERT (jerry_get_error_type (error) == JERRY_ERROR_TYPE);
|
||||
jerry_release_value (error);
|
||||
jerry_release_value (proxy);
|
||||
}
|
||||
|
||||
/* Test: jerry_set_prototype */
|
||||
obj_val = jerry_create_object ();
|
||||
res = jerry_set_prototype (obj_val, jerry_create_null ());
|
||||
@ -714,6 +731,25 @@ main (void)
|
||||
jerry_release_value (proto_val);
|
||||
jerry_release_value (obj_val);
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_PROXY))
|
||||
{
|
||||
/* Note: update this test when the internal method is implemented */
|
||||
jerry_value_t target = jerry_create_object ();
|
||||
jerry_value_t handler = jerry_create_object ();
|
||||
jerry_value_t proxy = jerry_create_proxy (target, handler);
|
||||
|
||||
jerry_release_value (target);
|
||||
jerry_release_value (handler);
|
||||
new_proto = jerry_create_object ();
|
||||
res = jerry_set_prototype (proxy, new_proto);
|
||||
jerry_release_value (new_proto);
|
||||
TEST_ASSERT (jerry_value_is_error (res));
|
||||
error = jerry_get_value_from_error (res, true);
|
||||
TEST_ASSERT (jerry_get_error_type (error) == JERRY_ERROR_TYPE);
|
||||
jerry_release_value (error);
|
||||
jerry_release_value (proxy);
|
||||
}
|
||||
|
||||
/* Test: eval */
|
||||
const jerry_char_t eval_code_src1[] = "(function () { return 123; })";
|
||||
val_t = jerry_eval (eval_code_src1, sizeof (eval_code_src1) - 1, JERRY_PARSE_STRICT_MODE);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user