mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add more skip check options for Proxy objects (#4614)
Reorganize the flags to follow the list in ES2020 section 9.5 JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
129ca4946c
commit
a95e3e37e1
@ -94,8 +94,9 @@ These option bits allow specializing Proxies with non-standard behaviour.
|
||||
These flags are recommended only for those trusted Proxies, whose handlers
|
||||
produce correct results.
|
||||
|
||||
- JERRY_PROXY_SKIP_GET_CHECKS - skip [[Get]] result checks
|
||||
- JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS - skip [[GetOwnProperty]] result checks
|
||||
- JERRY_PROXY_SKIP_RESULT_VALIDATION - skip result validation for [[GetPrototypeOf]], [[SetPrototypeOf]], [[IsExtensible]],
|
||||
[[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]],
|
||||
[[Get]], [[Set]], [[Delete]] and [[OwnPropertyKeys]]
|
||||
|
||||
*New in version [[NEXT_RELEASE]]*.
|
||||
|
||||
@ -5760,7 +5761,7 @@ main (void)
|
||||
|
||||
jerry_value_t target = jerry_create_object ();
|
||||
jerry_value_t handler = jerry_create_object ();
|
||||
jerry_value_t proxy = jerry_create_special_proxy (target, handler, JERRY_PROXY_SKIP_GET_CHECKS);
|
||||
jerry_value_t proxy = jerry_create_special_proxy (target, handler, JERRY_PROXY_SKIP_RESULT_VALIDATION);
|
||||
|
||||
jerry_release_value (target);
|
||||
jerry_release_value (handler);
|
||||
|
||||
@ -2242,10 +2242,8 @@ jerry_create_proxy (const jerry_value_t target, /**< target argument */
|
||||
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
|
||||
JERRY_STATIC_ASSERT ((int) JERRY_PROXY_SKIP_GET_CHECKS == (int) ECMA_PROXY_SKIP_GET_CHECKS,
|
||||
jerry_and_ecma_proxy_skip_get_checks_must_be_equal);
|
||||
JERRY_STATIC_ASSERT ((int) JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS == (int) ECMA_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS,
|
||||
jerry_and_ecma_proxy_skip_get_own_property_checks_must_be_equal);
|
||||
JERRY_STATIC_ASSERT ((int) JERRY_PROXY_SKIP_RESULT_VALIDATION == (int) ECMA_PROXY_SKIP_RESULT_VALIDATION,
|
||||
jerry_and_ecma_proxy_skip_result_validation_must_be_equal);
|
||||
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
@ -2271,9 +2269,7 @@ jerry_create_special_proxy (const jerry_value_t target, /**< target argument */
|
||||
}
|
||||
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
const uint32_t options_mask = (JERRY_PROXY_SKIP_GET_CHECKS
|
||||
| JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS);
|
||||
options &= options_mask;
|
||||
options &= JERRY_PROXY_SKIP_RESULT_VALIDATION;
|
||||
|
||||
ecma_object_t *proxy_p = ecma_proxy_create (target, handler, options);
|
||||
return jerry_return (proxy_p == NULL ? ECMA_VALUE_ERROR : ecma_make_object_value (proxy_p));
|
||||
|
||||
@ -2189,10 +2189,13 @@ do \
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_PROXY_SKIP_GET_CHECKS = (1u << 0), /**< skip [[Get]] result checks */
|
||||
ECMA_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS = (1u << 1), /**< skip [[GetOwnProperty]] result checks */
|
||||
ECMA_PROXY_IS_CALLABLE = (1u << 2), /**< proxy is callable */
|
||||
ECMA_PROXY_IS_CONSTRUCTABLE = (1u << 3), /**< proxy is constructable */
|
||||
ECMA_PROXY_SKIP_RESULT_VALIDATION = (1u << 0), /**< skip result validation for [[GetPrototypeOf]],
|
||||
* [[SetPrototypeOf]], [[IsExtensible]],
|
||||
* [[PreventExtensions]], [[GetOwnProperty]],
|
||||
* [[DefineOwnProperty]], [[HasProperty]], [[Get]],
|
||||
* [[Set]], [[Delete]] and [[OwnPropertyKeys]] */
|
||||
ECMA_PROXY_IS_CALLABLE = (1u << 1), /**< proxy is callable */
|
||||
ECMA_PROXY_IS_CONSTRUCTABLE = (1u << 2), /**< proxy is constructable */
|
||||
} ecma_proxy_flag_types_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -308,6 +308,11 @@ ecma_proxy_object_get_prototype_of (ecma_object_t *obj_p) /**< proxy object */
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned neither object nor null"));
|
||||
}
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return handler_proto;
|
||||
}
|
||||
|
||||
/* 11. */
|
||||
ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
|
||||
|
||||
@ -417,6 +422,11 @@ ecma_proxy_object_set_prototype_of (ecma_object_t *obj_p, /**< proxy object */
|
||||
|
||||
ecma_free_value (trap_result);
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return ecma_make_boolean_value (boolean_trap_result);
|
||||
}
|
||||
|
||||
/* 11. */
|
||||
ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
|
||||
|
||||
@ -512,6 +522,11 @@ ecma_proxy_object_is_extensible (ecma_object_t *obj_p) /**< proxy object */
|
||||
|
||||
ecma_free_value (trap_result);
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return ecma_make_boolean_value (boolean_trap_result);
|
||||
}
|
||||
|
||||
bool target_result;
|
||||
|
||||
/* 10. */
|
||||
@ -606,7 +621,8 @@ ecma_proxy_object_prevent_extensions (ecma_object_t *obj_p) /**< proxy object */
|
||||
ecma_free_value (trap_result);
|
||||
|
||||
/* 10. */
|
||||
if (boolean_trap_result)
|
||||
if (boolean_trap_result
|
||||
&& !(obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION))
|
||||
{
|
||||
ecma_value_t target_is_ext = ecma_builtin_object_object_is_extensible (target_obj_p);
|
||||
|
||||
@ -688,7 +704,7 @@ ecma_proxy_object_get_own_property_descriptor (ecma_object_t *obj_p, /**< proxy
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Trap is neither an object nor undefined"));
|
||||
}
|
||||
|
||||
if (obj_p->u2.prototype_cp & ECMA_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS)
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
if (ecma_is_value_undefined (trap_result))
|
||||
{
|
||||
@ -899,6 +915,11 @@ ecma_proxy_object_define_own_property (ecma_object_t *obj_p, /**< proxy object *
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
/* 13. */
|
||||
ecma_property_descriptor_t target_desc;
|
||||
|
||||
@ -1045,7 +1066,8 @@ ecma_proxy_object_has (ecma_object_t *obj_p, /**< proxy object */
|
||||
ecma_free_value (trap_result);
|
||||
|
||||
/* 11. */
|
||||
if (!boolean_trap_result)
|
||||
if (!boolean_trap_result
|
||||
&& !(obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION))
|
||||
{
|
||||
ecma_property_descriptor_t target_desc;
|
||||
|
||||
@ -1138,7 +1160,7 @@ ecma_proxy_object_get (ecma_object_t *obj_p, /**< proxy object */
|
||||
|
||||
/* 10. */
|
||||
if (ECMA_IS_VALUE_ERROR (trap_result)
|
||||
|| (obj_p->u2.prototype_cp & ECMA_PROXY_SKIP_GET_CHECKS))
|
||||
|| (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION))
|
||||
{
|
||||
return trap_result;
|
||||
}
|
||||
@ -1263,6 +1285,11 @@ ecma_proxy_object_set (ecma_object_t *obj_p, /**< proxy object */
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
/* 12. */
|
||||
ecma_property_descriptor_t target_desc;
|
||||
|
||||
@ -1372,6 +1399,11 @@ ecma_proxy_object_delete_property (ecma_object_t *obj_p, /**< proxy object */
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
if (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION)
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
/* 12. */
|
||||
ecma_property_descriptor_t target_desc;
|
||||
|
||||
@ -1580,7 +1612,8 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */
|
||||
|
||||
ecma_free_value (trap_result_array);
|
||||
|
||||
if (trap_result == NULL)
|
||||
if (trap_result == NULL
|
||||
|| (obj_p->u2.prototype_cp & JERRY_PROXY_SKIP_RESULT_VALIDATION))
|
||||
{
|
||||
return trap_result;
|
||||
}
|
||||
|
||||
@ -525,8 +525,11 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_PROXY_SKIP_GET_CHECKS = (1u << 0), /**< skip [[Get]] result checks */
|
||||
JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS = (1u << 1), /**< skip [[GetOwnProperty]] result checks */
|
||||
JERRY_PROXY_SKIP_RESULT_VALIDATION = (1u << 0), /**< skip result validation for [[GetPrototypeOf]],
|
||||
* [[SetPrototypeOf]], [[IsExtensible]],
|
||||
* [[PreventExtensions]], [[GetOwnProperty]],
|
||||
* [[DefineOwnProperty]], [[HasProperty]], [[Get]],
|
||||
* [[Set]], [[Delete]] and [[OwnPropertyKeys]] */
|
||||
} jerry_proxy_object_options_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -29,10 +29,7 @@ create_special_proxy_handler (const jerry_call_info_t *call_info_p, /**< call in
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
|
||||
const uint32_t options = (JERRY_PROXY_SKIP_GET_CHECKS
|
||||
| JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS);
|
||||
|
||||
return jerry_create_special_proxy (args_p[0], args_p[1], options);
|
||||
return jerry_create_special_proxy (args_p[0], args_p[1], JERRY_PROXY_SKIP_RESULT_VALIDATION);
|
||||
} /* create_special_proxy_handler */
|
||||
|
||||
static void
|
||||
@ -78,15 +75,34 @@ main (void)
|
||||
" throw 'Assertion failed!'\n"
|
||||
"}");
|
||||
|
||||
/* This test fails unless JERRY_PROXY_SKIP_GET_CHECKS is set. */
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" get(target, key) { return 5 }\n"
|
||||
"})\n"
|
||||
"assert(proxy.prop === 5)");
|
||||
/* These tests fail unless JERRY_PROXY_SKIP_RESULT_VALIDATION is set. */
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.preventExtensions(o)\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" getPrototypeOf(target) { return Array.prototype }\n"
|
||||
"})\n"
|
||||
"assert(Object.getPrototypeOf(proxy) === Array.prototype)");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.preventExtensions(o)\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" setPrototypeOf(target, proto) { return true }\n"
|
||||
"})\n"
|
||||
"Object.setPrototypeOf(proxy, Array.prototype)");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" isExtensible(target) { return false }\n"
|
||||
"})\n"
|
||||
"assert(Object.isExtensible(proxy) === false)");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" preventExtensions(target) { return true }\n"
|
||||
"})\n"
|
||||
"Object.preventExtensions(proxy)");
|
||||
|
||||
/* This test fails unless JERRY_PROXY_SKIP_GET_OWN_PROPERTY_CHECKS is set. */
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4, enumerable:true })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
@ -100,6 +116,48 @@ main (void)
|
||||
"assert(desc.enumerable === false)\n"
|
||||
"assert(desc.writable === true)\n");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { get() {} })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" defineProperty(target, key, descriptor) { return true }\n"
|
||||
"})\n"
|
||||
"Object.defineProperty(proxy, 'prop', { value:5 })");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" has(target, key) { return false }\n"
|
||||
"})\n"
|
||||
"assert(!Reflect.has(proxy, 'prop'))");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" get(target, key) { return 5 }\n"
|
||||
"})\n"
|
||||
"assert(proxy.prop === 5)");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" set(target, key, value) { return true }\n"
|
||||
"})\n"
|
||||
"proxy.prop = 8");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" deleteProperty(target, key) { return true }\n"
|
||||
"})\n"
|
||||
"assert(delete proxy.prop)");
|
||||
|
||||
run_eval ("var o = {}\n"
|
||||
"Object.defineProperty(o, 'prop', { value:4 })\n"
|
||||
"var proxy = create_special_proxy(o, {\n"
|
||||
" ownKeys(target) { return [] }\n"
|
||||
"})\n"
|
||||
"Object.keys(proxy)");
|
||||
|
||||
jerry_cleanup ();
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user