diff --git a/jerry-core/api/jerry-debugger.c b/jerry-core/api/jerry-debugger.c index 0e9802f1ae..627727b5dc 100644 --- a/jerry-core/api/jerry-debugger.c +++ b/jerry-core/api/jerry-debugger.c @@ -43,7 +43,7 @@ jerry_debugger_stop (void) if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE)) { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; } #endif /* JERRY_DEBUGGER */ @@ -59,7 +59,7 @@ jerry_debugger_continue (void) if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE)) { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; } #endif /* JERRY_DEBUGGER */ @@ -77,11 +77,11 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) /**< enable/d { if (enable_stop_at_breakpoint) { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_IGNORE); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE); } else { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_IGNORE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE); } } #else /* !JERRY_DEBUGGER */ @@ -122,7 +122,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE)) { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_SOURCE_MODE); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); jerry_debugger_uint8_data_t *client_source_data_p = NULL; jerry_debugger_wait_for_source_status_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED; @@ -142,8 +142,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONTEXT_RESET_MODE)) { ret_type = JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED; - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) - & ~JERRY_DEBUGGER_CONTEXT_RESET_MODE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE); break; } @@ -151,8 +150,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_NO_SOURCE)) { ret_type = JERRY_DEBUGGER_SOURCE_END; - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) - & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); break; } diff --git a/jerry-core/debugger/debugger-ws.c b/jerry-core/debugger/debugger-ws.c index 411724924f..04fdf0aab1 100644 --- a/jerry-core/debugger/debugger-ws.c +++ b/jerry-core/debugger/debugger-ws.c @@ -69,7 +69,7 @@ jerry_debugger_close_connection_tcp (bool log_error) /**< log error */ { JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); - JERRY_CONTEXT (debugger_flags) = (uint8_t) JERRY_DEBUGGER_VM_IGNORE; + JERRY_CONTEXT (debugger_flags) = JERRY_DEBUGGER_VM_IGNORE; if (log_error) { @@ -360,7 +360,7 @@ jerry_debugger_accept_connection (void) close (server_socket); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CONNECTED); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CONNECTED); bool is_handshake_ok = false; @@ -399,7 +399,7 @@ jerry_debugger_accept_connection (void) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Connected from: %s\n", inet_ntoa (addr.sin_addr)); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; return true; @@ -444,7 +444,7 @@ jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] { JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); - JERRY_ASSERT (message_data_p != NULL ? (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE) + JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE) : !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)); JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY; diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index 06e7c58eac..f58957411b 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -34,8 +34,8 @@ * The number of message types in the debugger should reflect the * debugger versioning. */ -JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 26 - && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 16 +JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27 + && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 18 && JERRY_DEBUGGER_VERSION == 1, debugger_version_correlates_to_message_type_count); @@ -154,9 +154,9 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_IGNORE); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE); ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p, eval_string_size, true, false); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_IGNORE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE); if (!ECMA_IS_VALUE_ERROR (result)) { @@ -325,8 +325,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec else { result = true; - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) - & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); *resume_exec_p = true; } @@ -407,7 +406,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec { JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; *resume_exec_p = false; return true; @@ -417,7 +416,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec { JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; *resume_exec_p = true; return true; @@ -427,7 +426,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec { JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = NULL; *resume_exec_p = true; return true; @@ -437,7 +436,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec { JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_VM_STOP); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p); *resume_exec_p = true; return true; @@ -456,20 +455,51 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t); JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_exception_config_t, exception_config_p); - uint8_t debugger_flags = JERRY_CONTEXT (debugger_flags); - if (exception_config_p->enable == 0) { - debugger_flags = (uint8_t) (debugger_flags | JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception disabled\n"); } else { - debugger_flags = (uint8_t) (debugger_flags & ~JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception enabled\n"); } - JERRY_CONTEXT (debugger_flags) = debugger_flags; + return true; + } + + case JERRY_DEBUGGER_PARSER_CONFIG: + { + JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_parser_config_t); + JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_parser_config_t, parser_config_p); + + if (parser_config_p->enable_wait != 0) + { + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT); + jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing enabled\n"); + } + else + { + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT); + jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing disabled\n"); + } + + return true; + } + + case JERRY_DEBUGGER_PARSER_RESUME: + { + JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); + + if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE)) + { + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in parser wait mode\n"); + jerry_debugger_close_connection (); + return false; + } + + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE); return true; } @@ -568,8 +598,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec } else { - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) - & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); *resume_exec_p = true; } return true; @@ -586,8 +615,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_NO_SOURCE); + JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CLIENT_NO_SOURCE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE); *resume_exec_p = true; @@ -605,8 +633,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_CLIENT_SOURCE_MODE); - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CONTEXT_RESET_MODE); + JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE); *resume_exec_p = true; @@ -652,7 +679,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */ return; } - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_BREAKPOINT_MODE); + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE); jerry_debugger_uint8_data_t *uint8_data = NULL; @@ -667,7 +694,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */ uint8_data->uint8_size + sizeof (jerry_debugger_uint8_data_t)); } - JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) & ~JERRY_DEBUGGER_BREAKPOINT_MODE); + JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE); JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY; } /* jerry_debugger_breakpoint_hit */ diff --git a/jerry-core/debugger/debugger.h b/jerry-core/debugger/debugger.h index 404964b9df..0e18050dff 100644 --- a/jerry-core/debugger/debugger.h +++ b/jerry-core/debugger/debugger.h @@ -93,18 +93,41 @@ typedef enum JERRY_DEBUGGER_VM_STOP = 1u << 2, /**< stop at the next breakpoint regardless it is enabled */ JERRY_DEBUGGER_VM_IGNORE = 1u << 3, /**< ignore all breakpoints */ JERRY_DEBUGGER_VM_IGNORE_EXCEPTION = 1u << 4, /**< debugger stop at an exception */ - JERRY_DEBUGGER_CLIENT_SOURCE_MODE = 1u << 5, /**< debugger waiting for client code */ - JERRY_DEBUGGER_CLIENT_NO_SOURCE = 1u << 6, /**< debugger leaving the client source loop */ - JERRY_DEBUGGER_CONTEXT_RESET_MODE = 1u << 7, /**< debugger and engine reinitialization mode */ + JERRY_DEBUGGER_PARSER_WAIT = 1u << 5, /**< debugger should wait after parsing is completed */ + JERRY_DEBUGGER_PARSER_WAIT_MODE = 1u << 6, /**< debugger is waiting after parsing is completed */ + JERRY_DEBUGGER_CLIENT_SOURCE_MODE = 1u << 7, /**< debugger waiting for client code */ + JERRY_DEBUGGER_CLIENT_NO_SOURCE = 1u << 8, /**< debugger leaving the client source loop */ + JERRY_DEBUGGER_CONTEXT_RESET_MODE = 1u << 9, /**< debugger and engine reinitialization mode */ } jerry_debugger_flags_t; +/** + * Set debugger flags. + */ +#define JERRY_DEBUGGER_SET_FLAGS(flags) \ + JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags)) + +/** + * Clear debugger flags. + */ +#define JERRY_DEBUGGER_CLEAR_FLAGS(flags) \ + JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) & (uint32_t) ~(flags)) + +/** + * Set and clear debugger flags. + */ +#define JERRY_DEBUGGER_UPDATE_FLAGS(flags_to_set, flags_to_clear) \ + JERRY_CONTEXT (debugger_flags) = ((JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags_to_set)) \ + & (uint32_t) ~(flags_to_clear)) + /** * Types for the package. */ typedef enum { /* Messages sent by the server to client. */ + /* This is a handshake message, sent once during initialization. */ JERRY_DEBUGGER_CONFIGURATION = 1, /**< debugger configuration */ + /* These messages are sent by the parser. */ JERRY_DEBUGGER_PARSE_ERROR = 2, /**< parse error */ JERRY_DEBUGGER_BYTE_CODE_CP = 3, /**< byte code compressed pointer */ JERRY_DEBUGGER_PARSE_FUNCTION = 4, /**< parsing a new function */ @@ -116,19 +139,21 @@ typedef enum JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10, /**< source code name last fragment */ JERRY_DEBUGGER_FUNCTION_NAME = 11, /**< function name fragment */ JERRY_DEBUGGER_FUNCTION_NAME_END = 12, /**< function name last fragment */ - JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13, /**< invalidate byte code compressed pointer */ - JERRY_DEBUGGER_MEMSTATS_RECEIVE = 14, /**< memstats sent to the client*/ - JERRY_DEBUGGER_BREAKPOINT_HIT = 15, /**< notify breakpoint hit */ - JERRY_DEBUGGER_EXCEPTION_HIT = 16, /**< notify exception hit */ - JERRY_DEBUGGER_EXCEPTION_STR = 17, /**< exception string fragment */ - JERRY_DEBUGGER_EXCEPTION_STR_END = 18, /**< exception string last fragment */ - JERRY_DEBUGGER_BACKTRACE = 19, /**< backtrace data */ - JERRY_DEBUGGER_BACKTRACE_END = 20, /**< last backtrace data */ - JERRY_DEBUGGER_EVAL_RESULT = 21, /**< eval result */ - JERRY_DEBUGGER_EVAL_RESULT_END = 22, /**< last part of eval result */ - JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23, /**< engine waiting for a source code */ - JERRY_DEBUGGER_OUTPUT_RESULT = 24, /**< output sent by the program to the debugger */ - JERRY_DEBUGGER_OUTPUT_RESULT_END = 25, /**< last output result data */ + JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13, /**< engine waiting for a parser resume */ + /* These messages are generic messages. */ + JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14, /**< invalidate byte code compressed pointer */ + JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15, /**< memstats sent to the client*/ + JERRY_DEBUGGER_BREAKPOINT_HIT = 16, /**< notify breakpoint hit */ + JERRY_DEBUGGER_EXCEPTION_HIT = 17, /**< notify exception hit */ + JERRY_DEBUGGER_EXCEPTION_STR = 18, /**< exception string fragment */ + JERRY_DEBUGGER_EXCEPTION_STR_END = 19, /**< exception string last fragment */ + JERRY_DEBUGGER_BACKTRACE = 20, /**< backtrace data */ + JERRY_DEBUGGER_BACKTRACE_END = 21, /**< last backtrace data */ + JERRY_DEBUGGER_EVAL_RESULT = 22, /**< eval result */ + JERRY_DEBUGGER_EVAL_RESULT_END = 23, /**< last part of eval result */ + JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24, /**< engine waiting for a source code */ + JERRY_DEBUGGER_OUTPUT_RESULT = 25, /**< output sent by the program to the debugger */ + JERRY_DEBUGGER_OUTPUT_RESULT_END = 26, /**< last output result data */ JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */ @@ -138,22 +163,26 @@ typedef enum JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */ JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2, /**< update breakpoint status */ JERRY_DEBUGGER_EXCEPTION_CONFIG = 3, /**< exception handler config */ - JERRY_DEBUGGER_MEMSTATS = 4, /**< list memory statistics */ - JERRY_DEBUGGER_STOP = 5, /**< stop execution */ - JERRY_DEBUGGER_CLIENT_SOURCE = 6, /**< first message of client source */ - JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7, /**< next message of client source */ - JERRY_DEBUGGER_NO_MORE_SOURCES = 8, /**< no more sources notification */ - JERRY_DEBUGGER_CONTEXT_RESET = 9, /**< context reset request */ + JERRY_DEBUGGER_PARSER_CONFIG = 4, /**< parser config */ + JERRY_DEBUGGER_MEMSTATS = 5, /**< list memory statistics */ + JERRY_DEBUGGER_STOP = 6, /**< stop execution */ + /* The following message is only available in waiting after parse mode. */ + JERRY_DEBUGGER_PARSER_RESUME = 7, /**< stop waiting after parse */ + /* The following four messages are only available in client switch mode. */ + JERRY_DEBUGGER_CLIENT_SOURCE = 8, /**< first message of client source */ + JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9, /**< next message of client source */ + JERRY_DEBUGGER_NO_MORE_SOURCES = 10, /**< no more sources notification */ + JERRY_DEBUGGER_CONTEXT_RESET = 11, /**< context reset request */ /* The following messages are only available in breakpoint * mode and they switch the engine to run mode. */ - JERRY_DEBUGGER_CONTINUE = 10, /**< continue execution */ - JERRY_DEBUGGER_STEP = 11, /**< next breakpoint, step into functions */ - JERRY_DEBUGGER_NEXT = 12, /**< next breakpoint in the same context */ + JERRY_DEBUGGER_CONTINUE = 12, /**< continue execution */ + JERRY_DEBUGGER_STEP = 13, /**< next breakpoint, step into functions */ + JERRY_DEBUGGER_NEXT = 14, /**< next breakpoint in the same context */ /* The following messages are only available in breakpoint * mode and this mode is kept after the message is processed. */ - JERRY_DEBUGGER_GET_BACKTRACE = 13, /**< get backtrace */ - JERRY_DEBUGGER_EVAL = 14, /**< first message of evaluating a string */ - JERRY_DEBUGGER_EVAL_PART = 15, /**< next message of evaluating a string */ + JERRY_DEBUGGER_GET_BACKTRACE = 15, /**< get backtrace */ + JERRY_DEBUGGER_EVAL = 16, /**< first message of evaluating a string */ + JERRY_DEBUGGER_EVAL_PART = 17, /**< next message of evaluating a string */ JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT, /**< number of different type of input messages */ } jerry_debugger_header_type_t; @@ -313,12 +342,24 @@ typedef struct jerry_debugger_frame_t frames[JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t)]; /**< frames */ } jerry_debugger_send_backtrace_t; +/** + * Incoming message: set behaviour when exception occures. + */ typedef struct { uint8_t type; /**< type of the message */ uint8_t enable; /**< non-zero: enable stop at exception */ } jerry_debugger_receive_exception_config_t; +/** + * Incoming message: set parser configuration. + */ +typedef struct +{ + uint8_t type; /**< type of the message */ + uint8_t enable_wait; /**< non-zero: wait after parsing is completed */ +} jerry_debugger_receive_parser_config_t; + /** * Incoming message: get backtrace. */ diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 72e58a1ff0..01d611b23f 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -116,11 +116,11 @@ typedef struct vm_frame_ctx_t *debugger_stop_context; /**< stop only if the current context is equal to this context */ jmem_cpointer_t debugger_byte_code_free_head; /**< head of byte code free linked list */ jmem_cpointer_t debugger_byte_code_free_tail; /**< tail of byte code free linked list */ - uint8_t debugger_flags; /**< debugger flags */ - uint8_t debugger_message_delay; /**< call receive message when reaches zero */ + uint32_t debugger_flags; /**< debugger flags */ uint16_t debugger_receive_buffer_offset; /**< receive buffer offset */ - int debugger_connection; /**< holds the file descriptor of the socket communication */ uint16_t debugger_port; /**< debugger socket communication port */ + uint8_t debugger_message_delay; /**< call receive message when reaches zero */ + int debugger_connection; /**< holds the file descriptor of the socket communication */ #endif /* JERRY_DEBUGGER */ #ifdef JMEM_STATS diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index ef763c3a70..5d31ed847a 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -2275,7 +2275,7 @@ parser_save_context (parser_context_t *context_p, /**< context */ JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE); #ifdef JERRY_DEBUGGER - if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED + if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) && context_p->breakpoint_info_count > 0) { parser_send_breakpoints (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST); @@ -2756,6 +2756,28 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */ return ecma_raise_syntax_error (""); #endif /* JERRY_ENABLE_ERROR_MESSAGES */ } + +#ifdef JERRY_DEBUGGER + if ((JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT)) + == (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT)) + { + JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE); + jerry_debugger_send_type (JERRY_DEBUGGER_WAITING_AFTER_PARSE); + + while (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE) + { + jerry_debugger_receive (NULL); + + if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)) + { + break; + } + + jerry_debugger_sleep (); + } + } +#endif /* JERRY_DEBUGGER */ + return ECMA_VALUE_TRUE; #else /* JERRY_DISABLE_JS_PARSER */ JERRY_UNUSED (arg_list_p); diff --git a/jerry-debugger/jerry-client-ws.html b/jerry-debugger/jerry-client-ws.html index f4fe9a87ad..c0fd2861f6 100644 --- a/jerry-debugger/jerry-client-ws.html +++ b/jerry-debugger/jerry-client-ws.html @@ -51,19 +51,20 @@

JerryScript HTML (WebSocket) Debugger Client

var JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10; var JERRY_DEBUGGER_FUNCTION_NAME = 11; var JERRY_DEBUGGER_FUNCTION_NAME_END = 12; -var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13; -var JERRY_DEBUGGER_MEMSTATS_RECEIVE = 14; -var JERRY_DEBUGGER_BREAKPOINT_HIT = 15; -var JERRY_DEBUGGER_EXCEPTION_HIT = 16; -var JERRY_DEBUGGER_EXCEPTION_STR = 17; -var JERRY_DEBUGGER_EXCEPTION_STR_END = 18; -var JERRY_DEBUGGER_BACKTRACE = 19; -var JERRY_DEBUGGER_BACKTRACE_END = 20; -var JERRY_DEBUGGER_EVAL_RESULT = 21; -var JERRY_DEBUGGER_EVAL_RESULT_END = 22; -var JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23; -var JERRY_DEBUGGER_OUTPUT_RESULT = 24; -var JERRY_DEBUGGER_OUTPUT_RESULT_END = 25; +var JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13; +var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14; +var JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15; +var JERRY_DEBUGGER_BREAKPOINT_HIT = 16; +var JERRY_DEBUGGER_EXCEPTION_HIT = 17; +var JERRY_DEBUGGER_EXCEPTION_STR = 18; +var JERRY_DEBUGGER_EXCEPTION_STR_END = 19; +var JERRY_DEBUGGER_BACKTRACE = 20; +var JERRY_DEBUGGER_BACKTRACE_END = 21; +var JERRY_DEBUGGER_EVAL_RESULT = 22; +var JERRY_DEBUGGER_EVAL_RESULT_END = 23; +var JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24; +var JERRY_DEBUGGER_OUTPUT_RESULT = 25; +var JERRY_DEBUGGER_OUTPUT_RESULT_END = 26; // Subtypes of eval var JERRY_DEBUGGER_EVAL_OK = 1; @@ -80,18 +81,20 @@

JerryScript HTML (WebSocket) Debugger Client

var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1; var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2; var JERRY_DEBUGGER_EXCEPTION_CONFIG = 3; -var JERRY_DEBUGGER_MEMSTATS = 4; -var JERRY_DEBUGGER_STOP = 5; -var JERRY_DEBUGGER_CLIENT_SOURCE = 6; -var JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7; -var JERRY_DEBUGGER_NO_MORE_SOURCES = 8; -var JERRY_DEBUGGER_CONTEXT_RESET = 9; -var JERRY_DEBUGGER_CONTINUE = 10; -var JERRY_DEBUGGER_STEP = 11; -var JERRY_DEBUGGER_NEXT = 12; -var JERRY_DEBUGGER_GET_BACKTRACE = 13; -var JERRY_DEBUGGER_EVAL = 14; -var JERRY_DEBUGGER_EVAL_PART = 15; +var JERRY_DEBUGGER_PARSER_CONFIG = 4; +var JERRY_DEBUGGER_MEMSTATS = 5; +var JERRY_DEBUGGER_STOP = 6; +var JERRY_DEBUGGER_PARSER_RESUME = 7; +var JERRY_DEBUGGER_CLIENT_SOURCE = 8; +var JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9; +var JERRY_DEBUGGER_NO_MORE_SOURCES = 10; +var JERRY_DEBUGGER_CONTEXT_RESET = 11; +var JERRY_DEBUGGER_CONTINUE = 12; +var JERRY_DEBUGGER_STEP = 13; +var JERRY_DEBUGGER_NEXT = 14; +var JERRY_DEBUGGER_GET_BACKTRACE = 15; +var JERRY_DEBUGGER_EVAL = 16; +var JERRY_DEBUGGER_EVAL_PART = 17; var textBox = document.getElementById("log"); var commandBox = document.getElementById("command"); diff --git a/jerry-debugger/jerry-client-ws.py b/jerry-debugger/jerry-client-ws.py index b1b1b9a119..cdea8a65e0 100755 --- a/jerry-debugger/jerry-client-ws.py +++ b/jerry-debugger/jerry-client-ws.py @@ -41,19 +41,20 @@ JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10 JERRY_DEBUGGER_FUNCTION_NAME = 11 JERRY_DEBUGGER_FUNCTION_NAME_END = 12 -JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 13 -JERRY_DEBUGGER_MEMSTATS_RECEIVE = 14 -JERRY_DEBUGGER_BREAKPOINT_HIT = 15 -JERRY_DEBUGGER_EXCEPTION_HIT = 16 -JERRY_DEBUGGER_EXCEPTION_STR = 17 -JERRY_DEBUGGER_EXCEPTION_STR_END = 18 -JERRY_DEBUGGER_BACKTRACE = 19 -JERRY_DEBUGGER_BACKTRACE_END = 20 -JERRY_DEBUGGER_EVAL_RESULT = 21 -JERRY_DEBUGGER_EVAL_RESULT_END = 22 -JERRY_DEBUGGER_WAIT_FOR_SOURCE = 23 -JERRY_DEBUGGER_OUTPUT_RESULT = 24 -JERRY_DEBUGGER_OUTPUT_RESULT_END = 25 +JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13 +JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14 +JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15 +JERRY_DEBUGGER_BREAKPOINT_HIT = 16 +JERRY_DEBUGGER_EXCEPTION_HIT = 17 +JERRY_DEBUGGER_EXCEPTION_STR = 18 +JERRY_DEBUGGER_EXCEPTION_STR_END = 19 +JERRY_DEBUGGER_BACKTRACE = 20 +JERRY_DEBUGGER_BACKTRACE_END = 21 +JERRY_DEBUGGER_EVAL_RESULT = 22 +JERRY_DEBUGGER_EVAL_RESULT_END = 23 +JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24 +JERRY_DEBUGGER_OUTPUT_RESULT = 25 +JERRY_DEBUGGER_OUTPUT_RESULT_END = 26 # Subtypes of eval JERRY_DEBUGGER_EVAL_OK = 1 @@ -71,18 +72,20 @@ JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1 JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2 JERRY_DEBUGGER_EXCEPTION_CONFIG = 3 -JERRY_DEBUGGER_MEMSTATS = 4 -JERRY_DEBUGGER_STOP = 5 -JERRY_DEBUGGER_CLIENT_SOURCE = 6 -JERRY_DEBUGGER_CLIENT_SOURCE_PART = 7 -JERRY_DEBUGGER_NO_MORE_SOURCES = 8 -JERRY_DEBUGGER_CONTEXT_RESET = 9 -JERRY_DEBUGGER_CONTINUE = 10 -JERRY_DEBUGGER_STEP = 11 -JERRY_DEBUGGER_NEXT = 12 -JERRY_DEBUGGER_GET_BACKTRACE = 13 -JERRY_DEBUGGER_EVAL = 14 -JERRY_DEBUGGER_EVAL_PART = 15 +JERRY_DEBUGGER_PARSER_CONFIG = 4 +JERRY_DEBUGGER_MEMSTATS = 5 +JERRY_DEBUGGER_STOP = 6 +JERRY_DEBUGGER_PARSER_RESUME = 7 +JERRY_DEBUGGER_CLIENT_SOURCE = 8 +JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9 +JERRY_DEBUGGER_NO_MORE_SOURCES = 10 +JERRY_DEBUGGER_CONTEXT_RESET = 11 +JERRY_DEBUGGER_CONTINUE = 12 +JERRY_DEBUGGER_STEP = 13 +JERRY_DEBUGGER_NEXT = 14 +JERRY_DEBUGGER_GET_BACKTRACE = 15 +JERRY_DEBUGGER_EVAL = 16 +JERRY_DEBUGGER_EVAL_PART = 17 MAX_BUFFER_SIZE = 128 WEBSOCKET_BINARY_FRAME = 2 @@ -315,6 +318,8 @@ def do_delete(self, args): self.debugger.send_breakpoint(breakpoint) elif breakpoint_index in self.debugger.pending_breakpoint_list: del self.debugger.pending_breakpoint_list[breakpoint_index] + if not self.debugger.pending_breakpoint_list: + self.debugger.send_parser_config(0) else: print("Error: Breakpoint %d not found" % (breakpoint_index)) @@ -636,7 +641,9 @@ def delete_active(self): self.send_breakpoint(breakpoint) def delete_pending(self): - self.pending_breakpoint_list.clear() + if self.pending_breakpoint_list: + self.pending_breakpoint_list.clear() + self.send_parser_config(0) def breakpoint_pending_exists(self, breakpoint): for existing_bp in self.pending_breakpoint_list.values(): @@ -684,13 +691,22 @@ def send_exception_config(self, enable): enable) self.send_message(message) + def send_parser_config(self, enable): + message = struct.pack(self.byte_order + "BBIBB", + WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT, + WEBSOCKET_FIN_BIT + 1 + 1, + 0, + JERRY_DEBUGGER_PARSER_CONFIG, + enable) + self.send_message(message) + def set_colors(self): - self.green = '\033[92m' self.nocolor = '\033[0m' + self.green = '\033[92m' self.red = '\033[31m' self.yellow = '\033[93m' - self.green_bg = '\033[42m' - self.yellow_bg = '\033[43m' + self.green_bg = '\033[42m\033[30m' + self.yellow_bg = '\033[43m\033[30m' self.blue = '\033[94m' def get_message(self, blocking): @@ -843,29 +859,29 @@ def parse_source(debugger, data): debugger.line_list.insert(line, breakpoint) # Try to set the pending breakpoints - if len(debugger.pending_breakpoint_list) != 0: + if debugger.pending_breakpoint_list: logging.debug("Pending breakpoints list: %s", debugger.pending_breakpoint_list) bp_list = debugger.pending_breakpoint_list - for breakpoint in bp_list: + for breakpoint_index, breakpoint in bp_list.items(): for src in debugger.function_list.values(): - if src.source_name == bp_list[breakpoint].source_name: + if src.source_name == breakpoint.source_name: source_lines = len(src.source) else: source_lines = 0 - if bp_list[breakpoint].line: - if bp_list[breakpoint].line <= source_lines: - tmp_bp = breakpoint - breakpoint = bp_list[breakpoint].source_name + ":" + str(bp_list[breakpoint].line) - if set_breakpoint(debugger, breakpoint, True): - del tmp_bp - elif bp_list[breakpoint].function: - tmp_bp = breakpoint - breakpoint = bp_list[breakpoint].function - if set_breakpoint(debugger, breakpoint, True): - del tmp_bp + if breakpoint.line: + if breakpoint.line <= source_lines: + command = breakpoint.source_name + ":" + str(breakpoint.line) + if set_breakpoint(debugger, command, True): + del bp_list[breakpoint_index] + elif breakpoint.function: + command = breakpoint.function + if set_breakpoint(debugger, command, True): + del bp_list[breakpoint_index] + if not bp_list: + debugger.send_parser_config(0) else: logging.debug("No pending breakpoints") @@ -971,14 +987,19 @@ def set_breakpoint(debugger, string, pending): if not found and not pending: print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \ - (debugger.yellow, debugger.nocolor)) + (debugger.yellow, debugger.nocolor)) + ans = sys.stdin.readline() if ans in ['yes\n', 'y\n']: + if not debugger.pending_breakpoint_list: + debugger.send_parser_config(1) + if line: breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1)) else: breakpoint = JerryPendingBreakpoint(function=string) enable_breakpoint(debugger, breakpoint) + elif not found and pending: return False @@ -1062,6 +1083,9 @@ def main(): JERRY_DEBUGGER_FUNCTION_NAME_END]: parse_source(debugger, data) + elif buffer_type == JERRY_DEBUGGER_WAITING_AFTER_PARSE: + debugger.send_command(JERRY_DEBUGGER_PARSER_RESUME) + elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP: release_function(debugger, data) diff --git a/tests/debugger/do_pending_breakpoints.cmd b/tests/debugger/do_pending_breakpoints.cmd index e57e4d578d..fd879372d5 100644 --- a/tests/debugger/do_pending_breakpoints.cmd +++ b/tests/debugger/do_pending_breakpoints.cmd @@ -1,7 +1,9 @@ +break :1 +y break f y list -n -n +c +list c c diff --git a/tests/debugger/do_pending_breakpoints.expected b/tests/debugger/do_pending_breakpoints.expected index e5bbea63ff..33efcc2632 100644 --- a/tests/debugger/do_pending_breakpoints.expected +++ b/tests/debugger/do_pending_breakpoints.expected @@ -1,17 +1,24 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_pending_breakpoints.js:15 +(jerry-debugger) break :1 +No breakpoint found, do you want to add a pending breakpoint? (y or [n]) +Pending breakpoint at :1 (jerry-debugger) break f No breakpoint found, do you want to add a pending breakpoint? (y or [n]) Pending breakpoint at f() (jerry-debugger) list === Pending breakpoints === - 1: f() (pending) -(jerry-debugger) n + 1: :1 (pending) + 2: f() (pending) +(jerry-debugger) c out: pending-breakpoints -Stopped at tests/debugger/do_pending_breakpoints.js:17 -(jerry-debugger) n -Breakpoint 2 at :1 (in f() at line:1, col:1) -Stopped at tests/debugger/do_pending_breakpoints.js:19 +Breakpoint 3 at :1 +Breakpoint 4 at :3 (in f() at line:2, col:1) +Stopped at breakpoint:3 :1 +(jerry-debugger) list +=== Active breakpoints === + 3: :1 + 4: :3 (in f() at line:2, col:1) (jerry-debugger) c -Stopped at breakpoint:2 :1 (in f() at line:1, col:1) +Stopped at breakpoint:4 :3 (in f() at line:2, col:1) (jerry-debugger) c diff --git a/tests/debugger/do_pending_breakpoints.js b/tests/debugger/do_pending_breakpoints.js index a7062166a5..0e0826e46f 100644 --- a/tests/debugger/do_pending_breakpoints.js +++ b/tests/debugger/do_pending_breakpoints.js @@ -14,7 +14,7 @@ print("pending-breakpoints"); -eval("function f(){ return 5 }"); +eval("1;\nfunction f()\n{ return 5 }"); var bird = "colibri"; f();