diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md
index ab43cb8e3..7ee5bc086 100644
--- a/docs/02.API-REFERENCE.md
+++ b/docs/02.API-REFERENCE.md
@@ -164,10 +164,10 @@ Container object types:
Well-known symbols:
+ - JERRY_SYMBOL_ASYNC_ITERATOR - @@asyncIterator well-known symbol
- JERRY_SYMBOL_HAS_INSTANCE - @@hasInstance well-known symbol
- JERRY_SYMBOL_IS_CONCAT_SPREADABLE - @@isConcatSpreadable well-known symbol
- JERRY_SYMBOL_ITERATOR - @@iterator well-known symbol
- - JERRY_SYMBOL_ASYNC_ITERATOR - @@asyncIterator well-known symbol
- JERRY_SYMBOL_MATCH - @@match well-known symbol
- JERRY_SYMBOL_REPLACE - @@replace well-known symbol
- JERRY_SYMBOL_SEARCH - @@search well-known symbol
@@ -9118,6 +9118,59 @@ main (int argc, char** argv)
- [jerry_construct_object](#jerry_construct_object)
+## jerry_set_realm
+
+**Summary**
+
+Replaces the currently active realm (including the global object) with another realm.
+The replacement should be temporary, and the original realm must be restored after
+the tasks are completed. During the replacement, the realm must be referenced
+by the application (i.e. the gc must not reclaim it). This is also true to
+the returned previously active realm, so there is no need to free the value
+after the restoration. The function can only fail if realms are not supported
+or the passed argument is not a realm. In this case the returned exception must
+be freed by [jerry_release_value](#jerry_release_value).
+
+This function is useful to parse a script, create a native function, load a snapshot
+or create an exception in another realm. Each ECMAScript code runs in the realm
+which was active when the code was parsed or loaded regardless of the current realm.
+
+*Notes*:
+- This feature depends on build option (`JERRY_BUILTIN_REALMS`) and can be checked
+ in runtime with the `JERRY_FEATURE_REALM` feature enum value,
+ see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
+
+**Prototype**
+
+```c
+jerry_value_t
+jerry_set_realm (jerry_value_t realm_value);
+```
+- `realm_value` - the new realm value
+- return
+ - previous realm value - if the passed value is a realm
+ - exception - otherwise
+
+*New in version [[NEXT_RELEASE]]*.
+
+**Example**
+
+```c
+{
+ jerry_value_t realm_value = jerry_create_realm ();
+
+ jerry_value_t old_realm = jerry_set_realm (realm_value);
+
+ ... // usage of the realm
+
+ jerry_set_realm (old_realm);
+}
+```
+
+**See also**
+
+- [jerry_create_realm](#jerry_create_realm)
+
# ArrayBuffer and TypedArray functions
These APIs all depend on the es.next profile.
diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c
index a4b3a3cb9..1a80269fb 100644
--- a/jerry-core/api/jerry.c
+++ b/jerry-core/api/jerry.c
@@ -4204,7 +4204,7 @@ jerry_get_well_known_symbol (jerry_well_known_symbol_t symbol) /**< jerry_well_k
jerry_assert_api_available ();
#if ENABLED (JERRY_ESNEXT)
- lit_magic_string_id_t id = (lit_magic_string_id_t) (LIT_GLOBAL_SYMBOL__FISRT + symbol);
+ lit_magic_string_id_t id = (lit_magic_string_id_t) (LIT_GLOBAL_SYMBOL__FIRST + symbol);
if (!LIT_IS_GLOBAL_SYMBOL (id))
{
@@ -4564,6 +4564,44 @@ jerry_get_new_target (void)
#endif /* ENABLED (JERRY_ESNEXT) */
} /* jerry_get_new_target */
+/**
+ * Replaces the currently active realm with another realm.
+ *
+ * The replacement should be temporary, and the original realm must be
+ * restored after the tasks are completed. During the replacement, the
+ * realm must be referenced by the application (i.e. the gc must not
+ * reclaim it). This is also true to the returned previously active
+ * realm, so there is no need to free the value after the restoration.
+ *
+ * @return previous realm value - if the passed value is a realm
+ * exception - otherwise
+ */
+jerry_value_t
+jerry_set_realm (jerry_value_t realm_value) /**< jerry api value */
+{
+ jerry_assert_api_available ();
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ if (ecma_is_value_object (realm_value))
+ {
+ ecma_object_t *object_p = ecma_get_object_from_value (realm_value);
+
+ if (ecma_get_object_is_builtin (object_p)
+ && ecma_builtin_is_global (object_p))
+ {
+ ecma_global_object_t *previous_global_object_p = JERRY_CONTEXT (global_object_p);
+ JERRY_CONTEXT (global_object_p) = (ecma_global_object_t *) object_p;
+ return ecma_make_object_value ((ecma_object_t *) previous_global_object_p);
+ }
+ }
+
+ return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Passed argument is not a realm")));
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
+ JERRY_UNUSED (realm_value);
+ return jerry_throw (ecma_raise_reference_error (ECMA_ERR_MSG ("Realm is not available")));
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+} /* jerry_set_realm */
+
/**
* Check if the given value is an ArrayBuffer object.
*
diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c
index 50a624234..64186b591 100644
--- a/jerry-core/ecma/base/ecma-gc.c
+++ b/jerry-core/ecma/base/ecma-gc.c
@@ -936,13 +936,25 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
break;
}
-#if ENABLED (JERRY_ESNEXT)
+#if ENABLED (JERRY_ESNEXT) || ENABLED (JERRY_BUILTIN_REALMS)
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
+#endif /* ENABLED (JERRY_ESNEXT) || ENABLED (JERRY_BUILTIN_REALMS) */
+
+ if (!ecma_get_object_is_builtin (object_p))
+ {
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) object_p;
+ ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+ native_function_p->realm_value));
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+ break;
+ }
+
+#if ENABLED (JERRY_ESNEXT)
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
- if (ecma_get_object_is_builtin (object_p)
- && ext_func_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
+ if (ext_func_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
{
switch (ext_func_p->u.built_in.routine_id)
{
@@ -1005,10 +1017,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
}
}
}
+#endif /* ENABLED (JERRY_ESNEXT) */
+#if ENABLED (JERRY_ESNEXT) || ENABLED (JERRY_BUILTIN_REALMS)
break;
}
-#endif /* ENABLED (JERRY_ESNEXT) */
+#endif /* ENABLED (JERRY_ESNEXT) || ENABLED (JERRY_BUILTIN_REALMS) */
default:
{
break;
@@ -1496,6 +1510,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
}
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
{
+ ext_object_size = sizeof (ecma_native_function_t);
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 74af0237c..1b429b873 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -994,8 +994,6 @@ typedef struct
jmem_cpointer_tag_t target_function; /**< target function */
ecma_value_t args_len_or_this; /**< length of arguments or this value */
} bound_function;
-
- ecma_native_handler_t external_handler_cb; /**< external function */
} u;
} ecma_extended_object_t;
@@ -1014,6 +1012,18 @@ typedef struct
#define ECMA_BUILTIN_IS_EXTENDED_BUILT_IN(object_type) \
((object_type) == ECMA_OBJECT_TYPE_CLASS || (object_type) == ECMA_OBJECT_TYPE_ARRAY)
+/**
+ * Description of native functions
+ */
+typedef struct
+{
+ ecma_extended_object_t extended_object; /**< extended object part */
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ecma_value_t realm_value; /**< realm value */
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+ ecma_native_handler_t native_handler_cb; /**< external function */
+} ecma_native_function_t;
+
/**
* Flags for array.length_prop_and_hole_count
*/
diff --git a/jerry-core/ecma/base/ecma-init-finalize.c b/jerry-core/ecma/base/ecma-init-finalize.c
index 8acab129b..c522d54b2 100644
--- a/jerry-core/ecma/base/ecma-init-finalize.c
+++ b/jerry-core/ecma/base/ecma-init-finalize.c
@@ -88,6 +88,18 @@ ecma_finalize (void)
}
while (JERRY_CONTEXT (ecma_gc_new_objects) != 0);
+#if ENABLED (JERRY_ESNEXT)
+ jmem_cpointer_t *global_symbols_cp = JERRY_CONTEXT (global_symbols_cp);
+
+ for (uint32_t i = 0; i < ECMA_BUILTIN_GLOBAL_SYMBOL_COUNT; i++)
+ {
+ if (global_symbols_cp[i] != JMEM_CP_NULL)
+ {
+ ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, global_symbols_cp[i]));
+ }
+ }
+#endif /* ENABLED (JERRY_ESNEXT) */
+
ecma_finalize_lit_storage ();
} /* ecma_finalize */
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h
index 826f20aae..9302fd939 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h
@@ -190,12 +190,12 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
magic_string_id \
},
#if ENABLED (JERRY_ESNEXT)
-#define SYMBOL_VALUE(symbol, desc_magic_string_id) \
+#define SYMBOL_VALUE(name, symbol) \
{ \
- symbol, \
+ name, \
ECMA_BUILTIN_PROPERTY_SYMBOL, \
ECMA_PROPERTY_FIXED, \
- desc_magic_string_id \
+ symbol \
},
#define INTRINSIC_PROPERTY(name, magic_string_id, prop_attributes) \
{ \
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
index d0063f7c9..9803fcabc 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.inc.h
@@ -21,53 +21,6 @@
#if ENABLED (JERRY_ESNEXT)
-/* ECMA-262 v10, 19.4.2.1 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR,
- LIT_MAGIC_STRING_ASYNC_ITERATOR)
-
-/* ECMA-262 v6, 19.4.2.2 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_HAS_INSTANCE,
- LIT_MAGIC_STRING_HAS_INSTANCE)
-
-/* ECMA-262 v6, 19.4.2.3 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE,
- LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE)
-
-/* ECMA-262 v6, 19.4.2.4 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_ITERATOR,
- LIT_MAGIC_STRING_ITERATOR)
-
-/* ECMA-262 v6, 19.4.2.6 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_MATCH,
- LIT_MAGIC_STRING_MATCH)
-
-/* ECMA-262 v6, 19.4.2.8 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_REPLACE,
- LIT_MAGIC_STRING_REPLACE)
-
-/* ECMA-262 v6, 19.4.2.9 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SEARCH,
- LIT_MAGIC_STRING_SEARCH)
-
-/* ECMA-262 v6, 19.4.2.10 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPECIES,
- LIT_MAGIC_STRING_SPECIES)
-
-/* ECMA-262 v6, 19.4.2.11 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPLIT,
- LIT_MAGIC_STRING_SPLIT)
-
-/* ECMA-262 v6, 19.4.2.12 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_PRIMITIVE,
- LIT_MAGIC_STRING_TO_PRIMITIVE)
-
-/* ECMA-262 v6, 19.4.2.13 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
- LIT_MAGIC_STRING_TO_STRING_TAG)
-
-/* ECMA-262 v6, 19.4.2.14 */
-SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_UNSCOPABLES,
- LIT_MAGIC_STRING_UNSCOPABLES)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_ARRAY_PROTOTYPE_VALUES, 0, 0)
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h
index 840a91a36..111c82596 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.inc.h
@@ -42,64 +42,52 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v10, 19.4.2.1 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_ASYNC_ITERATOR,
- LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_ASYNC_ITERATOR,
+ LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR)
/* ECMA-262 v6, 19.4.2.2 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_HAS_INSTANCE,
- LIT_GLOBAL_SYMBOL_HAS_INSTANCE,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_HAS_INSTANCE,
+ LIT_GLOBAL_SYMBOL_HAS_INSTANCE)
/* ECMA-262 v6, 19.4.2.3 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE,
- LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE,
+ LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE)
/* ECMA-262 v6, 19.4.2.4 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_ITERATOR,
- LIT_GLOBAL_SYMBOL_ITERATOR,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_ITERATOR,
+ LIT_GLOBAL_SYMBOL_ITERATOR)
/* ECMA-262 v6, 19.4.2.6 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_MATCH,
- LIT_GLOBAL_SYMBOL_MATCH,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_MATCH,
+ LIT_GLOBAL_SYMBOL_MATCH)
/* ECMA-262 v6, 19.4.2.8 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_REPLACE,
- LIT_GLOBAL_SYMBOL_REPLACE,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_REPLACE,
+ LIT_GLOBAL_SYMBOL_REPLACE)
/* ECMA-262 v6, 19.4.2.9 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SEARCH,
- LIT_GLOBAL_SYMBOL_SEARCH,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_SEARCH,
+ LIT_GLOBAL_SYMBOL_SEARCH)
/* ECMA-262 v6, 19.4.2.10 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SPECIES,
- LIT_GLOBAL_SYMBOL_SPECIES,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_SPECIES,
+ LIT_GLOBAL_SYMBOL_SPECIES)
/* ECMA-262 v6, 19.4.2.11 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_SPLIT,
- LIT_GLOBAL_SYMBOL_SPLIT,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_SPLIT,
+ LIT_GLOBAL_SYMBOL_SPLIT)
/* ECMA-262 v6, 19.4.2.12 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TO_PRIMITIVE,
- LIT_GLOBAL_SYMBOL_TO_PRIMITIVE,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_TO_PRIMITIVE,
+ LIT_GLOBAL_SYMBOL_TO_PRIMITIVE)
/* ECMA-262 v6, 19.4.2.13 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_TO_STRING_TAG,
- LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_TO_STRING_TAG,
+ LIT_GLOBAL_SYMBOL_TO_STRING_TAG)
/* ECMA-262 v6, 19.4.2.14 */
-INTRINSIC_PROPERTY (LIT_MAGIC_STRING_UNSCOPABLES,
- LIT_GLOBAL_SYMBOL_UNSCOPABLES,
- ECMA_PROPERTY_FIXED)
+SYMBOL_VALUE (LIT_MAGIC_STRING_UNSCOPABLES,
+ LIT_GLOBAL_SYMBOL_UNSCOPABLES)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c
index 8ecad7ec8..38811155e 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtins.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c
@@ -668,6 +668,8 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, *builtin_p);
} /* ecma_builtin_get */
+#if ENABLED (JERRY_BUILTIN_REALMS)
+
/**
* Get reference to specified built-in object using the realm provided by another built-in object
*
@@ -676,14 +678,12 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
*
* @return pointer to the object's instance
*/
-static ecma_object_t *
-ecma_builtin_get_from_realm (ecma_object_t *builtin_object_p, /**< built-in object */
+ecma_object_t *
+ecma_builtin_get_from_realm (ecma_global_object_t *global_object_p, /**< global object */
ecma_builtin_id_t builtin_id) /**< id of built-in to check on */
{
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_OBJECTS_COUNT);
-#if ENABLED (JERRY_BUILTIN_REALMS)
- ecma_global_object_t *global_object_p = ecma_builtin_get_realm (builtin_object_p);
jmem_cpointer_t *builtin_p = global_object_p->builtin_objects + builtin_id;
if (JERRY_UNLIKELY (*builtin_p == JMEM_CP_NULL))
@@ -692,11 +692,31 @@ ecma_builtin_get_from_realm (ecma_object_t *builtin_object_p, /**< built-in obje
}
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, *builtin_p);
+} /* ecma_builtin_get_from_realm */
+
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+/**
+ * Get reference to specified built-in object using the realm provided by another built-in object
+ *
+ * Note:
+ * Does not increase the reference counter.
+ *
+ * @return pointer to the object's instance
+ */
+static inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
+ecma_builtin_get_from_builtin (ecma_object_t *builtin_object_p, /**< built-in object */
+ ecma_builtin_id_t builtin_id) /**< id of built-in to check on */
+{
+ JERRY_ASSERT (builtin_id < ECMA_BUILTIN_OBJECTS_COUNT);
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ return ecma_builtin_get_from_realm (ecma_builtin_get_realm (builtin_object_p), builtin_id);
#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
JERRY_UNUSED (builtin_object_p);
return ecma_builtin_get (builtin_id);
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
-} /* ecma_builtin_get_from_realm */
+} /* ecma_builtin_get_from_builtin */
/**
* Construct a Function object for specified built-in routine
@@ -712,8 +732,8 @@ ecma_builtin_make_function_object_for_routine (ecma_object_t *builtin_object_p,
uint32_t routine_index, /**< property descriptor index of routine */
uint8_t flags) /**< see also: ecma_builtin_routine_flags */
{
- ecma_object_t *prototype_obj_p = ecma_builtin_get_from_realm (builtin_object_p,
- ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
+ ecma_object_t *prototype_obj_p = ecma_builtin_get_from_builtin (builtin_object_p,
+ ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
size_t ext_object_size = sizeof (ecma_extended_object_t);
@@ -1169,20 +1189,14 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
#if ENABLED (JERRY_ESNEXT)
case ECMA_BUILTIN_PROPERTY_SYMBOL:
{
- ecma_string_t *symbol_dot_p = ecma_get_magic_string (LIT_MAGIC_STRING_SYMBOL_DOT_UL);
- ecma_string_t *name_p = ecma_get_magic_string ((lit_magic_string_id_t) curr_property_p->value);
- ecma_string_t *descriptor_p = ecma_concat_ecma_strings (symbol_dot_p, name_p);
+ lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->value;
- ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (ecma_make_string_value (descriptor_p));
- lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->magic_string_id;
- symbol_p->u.hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG);
-
- value = ecma_make_symbol_value (symbol_p);
+ value = ecma_make_symbol_value (ecma_op_get_global_symbol (symbol_id));
break;
}
case ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY:
{
- ecma_object_t *intrinsic_object_p = ecma_builtin_get_from_realm (object_p, ECMA_BUILTIN_ID_INTRINSIC_OBJECT);
+ ecma_object_t *intrinsic_object_p = ecma_builtin_get_from_builtin (object_p, ECMA_BUILTIN_ID_INTRINSIC_OBJECT);
value = ecma_op_object_get_by_magic_id (intrinsic_object_p, (lit_magic_string_id_t) curr_property_p->value);
break;
}
@@ -1191,8 +1205,8 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
is_accessor = true;
uint16_t getter_id = ECMA_ACCESSOR_READ_WRITE_GET_GETTER_ID (curr_property_p->value);
uint16_t setter_id = ECMA_ACCESSOR_READ_WRITE_GET_SETTER_ID (curr_property_p->value);
- getter_p = ecma_builtin_get_from_realm (object_p, getter_id);
- setter_p = ecma_builtin_get_from_realm (object_p, setter_id);
+ getter_p = ecma_builtin_get_from_builtin (object_p, getter_id);
+ setter_p = ecma_builtin_get_from_builtin (object_p, setter_id);
ecma_ref_object (getter_p);
ecma_ref_object (setter_p);
break;
@@ -1201,7 +1215,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
case ECMA_BUILTIN_PROPERTY_OBJECT:
{
ecma_object_t *builtin_object_p;
- builtin_object_p = ecma_builtin_get_from_realm (object_p, (ecma_builtin_id_t) curr_property_p->value);
+ builtin_object_p = ecma_builtin_get_from_builtin (object_p, (ecma_builtin_id_t) curr_property_p->value);
ecma_ref_object (builtin_object_p);
value = ecma_make_object_value (builtin_object_p);
break;
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h
index 86d17c325..ef3ffa043 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtins.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h
@@ -56,6 +56,12 @@ typedef enum
*/
#define ECMA_BUILTIN_ID_HANDLER ECMA_BUILTIN_ID__COUNT
+/**
+ * Number of global symbols
+ */
+#define ECMA_BUILTIN_GLOBAL_SYMBOL_COUNT \
+ (LIT_GLOBAL_SYMBOL__LAST - LIT_GLOBAL_SYMBOL__FIRST + 1)
+
#endif /* ENABLED (JERRY_ESNEXT) */
/**
@@ -143,4 +149,9 @@ ecma_builtin_get_global (void);
bool
ecma_builtin_function_is_routine (ecma_object_t *func_obj_p);
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ecma_object_t *
+ecma_builtin_get_from_realm (ecma_global_object_t *global_object_p, ecma_builtin_id_t builtin_id);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
#endif /* !ECMA_BUILTINS_H */
diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c
index df78dc3c5..084350daf 100644
--- a/jerry-core/ecma/operations/ecma-array-object.c
+++ b/jerry-core/ecma/operations/ecma-array-object.c
@@ -708,13 +708,22 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
return NULL;
}
- if (ecma_is_constructor (constructor)
- && ecma_get_object_from_value (constructor) == ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY))
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ if (ecma_is_constructor (constructor))
{
- ecma_free_value (constructor);
- constructor = ECMA_VALUE_UNDEFINED;
+ ecma_object_t *constructor_p = ecma_get_object_from_value (constructor);
+ ecma_global_object_t *global_object_p = ecma_op_function_get_function_realm (constructor_p);
+
+ if ((ecma_object_t *) global_object_p != ecma_builtin_get_global ()
+ && constructor_p == ecma_builtin_get_from_realm (global_object_p, ECMA_BUILTIN_ID_ARRAY))
+ {
+ ecma_deref_object (constructor_p);
+ constructor = ECMA_VALUE_UNDEFINED;
+ }
}
- else if (ecma_is_value_object (constructor))
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ if (ecma_is_value_object (constructor))
{
ecma_object_t *ctor_object_p = ecma_get_object_from_value (constructor);
constructor = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_GLOBAL_SYMBOL_SPECIES);
diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c
index 87f93a84a..064b98111 100644
--- a/jerry-core/ecma/operations/ecma-function-object.c
+++ b/jerry-core/ecma/operations/ecma-function-object.c
@@ -672,10 +672,9 @@ ecma_op_create_external_function_object (ecma_native_handler_t handler_cb) /**<
{
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_NATIVE_FUNCTION);
+ ecma_object_t *function_obj_p = ecma_create_object (prototype_obj_p,
+ sizeof (ecma_native_function_t),
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
/*
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_NATIVE_FUNCTION type.
@@ -683,8 +682,12 @@ ecma_op_create_external_function_object (ecma_native_handler_t handler_cb) /**<
* See also: ecma_object_get_class_name
*/
- ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
- ext_func_obj_p->u.external_handler_cb = handler_cb;
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) function_obj_p;
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ECMA_SET_INTERNAL_VALUE_POINTER (native_function_p->realm_value,
+ ecma_builtin_get_global ());
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+ native_function_p->native_handler_cb = handler_cb;
return function_obj_p;
} /* ecma_op_create_external_function_object */
@@ -782,6 +785,39 @@ ecma_op_function_get_realm (const ecma_compiled_code_t *bytecode_header_p) /**<
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
} /* ecma_op_function_get_realm */
+/**
+ * Get realm from a function
+ *
+ * Note:
+ * Does not increase the reference counter.
+ *
+ * @return realm (global) object
+ */
+ecma_global_object_t *
+ecma_op_function_get_function_realm (ecma_object_t *func_obj_p) /**< function object */
+{
+ if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
+ {
+ ecma_extended_object_t *ext_function_obj_p = (ecma_extended_object_t *) func_obj_p;
+ const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_function_obj_p);
+ ecma_value_t realm_value = ecma_op_function_get_realm (bytecode_data_p);
+ return (ecma_global_object_t *) ecma_get_object_from_value (realm_value);
+ }
+
+ JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
+
+ if (ecma_get_object_is_builtin (func_obj_p))
+ {
+ ecma_extended_object_t *ext_function_obj_p = (ecma_extended_object_t *) func_obj_p;
+ return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t,
+ ext_function_obj_p->u.built_in.realm_value);
+ }
+
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) func_obj_p;
+ return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t,
+ native_function_p->realm_value);
+} /* ecma_op_function_get_function_realm */
+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
/**
@@ -986,7 +1022,11 @@ ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< construc
}
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ proto_obj_p = ecma_builtin_get_from_realm (ecma_op_function_get_function_realm (ctor_obj_p), default_proto_id);
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
proto_obj_p = ecma_builtin_get (default_proto_id);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
ecma_ref_object (proto_obj_p);
}
else
@@ -1171,14 +1211,15 @@ ecma_op_function_call_native (ecma_object_t *func_obj_p, /**< Function object */
{
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;
if (ecma_get_object_is_builtin (func_obj_p))
{
#if ENABLED (JERRY_BUILTIN_REALMS)
ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
- ecma_value_t realm_value = ((ecma_extended_object_t *) func_obj_p)->u.built_in.realm_value;
- JERRY_CONTEXT (global_object_p) = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t, realm_value);
+
+ ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
+ JERRY_CONTEXT (global_object_p) = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t,
+ ext_func_obj_p->u.built_in.realm_value);
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
ecma_value_t ret_value = ecma_builtin_dispatch_call (func_obj_p,
@@ -1192,11 +1233,23 @@ ecma_op_function_call_native (ecma_object_t *func_obj_p, /**< Function object */
return ret_value;
}
- 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,
- arguments_list_len);
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) func_obj_p;
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p);
+ JERRY_CONTEXT (global_object_p) = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t,
+ native_function_p->realm_value);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ JERRY_ASSERT (native_function_p->native_handler_cb != NULL);
+ ecma_value_t ret_value = native_function_p->native_handler_cb (ecma_make_object_value (func_obj_p),
+ this_arg_value,
+ arguments_list_p,
+ arguments_list_len);
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ JERRY_CONTEXT (global_object_p) = saved_global_object_p;
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
{
ecma_raise_error_from_error_reference (ret_value);
@@ -1573,6 +1626,26 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
|| ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ecma_global_object_t *global_object_p;
+
+ if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
+ {
+ const ecma_compiled_code_t *bytecode_data_p;
+ bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
+
+ ecma_value_t realm_value = ecma_op_function_get_realm (bytecode_data_p);
+ global_object_p = (ecma_global_object_t *) ecma_get_object_from_value (realm_value);
+ }
+ else
+ {
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) object_p;
+
+ global_object_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t,
+ native_function_p->realm_value);
+ }
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
/* ECMA-262 v5, 13.2, 16-18 */
ecma_object_t *proto_object_p = NULL;
@@ -1590,17 +1663,29 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_GENERATOR)
{
- proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
- 0,
- ECMA_OBJECT_TYPE_GENERAL);
+ ecma_object_t *prototype_p;
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ prototype_p = ecma_builtin_get_from_realm (global_object_p, ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE);
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
+ prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ proto_object_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
init_constructor = false;
}
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ASYNC_GENERATOR)
{
- proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE),
- 0,
- ECMA_OBJECT_TYPE_GENERAL);
+ ecma_object_t *prototype_p;
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ prototype_p = ecma_builtin_get_from_realm (global_object_p, ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE);
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
+ prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ proto_object_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
init_constructor = false;
}
}
@@ -1610,7 +1695,15 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
if (proto_object_p == NULL)
#endif /* ENABLED (JERRY_ESNEXT) */
{
- proto_object_p = ecma_op_create_object_object_noarg ();
+ ecma_object_t *prototype_p;
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ prototype_p = ecma_builtin_get_from_realm (global_object_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
+#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
+ prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
+
+ proto_object_p = ecma_op_create_object_object_noarg_and_set_prototype (prototype_p);
}
/* 17. */
diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h
index 5223bd627..f1de6a25f 100644
--- a/jerry-core/ecma/operations/ecma-function-object.h
+++ b/jerry-core/ecma/operations/ecma-function-object.h
@@ -59,6 +59,9 @@ ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p);
#if ENABLED (JERRY_BUILTIN_REALMS)
ecma_value_t
ecma_op_function_get_realm (const ecma_compiled_code_t *bytecode_header_p);
+
+ecma_global_object_t *
+ecma_op_function_get_function_realm (ecma_object_t *func_obj_p);
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
ecma_value_t
diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c
index 78220af7b..327776915 100644
--- a/jerry-core/ecma/operations/ecma-objects.c
+++ b/jerry-core/ecma/operations/ecma-objects.c
@@ -882,6 +882,29 @@ ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */
} /* ecma_op_object_get_by_magic_id */
#if ENABLED (JERRY_ESNEXT)
+
+/**
+ * Descriptor string for each global symbol
+ */
+static const uint16_t ecma_global_symbol_descriptions[] =
+{
+ LIT_MAGIC_STRING_ASYNC_ITERATOR,
+ LIT_MAGIC_STRING_HAS_INSTANCE,
+ LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE,
+ LIT_MAGIC_STRING_ITERATOR,
+ LIT_MAGIC_STRING_MATCH,
+ LIT_MAGIC_STRING_REPLACE,
+ LIT_MAGIC_STRING_SEARCH,
+ LIT_MAGIC_STRING_SPECIES,
+ LIT_MAGIC_STRING_SPLIT,
+ LIT_MAGIC_STRING_TO_PRIMITIVE,
+ LIT_MAGIC_STRING_TO_STRING_TAG,
+ LIT_MAGIC_STRING_UNSCOPABLES
+};
+
+JERRY_STATIC_ASSERT (sizeof (ecma_global_symbol_descriptions) / sizeof (uint16_t) == ECMA_BUILTIN_GLOBAL_SYMBOL_COUNT,
+ ecma_global_symbol_descriptions_must_have_global_symbol_count_elements);
+
/**
* [[Get]] a well-known symbol by the given property id
*
@@ -890,11 +913,30 @@ ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */
ecma_string_t *
ecma_op_get_global_symbol (lit_magic_string_id_t property_id) /**< property symbol id */
{
- ecma_value_t symbol_value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_INTRINSIC_OBJECT),
- property_id);
- JERRY_ASSERT (ecma_is_value_symbol (symbol_value));
+ JERRY_ASSERT (LIT_IS_GLOBAL_SYMBOL (property_id));
- return ecma_get_symbol_from_value (symbol_value);
+ uint32_t symbol_index = (uint32_t) property_id - (uint32_t) LIT_GLOBAL_SYMBOL__FIRST;
+ jmem_cpointer_t symbol_cp = JERRY_CONTEXT (global_symbols_cp)[symbol_index];
+
+ if (symbol_cp != JMEM_CP_NULL)
+ {
+ ecma_string_t *symbol_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, symbol_cp);
+ ecma_ref_ecma_string (symbol_p);
+ return symbol_p;
+ }
+
+ ecma_string_t *symbol_dot_p = ecma_get_magic_string (LIT_MAGIC_STRING_SYMBOL_DOT_UL);
+ uint16_t description = ecma_global_symbol_descriptions[symbol_index];
+ ecma_string_t *name_p = ecma_get_magic_string ((lit_magic_string_id_t) description);
+ ecma_string_t *descriptor_p = ecma_concat_ecma_strings (symbol_dot_p, name_p);
+
+ ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (ecma_make_string_value (descriptor_p));
+ symbol_p->u.hash = (uint16_t) ((property_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG);
+
+ ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (global_symbols_cp)[symbol_index], symbol_p);
+
+ ecma_ref_ecma_string (symbol_p);
+ return symbol_p;
} /* ecma_op_get_global_symbol */
/**
diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h
index 60d3f1c7a..b0955d947 100644
--- a/jerry-core/include/jerryscript-core.h
+++ b/jerry-core/include/jerryscript-core.h
@@ -691,10 +691,10 @@ jerry_promise_state_t jerry_get_promise_state (const jerry_value_t promise);
*/
typedef enum
{
+ JERRY_SYMBOL_ASYNC_ITERATOR, /**< @@asyncIterator well-known symbol */
JERRY_SYMBOL_HAS_INSTANCE, /**< @@hasInstance well-known symbol */
JERRY_SYMBOL_IS_CONCAT_SPREADABLE, /**< @@isConcatSpreadable well-known symbol */
JERRY_SYMBOL_ITERATOR, /**< @@iterator well-known symbol */
- JERRY_SYMBOL_ASYNC_ITERATOR, /**< @@asyncIterator well-known symbol */
JERRY_SYMBOL_MATCH, /**< @@match well-known symbol */
JERRY_SYMBOL_REPLACE, /**< @@replace well-known symbol */
JERRY_SYMBOL_SEARCH, /**< @@search well-known symbol */
@@ -739,6 +739,7 @@ void jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, voi
jerry_value_t jerry_get_backtrace (uint32_t max_depth);
jerry_value_t jerry_get_resource_name (const jerry_value_t value);
jerry_value_t jerry_get_new_target (void);
+jerry_value_t jerry_set_realm (jerry_value_t realm_value);
/**
* Array buffer components.
diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h
index 43f8d4f31..eebd5906d 100644
--- a/jerry-core/jcontext/jcontext.h
+++ b/jerry-core/jcontext/jcontext.h
@@ -145,6 +145,9 @@ struct jerry_context_t
#if ENABLED (JERRY_BUILTIN_BIGINT)
jmem_cpointer_t bigint_list_first_cp; /**< first item of the literal bigint list */
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
+#if ENABLED (JERRY_ESNEXT)
+ jmem_cpointer_t global_symbols_cp[ECMA_BUILTIN_GLOBAL_SYMBOL_COUNT]; /**< global symbols */
+#endif /* ENABLED (JERRY_ESNEXT) */
#if ENABLED (JERRY_MODULE_SYSTEM)
ecma_module_t *ecma_modules_p; /**< list of referenced modules */
diff --git a/jerry-core/lit/lit-magic-strings.h b/jerry-core/lit/lit-magic-strings.h
index 670263c8e..0bcf9df20 100644
--- a/jerry-core/lit/lit-magic-strings.h
+++ b/jerry-core/lit/lit-magic-strings.h
@@ -42,11 +42,11 @@ typedef enum
LIT_INTERNAL_MAGIC_STRING_MAP_PROTOTYPE_ENTRIES, /**< Map.prototype entries and [@@iterator] routines */
LIT_INTERNAL_MAGIC_PROMISE_CAPABILITY, /**< PromiseCapability record */
/* List of well known symbols */
+ LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR, /**< @@asyncIterator well known symbol */
+ LIT_GLOBAL_SYMBOL__FIRST = LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR, /**< first global symbol */
LIT_GLOBAL_SYMBOL_HAS_INSTANCE, /**< @@hasInstance well known symbol */
- LIT_GLOBAL_SYMBOL__FISRT = LIT_GLOBAL_SYMBOL_HAS_INSTANCE, /**< first global symbol */
LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE, /**< @@isConcatSpreadable well known symbol */
LIT_GLOBAL_SYMBOL_ITERATOR, /**< @@iterator well known symbol */
- LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR, /**< @@asyncIterator well known symbol */
LIT_GLOBAL_SYMBOL_MATCH, /**< @@match well known symbol */
LIT_GLOBAL_SYMBOL_REPLACE, /**< @@replace well known symbol */
LIT_GLOBAL_SYMBOL_SEARCH, /**< @@search well known symbol */
@@ -73,7 +73,7 @@ typedef enum
/**
* Checks whether the given id corresponds to a global symbol
*/
-#define LIT_IS_GLOBAL_SYMBOL(id) ((id) >= LIT_GLOBAL_SYMBOL__FISRT && (id) <= LIT_GLOBAL_SYMBOL__LAST)
+#define LIT_IS_GLOBAL_SYMBOL(id) ((id) >= LIT_GLOBAL_SYMBOL__FIRST && (id) <= LIT_GLOBAL_SYMBOL__LAST)
/**
* Identifiers of implementation-defined external magic string constants
diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c
index 324d85195..1e6b5021b 100644
--- a/jerry-core/vm/opcodes.c
+++ b/jerry-core/vm/opcodes.c
@@ -1219,32 +1219,37 @@ ecma_value_t
opfunc_create_implicit_class_constructor (uint8_t opcode) /**< current cbc opcode */
{
/* 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_NATIVE_FUNCTION);
+ ecma_object_t *function_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
+ sizeof (ecma_native_function_t),
+ ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
- ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
+ ecma_native_function_t *native_function_p = (ecma_native_function_t *) function_obj_p;
+
+#if ENABLED (JERRY_BUILTIN_REALMS)
+ ECMA_SET_INTERNAL_VALUE_POINTER (native_function_p->realm_value,
+ ecma_builtin_get_global ());
+#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
/* 10.a.i */
if (opcode == CBC_EXT_PUSH_IMPLICIT_CONSTRUCTOR_HERITAGE)
{
- ext_func_obj_p->u.external_handler_cb = ecma_op_implicit_constructor_handler_heritage_cb;
+ native_function_p->native_handler_cb = ecma_op_implicit_constructor_handler_heritage_cb;
}
/* 10.b.i */
else
{
- ext_func_obj_p->u.external_handler_cb = ecma_op_implicit_constructor_handler_cb;
+ native_function_p->native_handler_cb = ecma_op_implicit_constructor_handler_cb;
}
ecma_property_value_t *prop_value_p;
- prop_value_p = ecma_create_named_data_property (func_obj_p,
+ prop_value_p = ecma_create_named_data_property (function_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
ECMA_PROPERTY_FLAG_CONFIGURABLE,
NULL);
prop_value_p->value = ecma_make_uint32_value (0);
- return ecma_make_object_value (func_obj_p);
+ return ecma_make_object_value (function_obj_p);
} /* opfunc_create_implicit_class_constructor */
/**
diff --git a/jerry-main/main-utils.c b/jerry-main/main-utils.c
index 8b6767c35..b108f1806 100644
--- a/jerry-main/main-utils.c
+++ b/jerry-main/main-utils.c
@@ -148,17 +148,50 @@ test262_eval_script (const jerry_value_t func_obj_val, /**< function object */
return ret_value;
} /* test262_eval_script */
+static jerry_value_t
+create_test262 (jerry_value_t global_obj);
+
/**
- * Init the $262 object
+ * $262.createRealm
+ *
+ * A function which creates a new realm object, and returns a newly created $262 object
+ *
+ * @return a new $262 object
*/
-static void
-register_test262 (void)
+static jerry_value_t
+test262_create_realm (const jerry_value_t func_obj_val, /**< function object */
+ const jerry_value_t this_p, /**< this arg */
+ const jerry_value_t args_p[], /**< function arguments */
+ const jerry_length_t args_cnt) /**< number of function arguments */
+{
+ (void) func_obj_val; /* unused */
+ (void) this_p; /* unused */
+ (void) args_p; /* unused */
+ (void) args_cnt; /* unused */
+
+ jerry_value_t realm_object = jerry_create_realm ();
+ jerry_value_t previous_realm = jerry_set_realm (realm_object);
+ assert (!jerry_value_is_error (previous_realm));
+ jerry_value_t test262_object = create_test262 (realm_object);
+ jerry_set_realm (previous_realm);
+ jerry_release_value (realm_object);
+
+ return test262_object;
+} /* test262_create_realm */
+
+/**
+ * Create a new $262 object
+ *
+ * @return a new $262 object
+ */
+static jerry_value_t
+create_test262 (jerry_value_t global_obj) /**< global object */
{
- jerry_value_t global_obj = jerry_get_global_object ();
jerry_value_t test262_object = jerry_create_object ();
test262_register_function (test262_object, "detachArrayBuffer", test262_detach_array_buffer);
test262_register_function (test262_object, "evalScript", test262_eval_script);
+ test262_register_function (test262_object, "createRealm", test262_create_realm);
test262_register_function (test262_object, "gc", jerryx_handler_gc);
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "global");
@@ -171,17 +204,16 @@ register_test262 (void)
jerry_release_value (prop_name);
assert (!jerry_value_is_error (result));
-
- jerry_release_value (global_obj);
- jerry_release_value (test262_object);
jerry_release_value (result);
-} /* register_test262 */
+
+ return test262_object;
+} /* create_test262 */
/**
* Inits the engine and the debugger
*/
void
-main_init_engine (main_args_t *arguments_p) /** main arguments */
+main_init_engine (main_args_t *arguments_p) /**< main arguments */
{
jerry_init (arguments_p->init_flags);
@@ -211,7 +243,10 @@ main_init_engine (main_args_t *arguments_p) /** main arguments */
}
if (arguments_p->option_flags & OPT_FLAG_TEST262_OBJECT)
{
- register_test262 ();
+ jerry_value_t global_obj = jerry_get_global_object ();
+ jerry_value_t test262_object = create_test262 (global_obj);
+ jerry_release_value (test262_object);
+ jerry_release_value (global_obj);
}
main_register_global_function ("assert", jerryx_handler_assert);
main_register_global_function ("gc", jerryx_handler_gc);
diff --git a/tests/jerry/es.next/realms4.js b/tests/jerry/es.next/realms4.js
new file mode 100644
index 000000000..02734f51c
--- /dev/null
+++ b/tests/jerry/es.next/realms4.js
@@ -0,0 +1,35 @@
+// 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 realm = createRealm()
+
+function compare(a, b)
+{
+ assert (a === b)
+ assert (typeof a === "symbol")
+ assert (typeof b === "symbol")
+}
+
+compare(Symbol.asyncIterator, realm.Symbol.asyncIterator)
+compare(Symbol.hasInstance, realm.Symbol.hasInstance)
+compare(Symbol.isConcatSpreadable, realm.Symbol.isConcatSpreadable)
+compare(Symbol.iterator, realm.Symbol.iterator)
+compare(Symbol.match, realm.Symbol.match)
+compare(Symbol.replace, realm.Symbol.replace)
+compare(Symbol.search, realm.Symbol.search)
+compare(Symbol.species, realm.Symbol.species)
+compare(Symbol.split, realm.Symbol.split)
+compare(Symbol.toPrimitive, realm.Symbol.toPrimitive)
+compare(Symbol.toStringTag, realm.Symbol.toStringTag)
+compare(Symbol.unscopables, realm.Symbol.unscopables)
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 67187c072..e6bcc830b 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -7932,8 +7932,6 @@
-
-
@@ -8012,7 +8010,6 @@
-
@@ -9532,26 +9529,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -9663,34 +9642,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -9699,46 +9658,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -9746,43 +9668,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -9793,9 +9692,7 @@
-
-
@@ -9805,8 +9702,6 @@
-
-
@@ -9822,10 +9717,6 @@
-
-
-
-
@@ -9833,8 +9724,6 @@
-
-