diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 10e49b9ca..b2cf06094 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -5791,7 +5791,7 @@ These APIs all depend on build option (`JERRY_BUILTIN_PROXY`). **Summary** -Gets the target object of a Proxy object +Gets the target object of a Proxy object. *Notes*: - This API depends on a build option (`JERRY_BUILTIN_PROXY`) and can be checked @@ -5804,7 +5804,7 @@ Gets the target object of a Proxy object ```c jerry_value_t -jerry_get_proxy_target (jerry_value_t proxy_value) +jerry_get_proxy_target (jerry_value_t proxy_value); ``` - `proxy_value` - Proxy object value @@ -5838,6 +5838,60 @@ jerry_get_proxy_target (jerry_value_t proxy_value) - [jerry_create_proxy](#jerry_create_proxy) - [jerry_create_special_proxy](#jerry_create_special_proxy) +- [jerry_get_proxy_handler](#jerry_get_proxy_handler) + +## jerry_get_proxy_handler + +**Summary** + +Gets the handler object of a Proxy object. + +*Notes*: +- This API depends on a build option (`JERRY_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 es.next profile enables this by default. + + +**Prototype** + +```c +jerry_value_t +jerry_get_proxy_handler (jerry_value_t proxy_value); +``` + +- `proxy_value` - Proxy object value +- return value + - type error - if proxy_value is not a Proxy object + - handler object - otherwise + +*New in version [[NEXT_RELEASE]]*. + +**Example** + +```c +{ + 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); + + handler = jerry_get_proxy_handler (proxy); + + // ... usage of the handler + + jerry_release_value (handler); + jerry_release_value (proxy); +} +``` + +**See also** + +- [jerry_create_proxy](#jerry_create_proxy) +- [jerry_create_special_proxy](#jerry_create_special_proxy) +- [jerry_get_proxy_target](#jerry_get_proxy_target) # Acquire and release API values diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 0621d08d3..8678a34fd 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -5023,9 +5023,43 @@ jerry_get_proxy_target (jerry_value_t proxy_value) /**< proxy value */ JERRY_UNUSED (proxy_value); #endif /* JERRY_BUILTIN_PROXY */ - return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Passed value is not a proxy object"))); + return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_argument_is_not_a_proxy))); } /* jerry_get_proxy_target */ +/** + * Get the handler object of a Proxy object + * + * @return type error - if proxy_value is not a Proxy object + * handler object - otherwise + */ +jerry_value_t +jerry_get_proxy_handler (jerry_value_t proxy_value) /**< proxy value */ +{ + jerry_assert_api_available (); + +#if JERRY_BUILTIN_PROXY + if (ecma_is_value_object (proxy_value)) + { + ecma_object_t *object_p = ecma_get_object_from_value (proxy_value); + + if (ECMA_OBJECT_IS_PROXY (object_p)) + { + ecma_proxy_object_t *proxy_object_p = (ecma_proxy_object_t *) object_p; + + if (!ecma_is_value_null (proxy_object_p->handler)) + { + ecma_ref_object (ecma_get_object_from_value (proxy_object_p->handler)); + } + return proxy_object_p->handler; + } + } +#else /* !JERRY_BUILTIN_PROXY */ + JERRY_UNUSED (proxy_value); +#endif /* JERRY_BUILTIN_PROXY */ + + return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_argument_is_not_a_proxy))); +} /* jerry_get_proxy_handler */ + /** * Validate UTF-8 string * diff --git a/jerry-core/ecma/base/ecma-errors.c b/jerry-core/ecma/base/ecma-errors.c index 925979a14..a5bba8734 100644 --- a/jerry-core/ecma/base/ecma-errors.c +++ b/jerry-core/ecma/base/ecma-errors.c @@ -118,6 +118,11 @@ const char * const ecma_error_class_is_non_configurable = "Prototype property of */ const char * const ecma_error_argument_is_not_an_object = "Argument is not an object"; +/** + * Error message, argument is not a Proxy object + */ +const char * const ecma_error_argument_is_not_a_proxy = "Argument is not a Proxy object"; + /** * Error message, target is not a constructor */ diff --git a/jerry-core/ecma/base/ecma-errors.h b/jerry-core/ecma/base/ecma-errors.h index 4301abfe6..cb66ff6e0 100644 --- a/jerry-core/ecma/base/ecma-errors.h +++ b/jerry-core/ecma/base/ecma-errors.h @@ -63,6 +63,7 @@ extern const char * const ecma_error_arraybuffer_is_detached; extern const char * const ecma_error_cannot_convert_to_object; extern const char * const ecma_error_class_is_non_configurable; extern const char * const ecma_error_argument_is_not_an_object; +extern const char * const ecma_error_argument_is_not_a_proxy; extern const char * const ecma_error_target_is_not_a_constructor; extern const char * const ecma_error_argument_is_not_an_regexp; extern const char * const ecma_error_invalid_array_length; diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 6d8583669..433aec6c3 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -324,6 +324,7 @@ void jerry_get_bigint_digits (jerry_value_t value, uint64_t *digits_p, uint32_t * Proxy functions. */ jerry_value_t jerry_get_proxy_target (jerry_value_t proxy_value); +jerry_value_t jerry_get_proxy_handler (jerry_value_t proxy_value); /** * Input validator functions. diff --git a/tests/unit-core/test-proxy.c b/tests/unit-core/test-proxy.c index 341cbede5..8c36e9c0a 100644 --- a/tests/unit-core/test-proxy.c +++ b/tests/unit-core/test-proxy.c @@ -340,21 +340,31 @@ main (void) target = jerry_create_object (); handler = jerry_create_object (); proxy = jerry_create_proxy (target, handler); - jerry_release_value (handler); { jerry_value_t res = jerry_get_proxy_target (proxy); TEST_ASSERT (res == target); jerry_release_value (res); + res = jerry_get_proxy_handler (proxy); + TEST_ASSERT (res == handler); + jerry_release_value (res); + res = jerry_get_proxy_target (target); TEST_ASSERT (jerry_value_is_error (res)); res = jerry_get_value_from_error (res, true); TEST_ASSERT (jerry_get_error_type (res) == JERRY_ERROR_TYPE); jerry_release_value (res); + + res = jerry_get_proxy_handler (handler); + TEST_ASSERT (jerry_value_is_error (res)); + res = jerry_get_value_from_error (res, true); + TEST_ASSERT (jerry_get_error_type (res) == JERRY_ERROR_TYPE); + jerry_release_value (res); } jerry_release_value (proxy); + jerry_release_value (handler); jerry_release_value (target); test_proxy_native ();