Correctly handle the Proxy IsCallable and IsConstructor information (#4264)

The `IsCallable(target)` and `IsConstructor(target)` info
can't be stored in the target/handler values.
If the input for the ProxyCreate was a revocable Proxy the original target's
callable/constructor information must be retained even after the
Proxy was revoked.

JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.usz@partner.samsung.com
This commit is contained in:
Péter Gál
2020-11-17 10:38:25 +01:00
committed by GitHub
parent 7262b98021
commit 5d916fb8d4
6 changed files with 99 additions and 8 deletions
+11 -3
View File
@@ -786,7 +786,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
case ECMA_OBJECT_TYPE_PROXY:
{
ecma_gc_mark_proxy_object (object_p);
break;
/* No need to free the properties of a proxy (there should be none).
* Aside from the tag bits every other bit should be zero,
*/
JERRY_ASSERT ((object_p->u1.property_list_cp & ~JMEM_TAG_MASK) == 0);
return;
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
@@ -1499,8 +1503,12 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
#if ENABLED (JERRY_BUILTIN_PROXY)
case ECMA_OBJECT_TYPE_PROXY:
{
ext_object_size = sizeof (ecma_proxy_object_t);
break;
/* No need to free the properties of a proxy (there should be none).
* Aside from the tag bits every other bit should be zero,
*/
JERRY_ASSERT ((object_p->u1.property_list_cp & ~JMEM_TAG_MASK) == 0);
ecma_dealloc_extended_object (object_p, sizeof (ecma_proxy_object_t));
return;
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
case ECMA_OBJECT_TYPE_FUNCTION:
+4
View File
@@ -2128,6 +2128,10 @@ do \
#if ENABLED (JERRY_BUILTIN_PROXY)
/**
* Description of Proxy objects.
*
* A Proxy object's property list is used to store extra information:
* * The "header.u1.property_list_cp" 1st tag bit stores the IsCallable information.
* * The "header.u1.property_list_cp" 2nd tag bit stores the IsConstructor information.
*/
typedef struct
{
@@ -106,7 +106,7 @@ ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
#if ENABLED (JERRY_BUILTIN_PROXY)
if (ECMA_OBJECT_TYPE_IS_PROXY (type))
{
return ecma_op_is_callable (((ecma_proxy_object_t *) obj_p)->target);
return ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (obj_p->u1.property_list_cp) != 0;
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
@@ -159,7 +159,7 @@ ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
#if ENABLED (JERRY_BUILTIN_PROXY)
if (ECMA_OBJECT_TYPE_IS_PROXY (type))
{
return ecma_is_constructor (((ecma_proxy_object_t *) obj_p)->target);
return ECMA_GET_SECOND_BIT_FROM_POINTER_TAG (obj_p->u1.property_list_cp) != 0;
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
@@ -66,6 +66,20 @@ ecma_proxy_create (ecma_value_t target, /**< proxy target */
ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
/* ES2015: 7. */
/* ES11+: 5. */
if (ecma_op_is_callable (target))
{
ECMA_SET_FIRST_BIT_TO_POINTER_TAG (obj_p->u1.property_list_cp);
/* ES2015: 7.b. */
/* ES11+: 5.b. */
if (ecma_is_constructor (target))
{
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (obj_p->u1.property_list_cp);
}
}
/* ES2015: 8. */
/* ES11+: 6. */
proxy_obj_p->target = target;