diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index 7ee5bc086..95765398a 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -9171,6 +9171,54 @@ jerry_set_realm (jerry_value_t realm_value); - [jerry_create_realm](#jerry_create_realm) +## jerry_realm_set_this + +**Summary** + +Sets the 'this' binding of a realm. This function must be called before executing +any script on the realm. Otherwise the operation is undefined. + +*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_realm_set_this (jerry_value_t realm_value, jerry_value_t this_value) +``` +- `realm_value` - realm value +- `this_value` - new this value +- return + - exception - if any error is happened + - true - 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); + /* The prototype of the object comes from the new realm. */ + jerry_value_t this_value = jerry_create_object (); + jerry_set_realm (old_realm); + + jerry_value_t result = jerry_realm_set_this (realm_value, this_value); + + ... // usage of the realm +} +``` + +**See also** + +- [jerry_create_realm](#jerry_create_realm) +- [jerry_set_realm](#jerry_set_realm) + # ArrayBuffer and TypedArray functions These APIs all depend on the es.next profile. diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index 9d0b4f6fb..83562582e 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -388,7 +388,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end); #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ECMA_VALUE_UNDEFINED; + args_p->realm_value = JMEM_CP_NULL; #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ } else @@ -400,7 +400,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end); #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ECMA_VALUE_UNDEFINED; + args_p->realm_value = JMEM_CP_NULL; #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ } @@ -601,7 +601,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th header_size = sizeof (cbc_uint16_arguments_t); #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ecma_make_object_value (ecma_builtin_get_global ()); + ECMA_SET_INTERNAL_VALUE_POINTER (args_p->realm_value, ecma_builtin_get_global ()); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ } else @@ -615,7 +615,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th header_size = sizeof (cbc_uint8_arguments_t); #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ecma_make_object_value (ecma_builtin_get_global ()); + ECMA_SET_INTERNAL_VALUE_POINTER (args_p->realm_value, ecma_builtin_get_global ()); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ } @@ -1028,7 +1028,7 @@ jerry_snapshot_result (const uint32_t *snapshot_p, /**< snapshot */ ecma_object_t *global_object_p = ecma_builtin_get_global (); #if ENABLED (JERRY_BUILTIN_REALMS) - JERRY_ASSERT (global_object_p == ecma_get_object_from_value (ecma_op_function_get_realm (bytecode_p))); + JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ #if ENABLED (JERRY_ESNEXT) diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 1a80269fb..1a5b3cdf9 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -471,7 +471,7 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a ecma_object_t *global_object_p = ecma_builtin_get_global (); #if ENABLED (JERRY_BUILTIN_REALMS) - JERRY_ASSERT (global_object_p == ecma_get_object_from_value (ecma_op_function_get_realm (bytecode_data_p))); + JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_data_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p); @@ -550,7 +550,7 @@ jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (u ecma_object_t *global_object_p = ecma_builtin_get_global (); #if ENABLED (JERRY_BUILTIN_REALMS) - JERRY_ASSERT (global_object_p == ecma_get_object_from_value (ecma_op_function_get_realm (bytecode_p))); + JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p); @@ -4602,6 +4602,58 @@ jerry_set_realm (jerry_value_t realm_value) /**< jerry api value */ #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ } /* jerry_set_realm */ +/** + * Sets the 'this' binding of a realm + * + * This function must be called before executing any script on the realm. + * Otherwise the operation is undefined. + * + * @return thrown error - if any error is happened + * true - otherwise + */ +jerry_value_t +jerry_realm_set_this (jerry_value_t realm_value, /**< realm value */ + jerry_value_t this_value) /**< this value */ +{ + jerry_assert_api_available (); + +#if ENABLED (JERRY_BUILTIN_REALMS) + if (!ecma_is_value_object (this_value)) + { + return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Second argument must be an object"))); + } + + 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 *global_object_p = (ecma_global_object_t *) object_p; + global_object_p->this_binding = this_value; + + ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL, + ecma_get_object_from_value (this_value), + ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); + + ECMA_SET_NON_NULL_POINTER (global_object_p->global_env_cp, global_lex_env_p); +#if ENABLED (JERRY_ESNEXT) + global_object_p->global_scope_cp = global_object_p->global_env_cp; +#endif /* ENABLED (JERRY_ESNEXT) */ + ecma_deref_object (global_lex_env_p); + return ECMA_VALUE_TRUE; + } + } + + return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("First argument is not a realm"))); +#else /* !ENABLED (JERRY_BUILTIN_REALMS) */ + JERRY_UNUSED (realm_value); + JERRY_UNUSED (this_value); + return jerry_throw (ecma_raise_reference_error (ECMA_ERR_MSG ("Realm is not available"))); +#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ +} /* jerry_realm_set_this */ + /** * 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 64186b591..4ece159e8 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -159,6 +159,10 @@ ecma_gc_mark_global_object (ecma_global_object_t *global_object_p) /**< global o ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, global_object_p->global_env_cp)); +#if ENABLED (JERRY_BUILTIN_REALMS) + ecma_gc_set_object_visited (ecma_get_object_from_value (global_object_p->this_binding)); +#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ + #if ENABLED (JERRY_ESNEXT) if (global_object_p->global_scope_cp != global_object_p->global_env_cp) { @@ -919,20 +923,20 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ } #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ - ecma_value_t realm_value; + ecma_object_t *realm_p; if (byte_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) byte_code_p; - realm_value = args_p->realm_value; + realm_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, args_p->realm_value); } else { cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) byte_code_p; - realm_value = args_p->realm_value; + realm_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, args_p->realm_value); } - ecma_gc_set_object_visited (ecma_get_object_from_value (realm_value)); + ecma_gc_set_object_visited (realm_p); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ break; } diff --git a/jerry-core/ecma/base/ecma-module.c b/jerry-core/ecma/base/ecma-module.c index 634a446cd..c1302211b 100644 --- a/jerry-core/ecma/base/ecma-module.c +++ b/jerry-core/ecma/base/ecma-module.c @@ -486,8 +486,7 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */ } #if ENABLED (JERRY_BUILTIN_REALMS) - ecma_object_t *global_object_p; - global_object_p = ecma_get_object_from_value (ecma_op_function_get_realm (module_p->compiled_code_p)); + ecma_object_t *global_object_p = (ecma_object_t *) ecma_op_function_get_realm (module_p->compiled_code_p); #else /* !ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *global_object_p = ecma_builtin_get_global (); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 38811155e..f2d8e283b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -614,6 +614,7 @@ ecma_builtin_create_global_object (void) #if ENABLED (JERRY_BUILTIN_REALMS) ECMA_SET_INTERNAL_VALUE_POINTER (global_object_p->extended_object.u.built_in.realm_value, global_object_p); global_object_p->extra_realms_bitset = 0; + global_object_p->this_binding = ecma_make_object_value (object_p); #else /* !ENABLED (JERRY_BUILTIN_REALMS) */ global_object_p->extended_object.u.built_in.continue_instantiated_bitset[0] = 0; #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index ef3ffa043..5be9d0714 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -108,6 +108,7 @@ typedef struct uint32_t extra_instantiated_bitset[1]; /**< extra bit set for instantiated properties */ #if ENABLED (JERRY_BUILTIN_REALMS) uint32_t extra_realms_bitset; /**< extra bit set for instantiated properties when realms is enabled */ + ecma_value_t this_binding; /**< 'this' binding of this global object */ #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ jmem_cpointer_t global_env_cp; /**< global lexical environment */ #if ENABLED (JERRY_ESNEXT) diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 064b98111..b6069ac1d 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -484,7 +484,7 @@ ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< argu ecma_object_t *global_object_p = ecma_builtin_get_global (); #if ENABLED (JERRY_BUILTIN_REALMS) - JERRY_ASSERT (global_object_p == ecma_get_object_from_value (ecma_op_function_get_realm (bytecode_p))); + JERRY_ASSERT (global_object_p == (ecma_object_t *) ecma_op_function_get_realm (bytecode_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *global_env_p = ecma_get_global_environment (global_object_p); @@ -755,9 +755,9 @@ ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< fun * Note: * Does not increase the reference counter. * - * @return realm (global) object + * @return pointer to realm (global) object */ -inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE +inline ecma_global_object_t * JERRY_ATTR_ALWAYS_INLINE ecma_op_function_get_realm (const ecma_compiled_code_t *bytecode_header_p) /**< byte code header */ { ecma_value_t realm_value; @@ -774,14 +774,14 @@ ecma_op_function_get_realm (const ecma_compiled_code_t *bytecode_header_p) /**< } #if ENABLED (JERRY_SNAPSHOT_EXEC) - if (JERRY_LIKELY (realm_value != ECMA_VALUE_UNDEFINED)) + if (JERRY_LIKELY (realm_value != JMEM_CP_NULL)) { - return realm_value; + return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t, realm_value); } - return ecma_make_object_value (ecma_builtin_get_global ()); + return (ecma_global_object_t *) ecma_builtin_get_global (); #else /* !ENABLED (JERRY_SNAPSHOT_EXEC) */ - return realm_value; + return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_global_object_t, realm_value); #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */ } /* ecma_op_function_get_realm */ @@ -800,8 +800,7 @@ ecma_op_function_get_function_realm (ecma_object_t *func_obj_p) /**< function ob { 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); + return ecma_op_function_get_realm (bytecode_data_p); } JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION); @@ -1074,7 +1073,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */ shared_args.header.bytecode_header_p = bytecode_data_p; #if ENABLED (JERRY_BUILTIN_REALMS) - ecma_value_t realm_value = ecma_op_function_get_realm (bytecode_data_p); + ecma_global_object_t *realm_p = ecma_op_function_get_realm (bytecode_data_p); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ /* 1. */ @@ -1105,7 +1104,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */ { /* 2. */ #if ENABLED (JERRY_BUILTIN_REALMS) - this_binding = realm_value; + this_binding = realm_p->this_binding; #else /* !ENABLED (JERRY_BUILTIN_REALMS) */ this_binding = ecma_make_object_value (ecma_builtin_get_global ()); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ @@ -1155,7 +1154,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */ #if ENABLED (JERRY_BUILTIN_REALMS) ecma_global_object_t *saved_global_object_p = JERRY_CONTEXT (global_object_p); - JERRY_CONTEXT (global_object_p) = (ecma_global_object_t *) ecma_get_object_from_value (realm_value); + JERRY_CONTEXT (global_object_p) = realm_p; #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ ret_value = vm_run (&shared_args.header, this_binding, scope_p); @@ -1634,8 +1633,7 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun 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); + global_object_p = ecma_op_function_get_realm (bytecode_data_p); } else { diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index f1de6a25f..6a330e841 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -57,7 +57,7 @@ const ecma_compiled_code_t * ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p); #if ENABLED (JERRY_BUILTIN_REALMS) -ecma_value_t +ecma_global_object_t * ecma_op_function_get_realm (const ecma_compiled_code_t *bytecode_header_p); ecma_global_object_t * diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index ef9ab56a9..3eef74aa6 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -90,8 +90,14 @@ static inline bool JERRY_ATTR_ALWAYS_INLINE ecma_op_is_global_environment (ecma_object_t *lex_env_p) /**< lexical environment */ { JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); +#if ENABLED (JERRY_BUILTIN_REALMS) + JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL + || (ecma_make_object_value (ecma_get_lex_env_binding_object (lex_env_p)) + == ((ecma_global_object_t *) ecma_builtin_get_global ())->this_binding)); +#else /* !ENABLED (JERRY_BUILTIN_REALMS) */ JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL || ecma_get_lex_env_binding_object (lex_env_p) == ecma_builtin_get_global ()); +#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ return lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL; } /* ecma_op_is_global_environment */ diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index b0955d947..675337052 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -740,6 +740,7 @@ 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); +jerry_value_t jerry_realm_set_this (jerry_value_t realm_value, jerry_value_t this_value); /** * Array buffer components. diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 5b6c38000..f8aed0980 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -978,7 +978,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ args_p->const_literal_end = const_literal_end; args_p->literal_end = context_p->literal_count; #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ecma_make_object_value ((ecma_object_t *) JERRY_CONTEXT (global_object_p)); + ECMA_SET_INTERNAL_VALUE_POINTER (args_p->realm_value, JERRY_CONTEXT (global_object_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ compiled_code_p->status_flags |= CBC_CODE_FLAGS_UINT16_ARGUMENTS; @@ -995,7 +995,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ args_p->const_literal_end = (uint8_t) const_literal_end; args_p->literal_end = (uint8_t) context_p->literal_count; #if ENABLED (JERRY_BUILTIN_REALMS) - args_p->realm_value = ecma_make_object_value ((ecma_object_t *) JERRY_CONTEXT (global_object_p)); + ECMA_SET_INTERNAL_VALUE_POINTER (args_p->realm_value, JERRY_CONTEXT (global_object_p)); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ byte_code_p += sizeof (cbc_uint8_arguments_t); diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 1e6b5021b..49c3792d1 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -844,8 +844,7 @@ opfunc_resume_executable_object (vm_executable_object_t *executable_object_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_op_function_get_realm (bytecode_header_p); - JERRY_CONTEXT (global_object_p) = (ecma_global_object_t *) ecma_get_object_from_value (realm_value); + JERRY_CONTEXT (global_object_p) = ecma_op_function_get_realm (bytecode_header_p); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ ecma_value_t result = vm_execute (&executable_object_p->frame_ctx); diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index dfca952a4..aecfbecf6 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -302,11 +302,9 @@ ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode to run */ { #if ENABLED (JERRY_BUILTIN_REALMS) - ecma_value_t realm_value = ecma_op_function_get_realm (bytecode_p); - ecma_object_t *global_obj_p = ecma_get_object_from_value (realm_value); + ecma_object_t *global_obj_p = (ecma_object_t *) ecma_op_function_get_realm (bytecode_p); #else /* !ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *global_obj_p = ecma_builtin_get_global (); - ecma_value_t realm_value = ecma_make_object_value (global_obj_p); #endif /* ENABLED (JERRY_BUILTIN_REALMS) */ #if ENABLED (JERRY_ESNEXT) @@ -343,7 +341,13 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode shared.bytecode_header_p = bytecode_p; shared.status_flags = 0; - return vm_run (&shared, realm_value, global_scope_p); +#if ENABLED (JERRY_BUILTIN_REALMS) + ecma_value_t this_binding = ((ecma_global_object_t *) global_obj_p)->this_binding; +#else /* !ENABLED (JERRY_BUILTIN_REALMS) */ + ecma_value_t this_binding = ecma_make_object_value (global_obj_p); +#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ + + return vm_run (&shared, this_binding, global_scope_p); } /* vm_run_global */ /** @@ -388,14 +392,14 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ else { #if ENABLED (JERRY_BUILTIN_REALMS) - ecma_value_t realm_value = ecma_op_function_get_realm (bytecode_data_p); - ecma_object_t *global_obj_p = ecma_get_object_from_value (realm_value); + ecma_object_t *global_obj_p = (ecma_object_t *) ecma_op_function_get_realm (bytecode_data_p); + this_binding = ((ecma_global_object_t *) global_obj_p)->this_binding; + ecma_ref_object (ecma_get_object_from_value (this_binding)); #else /* !ENABLED (JERRY_BUILTIN_REALMS) */ ecma_object_t *global_obj_p = ecma_builtin_get_global (); - ecma_value_t realm_value = ecma_make_object_value (global_obj_p); -#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ - this_binding = realm_value; ecma_ref_object (global_obj_p); + this_binding = ecma_make_object_value (global_obj_p); +#endif /* ENABLED (JERRY_BUILTIN_REALMS) */ lex_env_p = ecma_get_global_scope (global_obj_p); } diff --git a/tests/unit-core/test-set-realm.c b/tests/unit-core/test-realm.c similarity index 64% rename from tests/unit-core/test-set-realm.c rename to tests/unit-core/test-realm.c index d982f1bff..5e1030b1c 100644 --- a/tests/unit-core/test-set-realm.c +++ b/tests/unit-core/test-realm.c @@ -19,9 +19,9 @@ #include "test-common.h" static void -create_number_property (jerry_value_t object_value, - char *name_p, - double number) +create_number_property (jerry_value_t object_value, /**< object value */ + char *name_p, /**< name */ + double number) /**< value */ { jerry_value_t name_value = jerry_create_string ((const jerry_char_t *) name_p); jerry_value_t number_value = jerry_create_number (number); @@ -34,7 +34,23 @@ create_number_property (jerry_value_t object_value, } /* create_number_property */ static double -eval_and_get_number (char *script_p) +get_number_property (jerry_value_t object_value, /**< object value */ + char *name_p) /**< name */ +{ + jerry_value_t name_value = jerry_create_string ((const jerry_char_t *) name_p); + jerry_value_t result_value = jerry_get_property (object_value, name_value); + TEST_ASSERT (!jerry_value_is_error (result_value)); + TEST_ASSERT (jerry_value_is_number (result_value)); + + double result = jerry_get_number_value (result_value); + + jerry_release_value (result_value); + jerry_release_value (name_value); + return result; +} /* get_number_property */ + +static double +eval_and_get_number (char *script_p) /**< script source */ { jerry_value_t result_value; result_value = jerry_eval ((const jerry_char_t *) script_p, strlen (script_p), JERRY_PARSE_NO_OPTS); @@ -95,6 +111,30 @@ main (void) jerry_release_value (global_value); jerry_release_value (realm_value); + realm_value = jerry_create_realm (); + + result_value = jerry_set_realm (realm_value); + TEST_ASSERT (!jerry_value_is_error (result_value)); + object_value = jerry_create_object (); + jerry_set_realm (result_value); + + result_value = jerry_realm_set_this (realm_value, object_value); + TEST_ASSERT (jerry_value_is_boolean (result_value) && jerry_get_boolean_value (result_value)); + jerry_release_value (result_value); + + create_number_property (object_value, "x", 7.25); + create_number_property (object_value, "y", 1.25); + + result_value = jerry_set_realm (realm_value); + TEST_ASSERT (!jerry_value_is_error (result_value)); + TEST_ASSERT (eval_and_get_number ("var z = -5.5; x + this.y") == 8.5); + jerry_set_realm (result_value); + + TEST_ASSERT (get_number_property (object_value, "z") == -5.5); + + jerry_release_value (object_value); + jerry_release_value (realm_value); + jerry_cleanup (); return 0; } /* main */