diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c
index 3227e0c24..1f0541cac 100644
--- a/jerry-core/api/jerry.c
+++ b/jerry-core/api/jerry.c
@@ -1001,7 +1001,7 @@ jerry_object_get_type (const jerry_value_t value) /**< input value to check */
{
case ECMA_OBJECT_TYPE_FUNCTION:
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
return JERRY_OBJECT_TYPE_FUNCTION;
}
@@ -1145,7 +1145,7 @@ jerry_function_get_type (const jerry_value_t value) /**< input value to check */
{
return JERRY_FUNCTION_TYPE_BOUND;
}
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
return JERRY_FUNCTION_TYPE_GENERIC;
}
@@ -3692,19 +3692,13 @@ jerry_resolve_or_reject_promise (jerry_value_t promise, /**< the promise value *
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p)));
}
- lit_magic_string_id_t prop_name = (is_resolve ? LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION
- : LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
+ ecma_promise_object_t *promise_p = (ecma_promise_object_t *) ecma_get_object_from_value (promise);
+ ecma_value_t function = is_resolve ? promise_p->resolve : promise_p->reject;
- ecma_value_t function = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (promise), prop_name);
-
- ecma_value_t ret = ecma_op_function_call (ecma_get_object_from_value (function),
- ECMA_VALUE_UNDEFINED,
- &argument,
- 1);
-
- ecma_free_value (function);
-
- return ret;
+ return ecma_op_function_call (ecma_get_object_from_value (function),
+ ECMA_VALUE_UNDEFINED,
+ &argument,
+ 1);
#else /* !ENABLED (JERRY_BUILTIN_PROMISE) */
JERRY_UNUSED (promise);
JERRY_UNUSED (argument);
diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c
index 398104465..63b14ac4e 100644
--- a/jerry-core/ecma/base/ecma-gc.c
+++ b/jerry-core/ecma/base/ecma-gc.c
@@ -19,6 +19,7 @@
#include "ecma-alloc.h"
#include "ecma-array-object.h"
+#include "ecma-builtin-handlers.h"
#include "ecma-container-object.h"
#include "ecma-function-object.h"
#include "ecma-globals.h"
@@ -267,6 +268,15 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended
/* Mark all reactions. */
ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) ext_object_p;
+
+ if (!ecma_is_value_empty (promise_object_p->resolve))
+ {
+ JERRY_ASSERT (ecma_is_value_object (promise_object_p->resolve)
+ && ecma_is_value_object (promise_object_p->reject));
+ ecma_gc_set_object_visited (ecma_get_object_from_value (promise_object_p->resolve));
+ ecma_gc_set_object_visited (ecma_get_object_from_value (promise_object_p->reject));
+ }
+
ecma_collection_t *collection_p = promise_object_p->reactions;
if (collection_p != NULL)
@@ -771,48 +781,72 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break;
}
#if ENABLED (JERRY_ESNEXT)
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_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)
+ if (ecma_get_object_is_builtin (object_p))
{
- ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) object_p;
+ ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
- if (!ecma_is_value_null (rev_proxy_p->proxy))
+ switch (ext_func_p->u.native_handler.id)
{
- ecma_gc_set_object_visited (ecma_get_object_from_value (rev_proxy_p->proxy));
+ case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
+ case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
+ {
+ ecma_promise_resolver_t *resolver_obj_p = (ecma_promise_resolver_t *) object_p;
+ ecma_gc_set_object_visited (ecma_get_object_from_value (resolver_obj_p->promise));
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY:
+ case ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY:
+ {
+ ecma_promise_finally_function_t *finally_obj_p = (ecma_promise_finally_function_t *) object_p;
+ ecma_gc_set_object_visited (ecma_get_object_from_value (finally_obj_p->constructor));
+ ecma_gc_set_object_visited (ecma_get_object_from_value (finally_obj_p->on_finally));
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR:
+ {
+ ecma_promise_capability_executor_t *executor_p = (ecma_promise_capability_executor_t *) object_p;
+ ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->capability));
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER:
+ {
+ ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) object_p;
+ ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->capability));
+ ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->values));
+ ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->remaining_elements));
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROXY_REVOKE:
+ {
+ 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;
+ }
+ case ECMA_NATIVE_HANDLER_VALUE_THUNK:
+ case ECMA_NATIVE_HANDLER_VALUE_THROWER:
+ {
+ ecma_promise_value_thunk_t *thunk_obj_p = (ecma_promise_value_thunk_t *) object_p;
+
+ if (ecma_is_value_object (thunk_obj_p->value))
+ {
+ ecma_gc_set_object_visited (ecma_get_object_from_value (thunk_obj_p->value));
+ }
+ break;
+ }
+ default:
+ {
+ JERRY_UNREACHABLE ();
+ }
}
}
- else if (ext_func_p->u.external_handler_cb == ecma_op_get_capabilities_executor_cb)
- {
- ecma_promise_capability_executor_t *executor_p = (ecma_promise_capability_executor_t *) object_p;
- ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->capability));
- }
- else if (ext_func_p->u.external_handler_cb == ecma_promise_all_handler_cb)
- {
- ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) object_p;
- ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->capability));
- ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->values));
- ecma_gc_set_object_visited (ecma_get_object_from_value (executor_p->remaining_elements));
- }
- else if (ext_func_p->u.external_handler_cb == ecma_promise_then_finally_cb
- || ext_func_p->u.external_handler_cb == ecma_promise_catch_finally_cb)
- {
- ecma_promise_finally_function_t *finally_obj_p = (ecma_promise_finally_function_t *) object_p;
- ecma_gc_set_object_visited (ecma_get_object_from_value (finally_obj_p->constructor));
- ecma_gc_set_object_visited (ecma_get_object_from_value (finally_obj_p->on_finally));
- }
- else if (ext_func_p->u.external_handler_cb == ecma_value_thunk_helper_cb
- || ext_func_p->u.external_handler_cb == ecma_value_thunk_thrower_cb)
- {
- ecma_promise_value_thunk_t *thunk_obj_p = (ecma_promise_value_thunk_t *) object_p;
- if (ecma_is_value_object (thunk_obj_p->value))
- {
- ecma_gc_set_object_visited (ecma_get_object_from_value (thunk_obj_p->value));
- }
- }
break;
}
#endif /* ENABLED (JERRY_ESNEXT) */
@@ -1155,8 +1189,57 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
}
else
{
- length_and_bitset_size = ((ecma_extended_object_t *) object_p)->u.built_in.length_and_bitset_size;
- ext_object_size += (2 * sizeof (uint32_t)) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
+#if ENABLED (JERRY_ESNEXT)
+ if (object_type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
+ {
+ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
+ switch (ext_obj_p->u.native_handler.id)
+ {
+ case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
+ case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
+ {
+ ext_object_size = sizeof (ecma_promise_resolver_t);
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY:
+ case ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY:
+ {
+ ext_object_size = sizeof (ecma_promise_finally_function_t);
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR:
+ {
+ ext_object_size = sizeof (ecma_promise_capability_executor_t);
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER:
+ {
+ ext_object_size = sizeof (ecma_promise_all_executor_t);
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_PROXY_REVOKE:
+ {
+ ext_object_size = sizeof (ecma_revocable_proxy_object_t);
+ break;
+ }
+ case ECMA_NATIVE_HANDLER_VALUE_THUNK:
+ case ECMA_NATIVE_HANDLER_VALUE_THROWER:
+ {
+ ext_object_size = sizeof (ecma_promise_value_thunk_t);
+ break;
+ }
+ default:
+ {
+ JERRY_UNREACHABLE ();
+ }
+ }
+ }
+ else
+#endif /* ENABLED (JERRY_ESNEXT) */
+ {
+ length_and_bitset_size = ((ecma_extended_object_t *) object_p)->u.built_in.length_and_bitset_size;
+ ext_object_size += (2 * sizeof (uint32_t)) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
+ }
ecma_gc_free_properties (object_p);
ecma_dealloc_extended_object (object_p, ext_object_size);
@@ -1181,38 +1264,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
}
break;
}
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
-#if ENABLED (JERRY_ESNEXT)
- 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);
- }
- else if (ext_func_p->u.external_handler_cb == ecma_op_get_capabilities_executor_cb)
- {
- ext_object_size = sizeof (ecma_promise_capability_executor_t);
- }
- else if (ext_func_p->u.external_handler_cb == ecma_promise_all_handler_cb)
- {
- ext_object_size = sizeof (ecma_promise_all_executor_t);
- }
- else if (ext_func_p->u.external_handler_cb == ecma_promise_then_finally_cb
- || ext_func_p->u.external_handler_cb == ecma_promise_catch_finally_cb)
- {
- ext_object_size = sizeof (ecma_promise_finally_function_t);
- }
- else if (ext_func_p->u.external_handler_cb == ecma_value_thunk_helper_cb
- || ext_func_p->u.external_handler_cb == ecma_value_thunk_thrower_cb)
- {
- ecma_promise_value_thunk_t *thunk_obj_p = (ecma_promise_value_thunk_t *) object_p;
-
- ecma_free_value_if_not_object (thunk_obj_p->value);
-
- ext_object_size = sizeof (ecma_promise_value_thunk_t);
- }
-#endif /* ENABLED (JERRY_ESNEXT) */
break;
}
case ECMA_OBJECT_TYPE_CLASS:
diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h
index af4591697..001940089 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -290,10 +290,10 @@ typedef ecma_value_t (*ecma_vm_exec_stop_callback_t) (void *user_p);
/**
* Type of an external function handler.
*/
-typedef ecma_value_t (*ecma_external_handler_t) (const ecma_value_t function_obj,
- const ecma_value_t this_val,
- const ecma_value_t args_p[],
- const uint32_t args_count);
+typedef ecma_value_t (*ecma_native_handler_t) (const ecma_value_t function_obj,
+ const ecma_value_t this_val,
+ const ecma_value_t args_p[],
+ const uint32_t args_count);
/**
* Native free callback of an object.
@@ -664,7 +664,7 @@ typedef enum
/* Note: these 4 types must be in this order. See IsCallable operation. */
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 */
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION = 7, /**< Native function object */
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
ECMA_OBJECT_TYPE__MAX /**< maximum value */
@@ -959,7 +959,16 @@ typedef struct
ecma_value_t args_len_or_this; /**< length of arguments or this value */
} bound_function;
- ecma_external_handler_t external_handler_cb; /**< external function */
+ /**
+ * Description of a built-in native handler object.
+ */
+ struct
+ {
+ uint32_t id; /**< handler id */
+ uint32_t flags; /**< handler flags */
+ } native_handler;
+
+ ecma_native_handler_t external_handler_cb; /**< external function */
} u;
} ecma_extended_object_t;
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.c
new file mode 100644
index 000000000..87ebcf8d8
--- /dev/null
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.c
@@ -0,0 +1,61 @@
+/* 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.
+ */
+
+#include "ecma-globals.h"
+
+#if ENABLED (JERRY_ESNEXT)
+
+#include "ecma-builtin-handlers.h"
+#include "ecma-promise-object.h"
+
+static const ecma_native_handler_t ecma_native_handlers[] =
+{
+#define ECMA_NATIVE_HANDLER(id, handler, length) handler,
+#include "ecma-builtin-handlers.inc.h"
+#undef ECMA_NATIVE_HANDLER
+};
+
+static const uint8_t ecma_native_handler_lengths[] =
+{
+#define ECMA_NATIVE_HANDLER(id, handler, length) length,
+#include "ecma-builtin-handlers.inc.h"
+#undef ECMA_NATIVE_HANDLER
+};
+
+/**
+ * Get the native handler of a built-in handler type.
+ *
+ * return Function pointer of the handler
+ */
+ecma_native_handler_t
+ecma_builtin_handler_get (ecma_native_handler_id_t id) /**< handler id */
+{
+ JERRY_ASSERT (id < ECMA_NATIVE_HANDLER__COUNT);
+ return ecma_native_handlers[id];
+} /* ecma_builtin_handler_get */
+
+/**
+ * Get the initial 'length' value of a built-in handler type.
+ *
+ * return 'length' value of the handler
+ */
+uint8_t
+ecma_builtin_handler_get_length (ecma_native_handler_id_t id) /**< handler id */
+{
+ JERRY_ASSERT (id < ECMA_NATIVE_HANDLER__COUNT);
+ return ecma_native_handler_lengths[id];
+} /* ecma_builtin_handler_get_length */
+
+#endif /* ENABLED (JERRY_ESNEXT) */
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.h
new file mode 100644
index 000000000..4cff113ea
--- /dev/null
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.h
@@ -0,0 +1,51 @@
+/* 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.
+ */
+
+#ifndef ECMA_BUILTIN_HANDLERS_H
+#define ECMA_BUILTIN_HANDLERS_H
+
+#include "ecma-globals.h"
+
+#if ENABLED (JERRY_ESNEXT)
+
+#include "ecma-helpers.h"
+#include "ecma-builtins.h"
+#include "ecma-promise-object.h"
+#include "ecma-proxy-object.h"
+
+typedef enum
+{
+#define ECMA_NATIVE_HANDLER(id, handler, length) id,
+#include "ecma-builtin-handlers.inc.h"
+#undef ECMA_NATIVE_HANDLER
+ ECMA_NATIVE_HANDLER__COUNT
+} ecma_native_handler_id_t;
+
+typedef enum
+{
+ ECMA_NATIVE_HANDLER_FLAGS_NONE = 0,
+ ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED = (1 << 0),
+ ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED = (1 << 1),
+ ECMA_NATIVE_HANDLER_FLAGS_PROMISE_ALREADY_RESOLVED = (1 << 2),
+} ecma_native_handler_flags_t;
+
+ecma_native_handler_t
+ecma_builtin_handler_get (ecma_native_handler_id_t id);
+uint8_t
+ecma_builtin_handler_get_length (ecma_native_handler_id_t id);
+
+#endif /* ENABLED (JERRY_ESNEXT) */
+
+#endif /* !ECMA_BUILTIN_HANDLERS_H */
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.inc.h
new file mode 100644
index 000000000..0e4990cbf
--- /dev/null
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-handlers.inc.h
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_RESOLVE, ecma_promise_resolve_handler, 1)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_REJECT, ecma_promise_reject_handler, 1)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY, ecma_promise_then_finally_cb, 1)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY, ecma_promise_catch_finally_cb, 1)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER, ecma_promise_all_handler_cb, 1)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR, ecma_op_get_capabilities_executor_cb, 2)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_PROXY_REVOKE, ecma_proxy_revoke_cb, 0)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_VALUE_THUNK, ecma_value_thunk_helper_cb, 0)
+ECMA_NATIVE_HANDLER (ECMA_NATIVE_HANDLER_VALUE_THROWER, ecma_value_thunk_thrower_cb, 0)
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c
index 68f5730f0..b6d230f0d 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c
@@ -16,6 +16,7 @@
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtin-helpers.h"
+#include "ecma-builtin-handlers.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
@@ -294,22 +295,18 @@ ecma_builtin_promise_perform_all (ecma_value_t iterator, /**< iteratorRecord */
break;
}
- /* k. */
- ecma_object_t *executor_func_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_promise_all_executor_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
-
- ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) executor_func_p;
- executor_p->header.u.external_handler_cb = ecma_promise_all_handler_cb;
-
- /* l. */
if (JERRY_UNLIKELY (idx == UINT32_MAX - 1))
{
- ecma_deref_object (executor_func_p);
ecma_raise_range_error (ECMA_ERR_MSG ("Promise.all remaining elements limit reached."));
break;
}
+ /* k. */
+ ecma_object_t *executor_func_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_ALL_HELPER,
+ sizeof (ecma_promise_all_executor_t));
+
+ ecma_promise_all_executor_t *executor_p = (ecma_promise_all_executor_t *) executor_func_p;
+
/* m. + t. */
executor_p->index = ++idx;
diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c
index 0d5343238..950aef403 100644
--- a/jerry-core/ecma/operations/ecma-function-object.c
+++ b/jerry-core/ecma/operations/ecma-function-object.c
@@ -15,6 +15,7 @@
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
+#include "ecma-builtin-handlers.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
@@ -142,6 +143,11 @@ ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
ecma_object_type_t type = ecma_get_object_type (obj_p);
+ if (type < ECMA_OBJECT_TYPE_PROXY)
+ {
+ return false;
+ }
+
while (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
{
ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) obj_p;
@@ -164,7 +170,8 @@ ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
}
- return (type >= ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ JERRY_ASSERT (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
+ return !ecma_get_object_is_builtin (obj_p);
} /* ecma_object_is_constructor */
/**
@@ -559,17 +566,17 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's sc
* @return pointer to newly created external function object
*/
ecma_object_t *
-ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**< pointer to external native handler */
+ecma_op_create_external_function_object (ecma_native_handler_t handler_cb) /**< pointer to external native handler */
{
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *function_obj_p;
function_obj_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
/*
- * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
+ * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_NATIVE_FUNCTION type.
*
* See also: ecma_object_get_class_name
*/
@@ -580,6 +587,31 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**
return function_obj_p;
} /* ecma_op_create_external_function_object */
+#if ENABLED (JERRY_ESNEXT)
+/**
+ * Create built-in native handler object.
+ *
+ * @return pointer to newly created native handler object
+ */
+ecma_object_t *
+ecma_op_create_native_handler (ecma_native_handler_id_t id, /**< handler id */
+ size_t object_size) /**< created object size */
+{
+ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
+
+ ecma_object_t *function_obj_p = ecma_create_object (prototype_obj_p,
+ object_size,
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
+ ecma_set_object_is_builtin (function_obj_p);
+
+ ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
+ ext_func_obj_p->u.native_handler.id = id;
+ ext_func_obj_p->u.native_handler.flags = ECMA_NATIVE_HANDLER_FLAGS_NONE;
+
+ return function_obj_p;
+} /* ecma_op_create_native_handler */
+#endif /* ENABLED (JERRY_ESNEXT) */
+
/**
* Get compiled code of a function object.
*
@@ -659,7 +691,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
}
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
- || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
+ || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
|| ECMA_OBJECT_IS_PROXY (func_obj_p));
ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
@@ -988,16 +1020,24 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
* @return the result of the function call.
*/
static ecma_value_t JERRY_ATTR_NOINLINE
-ecma_op_function_call_external (ecma_object_t *func_obj_p, /**< Function object */
- ecma_value_t this_arg_value, /**< 'this' argument's value */
- const ecma_value_t *arguments_list_p, /**< arguments list */
- uint32_t arguments_list_len) /**< length of arguments list */
+ecma_op_function_call_native (ecma_object_t *func_obj_p, /**< Function object */
+ ecma_value_t this_arg_value, /**< 'this' argument's value */
+ const ecma_value_t *arguments_list_p, /**< arguments list */
+ uint32_t arguments_list_len) /**< length of arguments list */
{
- JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
- JERRY_ASSERT (ext_func_obj_p->u.external_handler_cb != NULL);
+#if ENABLED (JERRY_ESNEXT)
+ if (ecma_get_object_is_builtin (func_obj_p))
+ {
+ ecma_native_handler_t handler = ecma_builtin_handler_get (ext_func_obj_p->u.native_handler.id);
+ return handler (ecma_make_object_value (func_obj_p), this_arg_value, arguments_list_p, arguments_list_len);
+ }
+#endif /* ENABLED (JERRY_ESNEXT) */
+
+ JERRY_ASSERT (ext_func_obj_p->u.external_handler_cb != NULL);
ecma_value_t ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
this_arg_value,
arguments_list_p,
@@ -1012,7 +1052,7 @@ ecma_op_function_call_external (ecma_object_t *func_obj_p, /**< Function object
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
#endif /* ENABLED (JERRY_DEBUGGER) */
return ret_value;
-} /* ecma_op_function_call_external */
+} /* ecma_op_function_call_native */
/**
* Append the bound arguments into the given collection
@@ -1142,9 +1182,9 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
{
result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
}
- else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
{
- result = ecma_op_function_call_external (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
+ result = ecma_op_function_call_native (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
}
else
{
@@ -1200,13 +1240,13 @@ ecma_op_function_construct_bound (ecma_object_t *func_obj_p, /**< Function objec
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
-static ecma_value_t JERRY_ATTR_NOINLINE
-ecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function object */
- ecma_object_t *new_target_p, /**< new target */
- const ecma_value_t *arguments_list_p, /**< arguments list */
- uint32_t arguments_list_len) /**< length of arguments list */
+static ecma_value_t
+ecma_op_function_construct_native (ecma_object_t *func_obj_p, /**< Function object */
+ ecma_object_t *new_target_p, /**< new target */
+ const ecma_value_t *arguments_list_p, /**< arguments list */
+ uint32_t arguments_list_len) /**< length of arguments list */
{
- JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
@@ -1224,7 +1264,7 @@ ecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function ob
JERRY_CONTEXT (current_new_target) = new_target_p;
#endif /* ENABLED (JERRY_ESNEXT) */
- ecma_value_t ret_value = ecma_op_function_call_external (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
+ ecma_value_t ret_value = ecma_op_function_call_native (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
#if ENABLED (JERRY_ESNEXT)
JERRY_CONTEXT (current_new_target) = old_new_target_p;
@@ -1239,7 +1279,7 @@ ecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function ob
ecma_free_value (ret_value);
return this_arg;
-} /* ecma_op_function_construct_external */
+} /* ecma_op_function_construct_native */
/**
* General [[Construct]] implementation function objects
@@ -1275,9 +1315,9 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
}
- if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION))
+ if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION))
{
- return ecma_op_function_construct_external (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
+ return ecma_op_function_construct_native (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
}
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_FUNCTION);
@@ -1404,7 +1444,7 @@ static ecma_property_t *
ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the function object */
{
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
- || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
/* ECMA-262 v5, 13.2, 16-18 */
@@ -1616,39 +1656,66 @@ ecma_property_t *
ecma_op_external_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
ecma_string_t *property_name_p) /**< property's name */
{
- JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE))
{
return ecma_op_lazy_instantiate_prototype_object (object_p);
}
-#if ENABLED (JERRY_ESNEXT)
- if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH))
- {
- ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
- ecma_external_handler_t handler = ext_obj_p->u.external_handler_cb;
+ return NULL;
+} /* ecma_op_external_function_try_to_lazy_instantiate_property */
- if (handler == ecma_promise_then_finally_cb
- || handler == ecma_promise_catch_finally_cb
- || handler == ecma_promise_resolve_handler
- || handler == ecma_promise_reject_handler
- || handler == ecma_promise_all_handler_cb
- || handler == ecma_op_get_capabilities_executor_cb)
+#if ENABLED (JERRY_ESNEXT)
+/**
+ * Create specification defined properties for built-in native handlers.
+ *
+ * @return pointer property, if one was instantiated,
+ * NULL - otherwise.
+ */
+ecma_property_t *
+ecma_op_native_handler_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
+ ecma_string_t *property_name_p) /**< property's name */
+{
+ JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
+ && ecma_get_object_is_builtin (object_p));
+
+ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
+ ecma_property_t *prop_p = NULL;
+
+ if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME))
+ {
+ if ((ext_obj_p->u.native_handler.flags & ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED) == 0)
{
- ecma_property_t *value_prop_p;
ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
property_name_p,
ECMA_PROPERTY_FLAG_CONFIGURABLE,
- &value_prop_p);
- value_p->value = ecma_make_uint32_value (handler == ecma_op_get_capabilities_executor_cb ? 2 : 1);
- return value_prop_p;
+ &prop_p);
+
+ value_p->value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
+
+ ext_obj_p->u.native_handler.flags |= ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED;
}
}
-#endif /* ENABLED (JERRY_ESNEXT) */
+ else if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH))
+ {
+ if ((ext_obj_p->u.native_handler.flags & ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED) == 0)
+ {
+ ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
+ property_name_p,
+ ECMA_PROPERTY_FLAG_CONFIGURABLE,
+ &prop_p);
- return NULL;
-} /* ecma_op_external_function_try_to_lazy_instantiate_property */
+ const uint8_t length = ecma_builtin_handler_get_length (ext_obj_p->u.native_handler.id);
+ value_p->value = ecma_make_integer_value (length);
+
+ ext_obj_p->u.native_handler.flags |= ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED;
+ }
+ }
+
+ return prop_p;
+} /* ecma_op_native_handler_try_to_lazy_instantiate_property */
+#endif /* ENABLED (JERRY_ESNEXT) */
/**
* Create specification defined non-configurable properties for bound functions.
@@ -1826,6 +1893,37 @@ ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /**
}
} /* ecma_op_external_function_list_lazy_property_names */
+#if ENABLED (JERRY_ESNEXT)
+/**
+ * List names of an Built-in native handler object's lazy instantiated properties,
+ * adding them to corresponding string collections
+ *
+ * See also:
+ * ecma_op_native_handler_try_to_lazy_instantiate_property
+ */
+void
+ecma_op_native_handler_list_lazy_property_names (ecma_object_t *object_p, /**< function object */
+ ecma_collection_t *prop_names_p, /**< prop name collection */
+ ecma_property_counter_t *prop_counter_p) /**< prop counter */
+{
+ JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
+ && ecma_get_object_is_builtin (object_p));
+ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
+
+ if ((ext_obj_p->u.native_handler.flags & ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED) == 0)
+ {
+ ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_NAME));
+ prop_counter_p->string_named_props++;
+ }
+
+ if ((ext_obj_p->u.native_handler.flags & ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED) == 0)
+ {
+ ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
+ prop_counter_p->string_named_props++;
+ }
+} /* ecma_op_native_handler_list_lazy_property_names */
+#endif /* ENABLED (JERRY_ESNEXT) */
+
/**
* List names of a Bound Function object's lazy instantiated properties,
* adding them to corresponding string collections
diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h
index 6aa6c5bdc..bbc4fb9ea 100644
--- a/jerry-core/ecma/operations/ecma-function-object.h
+++ b/jerry-core/ecma/operations/ecma-function-object.h
@@ -18,6 +18,7 @@
#include "ecma-globals.h"
#include "ecma-builtins.h"
+#include "ecma-builtin-handlers.h"
#include "vm.h"
/** \addtogroup ecma ECMA
@@ -40,7 +41,7 @@ ecma_object_t *
ecma_op_create_simple_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
ecma_object_t *
-ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
+ecma_op_create_external_function_object (ecma_native_handler_t handler_cb);
const ecma_compiled_code_t *
ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p);
@@ -60,6 +61,18 @@ ecma_op_create_any_function_object (ecma_object_t *scope_p, const ecma_compiled_
ecma_object_t *
ecma_op_create_arrow_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p,
ecma_value_t this_binding);
+
+ecma_object_t *
+ecma_op_create_native_handler (ecma_native_handler_id_t id, size_t object_size);
+
+ecma_property_t *
+ecma_op_native_handler_try_to_lazy_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
+
+void
+ecma_op_native_handler_list_lazy_property_names (ecma_object_t *object_p,
+ ecma_collection_t *prop_names_p,
+ ecma_property_counter_t *prop_counter_p);
+
bool
ecma_op_function_is_generator (ecma_object_t *func_obj_p);
#endif /* ENABLED (JERRY_ESNEXT) */
diff --git a/jerry-core/ecma/operations/ecma-jobqueue.c b/jerry-core/ecma/operations/ecma-jobqueue.c
index 0b1f2153f..2b6b8fab6 100644
--- a/jerry-core/ecma/operations/ecma-jobqueue.c
+++ b/jerry-core/ecma/operations/ecma-jobqueue.c
@@ -360,23 +360,13 @@ ecma_process_promise_async_generator_job (ecma_job_promise_async_generator_t *jo
static ecma_value_t
ecma_process_promise_resolve_thenable_job (ecma_job_promise_resolve_thenable_t *job_p) /**< the job to be operated */
{
- ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
- ecma_promise_resolving_functions_t funcs;
- ecma_promise_create_resolving_functions (promise_p, &funcs, true);
+ ecma_promise_object_t *promise_p = (ecma_promise_object_t *) ecma_get_object_from_value (job_p->promise);
+ ecma_promise_create_resolving_functions (promise_p);
- ecma_string_t *str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
- ecma_string_t *str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
+ uint16_t new_flags = (uint16_t) (promise_p->header.u.class_prop.extra_info & ~ECMA_PROMISE_ALREADY_RESOLVED);
+ promise_p->header.u.class_prop.extra_info = new_flags;
- ecma_op_object_put (promise_p,
- str_resolve_p,
- funcs.resolve,
- false);
- ecma_op_object_put (promise_p,
- str_reject_p,
- funcs.reject,
- false);
-
- ecma_value_t argv[] = { funcs.resolve, funcs.reject };
+ ecma_value_t argv[] = { promise_p->resolve, promise_p->reject };
ecma_value_t ret;
ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then),
job_p->thenable,
@@ -389,7 +379,7 @@ ecma_process_promise_resolve_thenable_job (ecma_job_promise_resolve_thenable_t *
{
then_call_result = jcontext_take_exception ();
- ret = ecma_op_function_call (ecma_get_object_from_value (funcs.reject),
+ ret = ecma_op_function_call (ecma_get_object_from_value (promise_p->reject),
ECMA_VALUE_UNDEFINED,
&then_call_result,
1);
@@ -397,7 +387,6 @@ ecma_process_promise_resolve_thenable_job (ecma_job_promise_resolve_thenable_t *
ecma_free_value (then_call_result);
}
- ecma_promise_free_resolving_functions (&funcs);
ecma_free_promise_resolve_thenable_job (job_p);
return ret;
diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c
index 097bc7954..faa7ced70 100644
--- a/jerry-core/ecma/operations/ecma-objects.c
+++ b/jerry-core/ecma/operations/ecma-objects.c
@@ -246,6 +246,12 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
{
property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p);
}
+#if ENABLED (JERRY_ESNEXT)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
+ {
+ property_p = ecma_op_native_handler_try_to_lazy_instantiate_property (object_p, property_name_p);
+ }
+#endif /* !ENABLED (JERRY_ESNEXT) */
else
{
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
@@ -284,7 +290,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
/* Get prototype physical property. */
property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
- else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
{
property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
@@ -556,6 +562,12 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
{
property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p);
}
+#if ENABLED (JERRY_ESNEXT)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
+ {
+ property_p = ecma_op_native_handler_try_to_lazy_instantiate_property (object_p, property_name_p);
+ }
+#endif /* !ENABLED (JERRY_ESNEXT) */
else
{
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
@@ -589,7 +601,7 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
/* Get prototype physical property. */
property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
- else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
{
property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
@@ -1298,6 +1310,12 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
{
property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p);
}
+#if ENABLED (JERRY_ESNEXT)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
+ {
+ property_p = ecma_op_native_handler_try_to_lazy_instantiate_property (object_p, property_name_p);
+ }
+#endif /* !ENABLED (JERRY_ESNEXT) */
else
{
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
@@ -1322,7 +1340,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
/* Get prototype physical property. */
property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
- else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
{
property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p);
}
@@ -1584,7 +1602,7 @@ ecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */
* [ECMA_OBJECT_TYPE_GENERAL] = &ecma_op_general_object_default_value,
* [ECMA_OBJECT_TYPE_CLASS] = &ecma_op_general_object_default_value,
* [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_default_value,
- * [ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION] = &ecma_op_general_object_default_value,
+ * [ECMA_OBJECT_TYPE_NATIVE_FUNCTION] = &ecma_op_general_object_default_value,
* [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value,
* [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value,
* [ECMA_OBJECT_TYPE_PSEUDO_ARRAY] = &ecma_op_general_object_default_value
@@ -1629,7 +1647,7 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
case ECMA_OBJECT_TYPE_GENERAL:
case ECMA_OBJECT_TYPE_CLASS:
case ECMA_OBJECT_TYPE_FUNCTION:
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
return ecma_op_general_object_define_own_property (obj_p,
@@ -2023,6 +2041,12 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */
{
ecma_builtin_routine_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p);
}
+#if ENABLED (JERRY_ESNEXT)
+ else if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
+ {
+ ecma_op_native_handler_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p);
+ }
+#endif /* !ENABLED (JERRY_ESNEXT) */
else
{
ecma_builtin_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p);
@@ -2047,7 +2071,7 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */
ecma_op_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p);
break;
}
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
ecma_op_external_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p);
break;
@@ -2551,7 +2575,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
break;
}
case ECMA_OBJECT_TYPE_FUNCTION:
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
+ case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
{
return LIT_MAGIC_STRING_FUNCTION_UL;
diff --git a/jerry-core/ecma/operations/ecma-promise-object.c b/jerry-core/ecma/operations/ecma-promise-object.c
index e8bd9a41a..5f3d92fca 100644
--- a/jerry-core/ecma/operations/ecma-promise-object.c
+++ b/jerry-core/ecma/operations/ecma-promise-object.c
@@ -17,6 +17,7 @@
#include "ecma-array-object.h"
#include "ecma-boolean-object.h"
#include "ecma-builtins.h"
+#include "ecma-builtin-handlers.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
@@ -174,31 +175,10 @@ ecma_promise_trigger_reactions (ecma_collection_t *reactions, /**< lists of reac
*
* @return true if it was called before, false otherwise
*/
-static bool
-ecma_is_resolver_already_called (ecma_object_t *resolver_p, /**< resolver */
- ecma_object_t *promise_obj_p) /**< promise */
+static inline bool JERRY_ATTR_ALWAYS_INLINE
+ecma_is_resolver_already_called (ecma_object_t *promise_obj_p) /**< promise */
{
- ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
- ecma_property_t *property_p = ecma_find_named_property (resolver_p, str_already_resolved_p);
-
- if (property_p == NULL)
- {
- return (ecma_promise_get_flags (promise_obj_p) & ECMA_PROMISE_ALREADY_RESOLVED) != 0;
- }
-
- JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
-
- ecma_value_t already_resolved = ECMA_PROPERTY_VALUE_PTR (property_p)->value;
- ecma_object_t *object_p = ecma_get_object_from_value (already_resolved);
- JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS);
-
- ecma_extended_object_t *already_resolved_p = (ecma_extended_object_t *) object_p;
- JERRY_ASSERT (already_resolved_p->u.class_prop.class_id == LIT_MAGIC_STRING_BOOLEAN_UL);
-
- ecma_value_t current_value = already_resolved_p->u.class_prop.u.value;
- already_resolved_p->u.class_prop.u.value = ECMA_VALUE_TRUE;
-
- return current_value == ECMA_VALUE_TRUE;
+ return (ecma_promise_get_flags (promise_obj_p) & ECMA_PROMISE_ALREADY_RESOLVED) != 0;
} /* ecma_is_resolver_already_called */
/**
@@ -304,26 +284,23 @@ ecma_promise_reject_handler (const ecma_value_t function, /**< the function itse
const uint32_t argc) /**< argument number */
{
JERRY_UNUSED (this);
+ ecma_promise_resolver_t *function_p = (ecma_promise_resolver_t *) ecma_get_object_from_value (function);
- ecma_object_t *function_p = ecma_get_object_from_value (function);
- /* 2. */
- ecma_value_t promise = ecma_op_object_get_by_magic_id (function_p, LIT_INTERNAL_MAGIC_STRING_PROMISE);
/* 1. */
- ecma_object_t *promise_obj_p = ecma_get_object_from_value (promise);
+ ecma_object_t *promise_obj_p = ecma_get_object_from_value (function_p->promise);
JERRY_ASSERT (ecma_is_promise (promise_obj_p));
/* 3., 4. */
- if (!ecma_is_resolver_already_called (function_p, promise_obj_p))
+ if (!ecma_is_resolver_already_called (promise_obj_p))
{
/* 5. */
((ecma_extended_object_t *) promise_obj_p)->u.class_prop.extra_info |= ECMA_PROMISE_ALREADY_RESOLVED;
/* 6. */
ecma_value_t reject_value = (argc == 0) ? ECMA_VALUE_UNDEFINED : argv[0];
- ecma_reject_promise (promise, reject_value);
+ ecma_reject_promise (function_p->promise, reject_value);
}
- ecma_free_value (promise);
return ECMA_VALUE_UNDEFINED;
} /* ecma_promise_reject_handler */
@@ -341,25 +318,21 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
const uint32_t argc) /**< argument number */
{
JERRY_UNUSED (this);
+ ecma_promise_resolver_t *function_p = (ecma_promise_resolver_t *) ecma_get_object_from_value (function);
- ecma_object_t *function_p = ecma_get_object_from_value (function);
- /* 2. */
- ecma_value_t promise = ecma_op_object_get_by_magic_id (function_p, LIT_INTERNAL_MAGIC_STRING_PROMISE);
/* 1. */
- ecma_object_t *promise_obj_p = ecma_get_object_from_value (promise);
+ ecma_object_t *promise_obj_p = ecma_get_object_from_value (function_p->promise);
JERRY_ASSERT (ecma_is_promise (promise_obj_p));
/* 3., 4. */
- if (!ecma_is_resolver_already_called (function_p, promise_obj_p))
+ if (!ecma_is_resolver_already_called (promise_obj_p))
{
/* 5. */
((ecma_extended_object_t *) promise_obj_p)->u.class_prop.extra_info |= ECMA_PROMISE_ALREADY_RESOLVED;
- ecma_fulfill_promise (promise, (argc == 0) ? ECMA_VALUE_UNDEFINED : argv[0]);
+ ecma_fulfill_promise (function_p->promise, (argc == 0) ? ECMA_VALUE_UNDEFINED : argv[0]);
}
- ecma_free_value (promise);
-
return ECMA_VALUE_UNDEFINED;
} /* ecma_promise_resolve_handler */
@@ -370,19 +343,16 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
*
* @return pointer to the resolving function
*/
-static ecma_value_t
-ecma_promise_create_resolving_functions_helper (ecma_object_t *obj_p, /**< Promise Object */
- ecma_external_handler_t handler_cb) /**< Callback handler */
+static ecma_object_t *
+ecma_promise_create_resolving_functions_helper (ecma_object_t *promise_p, /**< Promise Object */
+ ecma_native_handler_id_t id) /**< Callback handler */
{
- ecma_string_t *str_promise_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE);
- ecma_object_t *func_obj_p = ecma_op_create_external_function_object (handler_cb);
+ ecma_object_t *func_obj_p = ecma_op_create_native_handler (id, sizeof (ecma_promise_resolver_t));
- ecma_op_object_put (func_obj_p,
- str_promise_p,
- ecma_make_object_value (obj_p),
- false);
+ ecma_promise_resolver_t *resolver_p = (ecma_promise_resolver_t *) func_obj_p;
+ resolver_p->promise = ecma_make_object_value (promise_p);
- return ecma_make_object_value (func_obj_p);
+ return func_obj_p;
} /* ecma_promise_create_resolving_functions_helper */
/**
@@ -393,51 +363,21 @@ ecma_promise_create_resolving_functions_helper (ecma_object_t *obj_p, /**< Promi
* @return pointer to the resolving functions
*/
void
-ecma_promise_create_resolving_functions (ecma_object_t *object_p, /**< the promise object */
- ecma_promise_resolving_functions_t *funcs, /**< [out] resolving functions */
- bool create_already_resolved) /**< create already resolved flag */
+ecma_promise_create_resolving_functions (ecma_promise_object_t *promise_p) /**< the promise object */
{
- /* 2. - 4. */
- funcs->resolve = ecma_promise_create_resolving_functions_helper (object_p,
- ecma_promise_resolve_handler);
+ /* 2. - 7. */
+ ecma_object_t *resolve_func_p = ecma_promise_create_resolving_functions_helper ((ecma_object_t *) promise_p,
+ ECMA_NATIVE_HANDLER_PROMISE_RESOLVE);
+ ecma_object_t *reject_func_p = ecma_promise_create_resolving_functions_helper ((ecma_object_t *) promise_p,
+ ECMA_NATIVE_HANDLER_PROMISE_REJECT);
- /* 5. - 7. */
- funcs->reject = ecma_promise_create_resolving_functions_helper (object_p,
- ecma_promise_reject_handler);
- if (!create_already_resolved)
- {
- return;
- }
+ promise_p->resolve = ecma_make_object_value (resolve_func_p);
+ promise_p->reject = ecma_make_object_value (reject_func_p);
- ecma_value_t already_resolved = ecma_op_create_boolean_object (ECMA_VALUE_FALSE);
- ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
- ecma_property_value_t *value_p;
-
- value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs->resolve),
- str_already_resolved_p,
- ECMA_PROPERTY_FIXED,
- NULL);
- value_p->value = already_resolved;
-
- value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs->reject),
- str_already_resolved_p,
- ECMA_PROPERTY_FIXED,
- NULL);
- value_p->value = already_resolved;
-
- ecma_free_value (already_resolved);
+ ecma_deref_object (resolve_func_p);
+ ecma_deref_object (reject_func_p);
} /* ecma_promise_create_resolving_functions */
-/**
- * Free the heap and the member of the resolving functions.
- */
-void
-ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs) /**< points to the functions */
-{
- ecma_free_value (funcs->resolve);
- ecma_free_value (funcs->reject);
-} /* ecma_promise_free_resolving_functions */
-
/**
* Create a promise object.
*
@@ -473,25 +413,15 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
/* 5 */
ext_object_p->u.class_prop.extra_info = ECMA_PROMISE_IS_PENDING;
ext_object_p->u.class_prop.u.value = ECMA_VALUE_UNDEFINED;
+
+ /* 6-8. */
ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) object_p;
-
- /* 6-7. */
promise_object_p->reactions = reactions;
- /* 8. */
- ecma_promise_resolving_functions_t funcs;
- ecma_promise_create_resolving_functions (object_p, &funcs, false);
+ /* Creating the resolving function may trigger a GC, so these need to be initialized. */
+ promise_object_p->resolve = ECMA_VALUE_EMPTY;
+ promise_object_p->reject = ECMA_VALUE_EMPTY;
- ecma_string_t *str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
- ecma_string_t *str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
-
- ecma_op_object_put (object_p,
- str_resolve_p,
- funcs.resolve,
- false);
- ecma_op_object_put (object_p,
- str_reject_p,
- funcs.reject,
- false);
+ ecma_promise_create_resolving_functions (promise_object_p);
/* 9. */
ecma_value_t completion = ECMA_VALUE_UNDEFINED;
@@ -500,7 +430,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
{
JERRY_ASSERT (ecma_op_is_callable (executor));
- ecma_value_t argv[] = { funcs.resolve, funcs.reject };
+ ecma_value_t argv[] = { promise_object_p->resolve, promise_object_p->reject };
completion = ecma_op_function_call (ecma_get_object_from_value (executor),
ECMA_VALUE_UNDEFINED,
argv,
@@ -518,13 +448,12 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
{
/* 10.a. */
completion = jcontext_take_exception ();
- status = ecma_op_function_call (ecma_get_object_from_value (funcs.reject),
+ status = ecma_op_function_call (ecma_get_object_from_value (promise_object_p->reject),
ECMA_VALUE_UNDEFINED,
&completion,
1);
}
- ecma_promise_free_resolving_functions (&funcs);
ecma_free_value (completion);
/* 10.b. */
@@ -700,13 +629,11 @@ ecma_promise_new_capability (ecma_value_t constructor)
capability_p->reject = ECMA_VALUE_UNDEFINED;
/* 4-5. */
- ecma_object_t *executor_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_promise_capability_executor_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ ecma_object_t *executor_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_CAPABILITY_EXECUTOR,
+ sizeof (ecma_promise_capability_executor_t));
/* 6. */
ecma_promise_capability_executor_t *executor_func_p = (ecma_promise_capability_executor_t *) executor_p;
- executor_func_p->header.u.external_handler_cb = ecma_op_get_capabilities_executor_cb;
executor_func_p->capability = ecma_make_object_value (capability_obj_p);
/* 7. */
@@ -999,8 +926,8 @@ ecma_value_thunk_thrower_cb (const ecma_value_t function_obj, /**< the function
* @return ecma value
*/
static ecma_value_t
-ecma_promise_than_catch_finally_helper (ecma_value_t function_obj, /**< the function itself */
- ecma_external_handler_t ext_func_obj, /**< external function object */
+ecma_promise_then_catch_finally_helper (ecma_value_t function_obj, /**< the function itself */
+ ecma_native_handler_id_t id, /**< handler id */
ecma_value_t arg) /**< callback function argument */
{
/* 2. */
@@ -1036,13 +963,9 @@ ecma_promise_than_catch_finally_helper (ecma_value_t function_obj, /**< the fun
/* 8. */
ecma_object_t *value_thunk_func_p;
- value_thunk_func_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_promise_value_thunk_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ value_thunk_func_p = ecma_op_create_native_handler (id, sizeof (ecma_promise_value_thunk_t));
ecma_promise_value_thunk_t *value_thunk_func_obj = (ecma_promise_value_thunk_t *) value_thunk_func_p;
- value_thunk_func_obj->header.u.external_handler_cb = ext_func_obj;
-
value_thunk_func_obj->value = ecma_copy_value_if_not_object (arg);
/* 9. */
@@ -1053,7 +976,7 @@ ecma_promise_than_catch_finally_helper (ecma_value_t function_obj, /**< the fun
ecma_deref_object (value_thunk_func_p);
return ret_value;
-} /* ecma_promise_than_catch_finally_helper */
+} /* ecma_promise_then_catch_finally_helper */
/**
* Definition of Then Finally Function
@@ -1072,7 +995,7 @@ ecma_promise_then_finally_cb (const ecma_value_t function_obj, /**< the function
JERRY_UNUSED_2 (this_val, args_count);
JERRY_ASSERT (args_count > 0);
- return ecma_promise_than_catch_finally_helper (function_obj, ecma_value_thunk_helper_cb, args_p[0]);
+ return ecma_promise_then_catch_finally_helper (function_obj, ECMA_NATIVE_HANDLER_VALUE_THUNK, args_p[0]);
} /* ecma_promise_then_finally_cb */
/**
@@ -1092,7 +1015,7 @@ ecma_promise_catch_finally_cb (const ecma_value_t function_obj, /**< the functio
JERRY_UNUSED_2 (this_val, args_count);
JERRY_ASSERT (args_count > 0);
- return ecma_promise_than_catch_finally_helper (function_obj, ecma_value_thunk_thrower_cb, args_p[0]);
+ return ecma_promise_then_catch_finally_helper (function_obj, ECMA_NATIVE_HANDLER_VALUE_THROWER, args_p[0]);
} /* ecma_promise_catch_finally_cb */
/**
@@ -1132,37 +1055,27 @@ ecma_promise_finally (ecma_value_t promise, /**< the promise which call 'finally
return ecma_op_invoke_by_magic_id (promise, LIT_MAGIC_STRING_THEN, invoke_args, 2);
}
- /* 6. a,b */
+ /* 6.a-b */
ecma_object_t *then_finally_obj_p;
- then_finally_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_promise_finally_function_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ then_finally_obj_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_THEN_FINALLY,
+ sizeof (ecma_promise_finally_function_t));
- ecma_promise_finally_function_t *then_finally_func_obj = (ecma_promise_finally_function_t *) then_finally_obj_p;
- then_finally_func_obj->header.u.external_handler_cb = ecma_promise_then_finally_cb;
+ /* 6.c-d */
+ ecma_promise_finally_function_t *then_finally_func_obj_p = (ecma_promise_finally_function_t *) then_finally_obj_p;
+ then_finally_func_obj_p->constructor = species;
+ then_finally_func_obj_p->on_finally = on_finally;
- /* 6.c */
- then_finally_func_obj->constructor = species;
-
- /* 6.d*/
- then_finally_func_obj->on_finally = on_finally;
-
- /* 6. e,f */
+ /* 6.e-f */
ecma_object_t *catch_finally_obj_p;
- catch_finally_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_promise_finally_function_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ catch_finally_obj_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROMISE_CATCH_FINALLY,
+ sizeof (ecma_promise_finally_function_t));
+ /* 6.g-h */
ecma_promise_finally_function_t *catch_finally_func_obj = (ecma_promise_finally_function_t *) catch_finally_obj_p;
- catch_finally_func_obj->header.u.external_handler_cb = ecma_promise_catch_finally_cb;
-
- /* 6.g */
catch_finally_func_obj->constructor = species;
-
- /* 6.h */
catch_finally_func_obj->on_finally = on_finally;
- ecma_free_value (species);
+ ecma_deref_object (ecma_get_object_from_value (species));
/* 7. */
ecma_value_t invoke_args[2] =
diff --git a/jerry-core/ecma/operations/ecma-promise-object.h b/jerry-core/ecma/operations/ecma-promise-object.h
index 33faf8b08..6d9bff549 100644
--- a/jerry-core/ecma/operations/ecma-promise-object.h
+++ b/jerry-core/ecma/operations/ecma-promise-object.h
@@ -46,13 +46,13 @@ typedef enum
} ecma_promise_executor_type_t;
/**
- * Description of the promise resolving functions.
+ * Description of a promise resolving function.
*/
typedef struct
{
- ecma_value_t resolve; /**< the resolve function */
- ecma_value_t reject; /**< the reject function */
-} ecma_promise_resolving_functions_t;
+ ecma_extended_object_t header;
+ ecma_value_t promise;
+} ecma_promise_resolver_t;
/**
* Description of the promise object.
@@ -62,6 +62,8 @@ typedef struct
{
ecma_extended_object_t header; /**< extended object part */
ecma_collection_t *reactions; /**< list of promise reactions */
+ ecma_value_t resolve; /**< resolve function */
+ ecma_value_t reject; /**< reject function */
} ecma_promise_object_t;
/**
@@ -139,9 +141,7 @@ ecma_promise_resolve_handler (const ecma_value_t function,
ecma_value_t ecma_promise_finally (ecma_value_t promise, ecma_value_t on_finally);
void ecma_promise_async_then (ecma_value_t promise, ecma_value_t executable_object);
ecma_value_t ecma_promise_async_await (ecma_extended_object_t *async_generator_object_p, ecma_value_t value);
-void ecma_promise_create_resolving_functions (ecma_object_t *object_p, ecma_promise_resolving_functions_t *funcs,
- bool create_already_resolved);
-void ecma_promise_free_resolving_functions (ecma_promise_resolving_functions_t *funcs);
+void ecma_promise_create_resolving_functions (ecma_promise_object_t *object_p);
uint32_t ecma_promise_remaining_inc_or_dec (ecma_value_t remaining, bool is_inc);
ecma_value_t ecma_promise_all_handler_cb (const ecma_value_t function_obj, const ecma_value_t this_val,
diff --git a/jerry-core/ecma/operations/ecma-proxy-object.c b/jerry-core/ecma/operations/ecma-proxy-object.c
index 016cb299d..848f25790 100644
--- a/jerry-core/ecma/operations/ecma-proxy-object.c
+++ b/jerry-core/ecma/operations/ecma-proxy-object.c
@@ -16,6 +16,7 @@
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtins.h"
+#include "ecma-builtin-handlers.h"
#include "ecma-builtin-object.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
@@ -165,13 +166,11 @@ ecma_proxy_create_revocable (ecma_value_t target, /**< target argument */
/* 3. */
ecma_object_t *func_obj_p;
- func_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
- sizeof (ecma_revocable_proxy_object_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ func_obj_p = ecma_op_create_native_handler (ECMA_NATIVE_HANDLER_PROXY_REVOKE,
+ sizeof (ecma_revocable_proxy_object_t));
- ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
- rev_proxy_p->header.u.external_handler_cb = ecma_proxy_revoke_cb;
/* 4. */
+ ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
rev_proxy_p->proxy = proxy_value;
ecma_property_value_t *prop_value_p;
diff --git a/jerry-core/lit/lit-magic-strings.h b/jerry-core/lit/lit-magic-strings.h
index db1420bb0..c4c19c9fd 100644
--- a/jerry-core/lit/lit-magic-strings.h
+++ b/jerry-core/lit/lit-magic-strings.h
@@ -32,14 +32,10 @@ typedef enum
#undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
/** @endcond */
LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< number of non-internal magic strings */
- LIT_INTERNAL_MAGIC_STRING_PROMISE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< [[Promise]] of promise
- * reject or resolve functions */
- LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED, /**< [[AlreadyResolved]] of promise reject or resolve functions */
- LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION, /**< the resolve funtion of the promise object */
- LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION, /**< the reject function of the promise object */
+ LIT_INTERNAL_MAGIC_API_INTERNAL = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< Used to add non-visible JS properties
+ * from the public API */
LIT_INTERNAL_MAGIC_STRING_ITERATOR_NEXT_INDEX, /**< [[%Iterator%NextIndex]] property */
LIT_INTERNAL_MAGIC_STRING_MAP_KEY, /**< Property key used when an object is a key in a map object */
- LIT_INTERNAL_MAGIC_API_INTERNAL, /**< Property key used to add non-visible JS properties from the public API */
LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, /**< %ArrayProto_values% intrinsic routine */
LIT_INTERNAL_MAGIC_STRING_TYPEDARRAY_PROTOTYPE_VALUES, /**< %TypedArray%.prototype values and [@@iterator] routine */
LIT_INTERNAL_MAGIC_STRING_SET_PROTOTYPE_VALUES, /**< Set.prototype values, keys and [@@iterator] routines */
diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c
index 656f4fdf9..7bc3bb367 100644
--- a/jerry-core/vm/opcodes.c
+++ b/jerry-core/vm/opcodes.c
@@ -1164,7 +1164,7 @@ opfunc_create_implicit_class_constructor (uint8_t opcode) /**< current cbc opcod
/* 8. */
ecma_object_t *func_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
sizeof (ecma_extended_object_t),
- ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c
index e02e816b9..c15c95538 100644
--- a/jerry-core/vm/vm.c
+++ b/jerry-core/vm/vm.c
@@ -2184,7 +2184,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ECMA_PROPERTY_FLAG_CONFIGURABLE,
NULL);
- if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+ if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_NATIVE_FUNCTION)
{
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (((ecma_extended_object_t *) func_obj_p)->u.function.scope_cp);
}
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 822d7fe12..a016c6dd8 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -820,9 +820,6 @@
-
-
-
@@ -921,26 +918,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -983,9 +966,6 @@
-
-
-