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:
@@ -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."));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user