/** * Decrease reference counter of Compact * Byte Code or regexp byte code. */ void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ { JERRY_ASSERT (bytecode_p->refs > 0); bytecode_p->refs--; if (bytecode_p->refs > 0) { /* Non-zero reference counter. */ return; } if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) { lit_cpointer_t *literal_start_p = NULL; uint32_t literal_end; uint32_t const_literal_end; if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { uint8_t *byte_p = (uint8_t *) bytecode_p; literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p; literal_end = args_p->literal_end; const_literal_end = args_p->const_literal_end; } else { uint8_t *byte_p = (uint8_t *) bytecode_p; literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p; literal_end = args_p->literal_end; const_literal_end = args_p->const_literal_end; } for (uint32_t i = const_literal_end; i < literal_end; i++) { jmem_cpointer_t bytecode_cpointer = literal_start_p[i]; ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t, bytecode_cpointer); /* Self references are ignored. */ if (bytecode_literal_p != bytecode_p) { ecma_bytecode_deref (bytecode_literal_p); } } } else { #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p; ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, re_bytecode_p->pattern_cp)); #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */ } jmem_heap_free_block (bytecode_p, ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); } /* ecma_bytecode_deref */
/** * Dealloc memory of an ecma-property */ inline void __attr_always_inline___ ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */ { jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t)); } /* ecma_dealloc_property_pair */
int jerry_main (int argc, char *argv[]) #endif { if (argc > JERRY_MAX_COMMAND_LINE_ARGS) { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Too many command line arguments. Current maximum is %d\n", JERRY_MAX_COMMAND_LINE_ARGS); return JERRY_STANDALONE_EXIT_CODE_FAIL; } const char *file_names[JERRY_MAX_COMMAND_LINE_ARGS]; int i; int files_counter = 0; bool start_debug_server = false; uint16_t debug_port = 5001; jerry_init_flag_t flags = JERRY_INIT_EMPTY; for (i = 1; i < argc; i++) { if (!strcmp ("-h", argv[i]) || !strcmp ("--help", argv[i])) { print_help (argv[0]); return JERRY_STANDALONE_EXIT_CODE_OK; } else if (!strcmp ("--mem-stats", argv[i])) { flags |= JERRY_INIT_MEM_STATS; jerry_log_level = JERRY_LOG_LEVEL_DEBUG; } else if (!strcmp ("--mem-stats-separate", argv[i])) { flags |= JERRY_INIT_MEM_STATS_SEPARATE; jerry_log_level = JERRY_LOG_LEVEL_DEBUG; } else if (!strcmp ("--show-opcodes", argv[i])) { flags |= JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES; jerry_log_level = JERRY_LOG_LEVEL_DEBUG; } else if (!strcmp ("--log-level", argv[i])) { if (++i < argc && strlen (argv[i]) == 1 && argv[i][0] >='0' && argv[i][0] <= '3') { jerry_log_level = argv[i][0] - '0'; } else { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); return JERRY_STANDALONE_EXIT_CODE_FAIL; } } else if (!strcmp ("--start-debug-server", argv[i])) { start_debug_server = true; } else if (!strcmp ("--debug-server-port", argv[i])) { if (++i < argc) { debug_port = str_to_uint (argv[i]); } else { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); return JERRY_STANDALONE_EXIT_CODE_FAIL; } } else { file_names[files_counter++] = argv[i]; } } jerry_init (flags); if (start_debug_server) { jerry_debugger_init (debug_port); } register_js_function ("assert", jerryx_handler_assert); register_js_function ("gc", jerryx_handler_gc); register_js_function ("print", jerryx_handler_print); jerry_value_t ret_value = jerry_create_undefined (); if (files_counter == 0) { printf ("No input files, running a hello world demo:\n"); const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript')"; size_t script_size = strlen ((const char *) script); ret_value = jerry_parse (script, script_size, false); if (!jerry_value_has_error_flag (ret_value)) { ret_value = jerry_run (ret_value); } } else { for (i = 0; i < files_counter; i++) { size_t source_size; const jerry_char_t *source_p = read_file (file_names[i], &source_size); if (source_p == NULL) { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Source file load error\n"); return JERRY_STANDALONE_EXIT_CODE_FAIL; } ret_value = jerry_parse_named_resource ((jerry_char_t *) file_names[i], strlen (file_names[i]), source_p, source_size, false); if (!jerry_value_has_error_flag (ret_value)) { jerry_value_t func_val = ret_value; ret_value = jerry_run (func_val); jerry_release_value (func_val); } if (jerry_value_has_error_flag (ret_value)) { print_unhandled_exception (ret_value, source_p); jmem_heap_free_block ((void*) source_p, source_size); break; } jmem_heap_free_block ((void*) source_p, source_size); jerry_release_value (ret_value); ret_value = jerry_create_undefined (); } } int ret_code = JERRY_STANDALONE_EXIT_CODE_OK; if (jerry_value_has_error_flag (ret_value)) { ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; } jerry_release_value (ret_value); jerry_cleanup (); return ret_code; } /* main */
/** * Dealloc memory of an extended object */ inline void __attr_always_inline___ ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< property pair to be freed */ size_t size) /**< size of object */ { jmem_heap_free_block (ext_object_p, size); } /* ecma_dealloc_extended_object */
/** * Decrease reference counter of Compact * Byte Code or regexp byte code. */ void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ { JERRY_ASSERT (bytecode_p->refs > 0); bytecode_p->refs--; if (bytecode_p->refs > 0) { /* Non-zero reference counter. */ return; } if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) { jmem_cpointer_t *literal_start_p = NULL; uint32_t literal_end; uint32_t const_literal_end; if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { uint8_t *byte_p = (uint8_t *) bytecode_p; literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p; literal_end = args_p->literal_end; const_literal_end = args_p->const_literal_end; } else { uint8_t *byte_p = (uint8_t *) bytecode_p; literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p; literal_end = args_p->literal_end; const_literal_end = args_p->const_literal_end; } for (uint32_t i = const_literal_end; i < literal_end; i++) { jmem_cpointer_t bytecode_cpointer = literal_start_p[i]; ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t, bytecode_cpointer); /* Self references are ignored. */ if (bytecode_literal_p != bytecode_p) { ecma_bytecode_deref (bytecode_literal_p); } } #ifdef JERRY_DEBUGGER if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) && !(bytecode_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE) && jerry_debugger_send_function_cp (JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP, bytecode_p)) { /* Delay the byte code free until the debugger client is notified. * If the connection is aborted the pointer is still freed by * jerry_debugger_close_connection(). */ jerry_debugger_byte_code_free_t *byte_code_free_p = (jerry_debugger_byte_code_free_t *) bytecode_p; jmem_cpointer_t byte_code_free_head = JERRY_CONTEXT (debugger_byte_code_free_head); byte_code_free_p->prev_cp = ECMA_NULL_POINTER; jmem_cpointer_t byte_code_free_cp; JMEM_CP_SET_NON_NULL_POINTER (byte_code_free_cp, byte_code_free_p); if (byte_code_free_head == ECMA_NULL_POINTER) { JERRY_CONTEXT (debugger_byte_code_free_tail) = byte_code_free_cp; } else { jerry_debugger_byte_code_free_t *first_byte_code_free_p; first_byte_code_free_p = JMEM_CP_GET_NON_NULL_POINTER (jerry_debugger_byte_code_free_t, byte_code_free_head); first_byte_code_free_p->prev_cp = byte_code_free_cp; } JERRY_CONTEXT (debugger_byte_code_free_head) = byte_code_free_cp; return; } #endif /* JERRY_DEBUGGER */ #ifdef JMEM_STATS jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); #endif /* JMEM_STATS */ } else { #ifndef CONFIG_DISABLE_REGEXP_BUILTIN re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p; ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, re_bytecode_p->pattern_cp)); #endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */ } jmem_heap_free_block (bytecode_p, ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); } /* ecma_bytecode_deref */