diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index a387fe2e72..367e42b5fd 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -417,6 +417,30 @@ ecma_gc_mark_properties (ecma_object_t *object_p, /**< object */ } } /* ecma_gc_mark_properties */ +/** + * Mark compiled code. + */ +static void +ecma_gc_mark_compiled_code (const ecma_compiled_code_t *compiled_code_p) /**< compiled code */ +{ + JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)); + + ecma_value_t script_value = ((cbc_uint8_arguments_t *) compiled_code_p)->script_value; + cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value); + + if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT) + { + cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p; + + JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value)); + ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value)); + } + +#if JERRY_BUILTIN_REALMS + ecma_gc_set_object_visited (script_p->realm_p); +#endif /* JERRY_BUILTIN_REALMS */ +} /* ecma_gc_mark_compiled_code */ + /** * Mark objects referenced by bound function object. */ @@ -871,6 +895,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ ecma_gc_mark_arguments_object (ext_object_p); break; } +#if JERRY_PARSER + case ECMA_OBJECT_CLASS_SCRIPT: + { + const ecma_compiled_code_t *compiled_code_p; + compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, + ext_object_p->u.cls.u3.value); + ecma_gc_mark_compiled_code (compiled_code_p); + break; + } +#endif /* JERRY_PARSER */ #if JERRY_BUILTIN_TYPEDARRAY case ECMA_OBJECT_CLASS_TYPEDARRAY: { @@ -903,6 +937,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->namespace_object_p); } + if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE) + && module_p->u.compiled_code_p != NULL) + { + ecma_gc_mark_compiled_code (module_p->u.compiled_code_p); + } + ecma_module_node_t *node_p = module_p->imports_p; while (node_p != NULL) @@ -1095,20 +1135,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ } #endif /* JERRY_SNAPSHOT_EXEC */ - ecma_value_t script_value = ((cbc_uint8_arguments_t *) byte_code_p)->script_value; - cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value); - - if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT) - { - cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p; - - JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value)); - ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value)); - } - -#if JERRY_BUILTIN_REALMS - ecma_gc_set_object_visited (script_p->realm_p); -#endif /* JERRY_BUILTIN_REALMS */ + ecma_gc_mark_compiled_code (byte_code_p); break; } #if JERRY_ESNEXT || JERRY_BUILTIN_REALMS diff --git a/tests/unit-core/test-module-dynamic.c b/tests/unit-core/test-module-dynamic.c index a3bd9aa2d2..9afb04bfa2 100644 --- a/tests/unit-core/test-module-dynamic.c +++ b/tests/unit-core/test-module-dynamic.c @@ -77,12 +77,15 @@ module_import_callback (const jerry_value_t specifier, /* string value */ { TEST_ASSERT (user_p == (void *) &mode); - jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, - user_value, - global_user_value); + if (mode != 3) + { + jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, + user_value, + global_user_value); - TEST_ASSERT (jerry_value_is_true (compare_value)); - jerry_release_value (compare_value); + TEST_ASSERT (jerry_value_is_true (compare_value)); + jerry_release_value (compare_value); + } switch (mode) { @@ -107,9 +110,21 @@ module_import_callback (const jerry_value_t specifier, /* string value */ jerry_release_value (object_value); return promise_value; } + case 3: + { + compare_specifier (specifier, 28); + + TEST_ASSERT (jerry_value_is_object (user_value)); + jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1"); + jerry_value_t result = jerry_get_property (user_value, property_name); + TEST_ASSERT (jerry_value_is_number (result) && jerry_get_number_value (result) == 3.5); + jerry_release_value (result); + jerry_release_value (property_name); + return jerry_create_undefined (); + } } - TEST_ASSERT (mode == 3 || mode == 4); + TEST_ASSERT (mode == 4 || mode == 5); jerry_parse_options_t parse_options; parse_options.options = JERRY_PARSE_MODULE; @@ -121,7 +136,7 @@ module_import_callback (const jerry_value_t specifier, /* string value */ TEST_ASSERT (!jerry_value_is_error (result_value)); jerry_release_value (result_value); - if (mode == 3) + if (mode == 4) { result_value = jerry_module_evaluate (parse_result_value); TEST_ASSERT (!jerry_value_is_error (result_value)); @@ -133,13 +148,20 @@ module_import_callback (const jerry_value_t specifier, /* string value */ static void run_script (const char *source_p, /* source code */ - jerry_parse_options_t *parse_options_p) /* parse options */ + jerry_parse_options_t *parse_options_p, /* parse options */ + bool release_user_value) /* release user value */ { jerry_value_t parse_result_value; parse_result_value = jerry_parse ((const jerry_char_t *) source_p, strlen (source_p), parse_options_p); TEST_ASSERT (!jerry_value_is_error (parse_result_value)); + if (release_user_value) + { + jerry_release_value (parse_options_p->user_value); + jerry_gc (JERRY_GC_PRESSURE_HIGH); + } + jerry_value_t result_value; if (parse_options_p->options & JERRY_PARSE_MODULE) { @@ -184,11 +206,11 @@ main (void) if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)) { - run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options); + run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options, false); } else { - run_script ("var expected_message = ''", &parse_options); + run_script ("var expected_message = ''", &parse_options, false); } global_user_value = jerry_create_object (); @@ -203,7 +225,7 @@ main (void) mode = 0; parse_options.options = JERRY_PARSE_HAS_USER_VALUE; parse_options.user_value = global_user_value; - run_script (source_p, &parse_options); + run_script (source_p, &parse_options, false); jerry_release_value (global_user_value); global_user_value = jerry_create_null (); @@ -219,7 +241,7 @@ main (void) mode = 1; parse_options.options = JERRY_PARSE_HAS_USER_VALUE; parse_options.user_value = global_user_value; - run_script (source_p, &parse_options); + run_script (source_p, &parse_options, false); jerry_release_value (global_user_value); global_user_value = jerry_create_number (5.6); @@ -236,7 +258,7 @@ main (void) mode = 2; parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE; parse_options.user_value = global_user_value; - run_script (source_p, &parse_options); + run_script (source_p, &parse_options, false); jerry_release_value (global_user_value); global_user_value = jerry_create_string ((const jerry_char_t *) "Any string..."); @@ -249,10 +271,27 @@ main (void) "}\n" "f()\n"); - mode = 3; + for (int i = 0; i < 2; i++) + { + mode = 3; + parse_options.options = JERRY_PARSE_HAS_USER_VALUE | (i == 1 ? JERRY_PARSE_MODULE : 0); + parse_options.user_value = jerry_create_object (); + jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1"); + jerry_value_t property_value = jerry_create_number (3.5); + jerry_value_t result = jerry_set_property (parse_options.user_value, property_name, property_value); + TEST_ASSERT (jerry_value_is_true (result)); + jerry_release_value (result); + jerry_release_value (property_value); + jerry_release_value (property_name); + + source_p = TEST_STRING_LITERAL ("import('28_module.mjs')"); + run_script (source_p, &parse_options, true); + } + + mode = 4; parse_options.options = JERRY_PARSE_HAS_USER_VALUE; parse_options.user_value = global_user_value; - run_script (source_p, &parse_options); + run_script (source_p, &parse_options, false); jerry_release_value (global_user_value); global_user_value = jerry_create_external_function (global_assert); @@ -268,10 +307,10 @@ main (void) "}\n" "f()\n"); - mode = 4; + mode = 5; parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE; parse_options.user_value = global_user_value; - run_script (source_p, &parse_options); + run_script (source_p, &parse_options, false); jerry_release_value (global_user_value); jerry_cleanup ();