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:
Robert Fancsik
2020-02-28 14:41:59 +01:00
committed by GitHub
parent 9b393ee2ea
commit 4e136c8973
57 changed files with 3017 additions and 397 deletions
+64
View File
@@ -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). */
+30 -1
View File
@@ -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;
}
+3 -26
View File
@@ -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.
+12 -2
View File
@@ -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);
+15 -1
View File
@@ -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."));
}