diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c
index 59ab05628..d35576b79 100644
--- a/jerry-core/ecma/base/ecma-gc.c
+++ b/jerry-core/ecma/base/ecma-gc.c
@@ -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:
diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h
index 1c3247dd0..b84a0eeaf 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -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
{
diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c
index ed004a9e6..c0e4f68a4 100644
--- a/jerry-core/ecma/operations/ecma-function-object.c
+++ b/jerry-core/ecma/operations/ecma-function-object.c
@@ -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) */
diff --git a/jerry-core/ecma/operations/ecma-proxy-object.c b/jerry-core/ecma/operations/ecma-proxy-object.c
index f9ee4083e..8866bfa5a 100644
--- a/jerry-core/ecma/operations/ecma-proxy-object.c
+++ b/jerry-core/ecma/operations/ecma-proxy-object.c
@@ -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;
diff --git a/tests/jerry/es.next/proxy_flags.js b/tests/jerry/es.next/proxy_flags.js
new file mode 100644
index 000000000..febd80ce7
--- /dev/null
+++ b/tests/jerry/es.next/proxy_flags.js
@@ -0,0 +1,68 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var target_called = 0;
+function target_method() {
+ target_called++;
+}
+
+var proxy_revocable_function = Proxy.revocable(target_method, {})
+var proxy_function = proxy_revocable_function.proxy;
+
+/* Test Proxy IsCallable(target) */
+/* The proxy target should have a function type. */
+assert(typeof(proxy_function) === "function");
+
+/* The proxy can be called with new */
+var new_obj = new proxy_function()
+assert(new_obj instanceof target_method);
+assert(target_called === 1);
+
+/* Test Proxy IsConstructor(target) */
+/* Array.from tries to use the "this" value as constructor. */
+var array_result = Array.from.call(proxy_function, [1, 2, 3]);
+assert(Array.isArray(array_result) === false);
+assert(target_called === 2);
+
+proxy_revocable_function.revoke();
+
+/* Test Proxy IsCallable(target) if the proxy is revoked. */
+/* After the proxy was revoked the type is still function. */
+assert(typeof(proxy_function) === "function");
+
+/* After the proxy was revoked the constructor should not be called
+ * and an error should be reported
+ */
+try {
+ new proxy_function();
+ assert(false);
+} catch (ex) {
+ assert(ex instanceof TypeError);
+}
+
+assert(target_called === 2);
+
+/* Test Proxy IsConstructor(target) if the proxy is revoked. */
+/* Array.from tries to use the "this" value as constructor and as the
+ * proxy is revoked the constructor call should fail.
+ * The IsConstructor(proxy_function) is still true.
+ */
+try {
+ Array.from.call(proxy_function, [1, 2, 3]);
+ assert(false);
+} catch (ex) {
+ assert(ex instanceof TypeError);
+}
+
+assert(target_called === 2);
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 619e7b1c0..764aa808a 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -109,9 +109,7 @@
Test expects incorrect call order
Test expects incorrect call order
-
-
@@ -544,7 +542,6 @@
-