diff --git a/jerry-core/debugger/debugger-ws.c b/jerry-core/debugger/debugger-ws.c index 8edb391a43..a19f4e80bc 100644 --- a/jerry-core/debugger/debugger-ws.c +++ b/jerry-core/debugger/debugger-ws.c @@ -46,17 +46,38 @@ */ #define JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK 0x7fu +/** + * Size of websocket header size. + */ +#define JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE 2 + /** * Payload mask size in bytes of a websocket package. */ #define JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE 4 /** - * + * Maximum message size with 1 byte size field. + */ +#define JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX 125 + +/** + * Waiting for data from the client. */ #define JERRY_DEBUGGER_RECEIVE_DATA_MODE \ (JERRY_DEBUGGER_BREAKPOINT_MODE | JERRY_DEBUGGER_CLIENT_SOURCE_MODE) +/** + * WebSocket opcode types. + */ +typedef enum +{ + JERRY_DEBUGGER_WEBSOCKET_TEXT_FRAME = 1, /**< text frame */ + JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME = 2, /**< binary frame */ + JERRY_DEBUGGER_WEBSOCKET_CLOSE_CONNECTION = 8, /**< close connection */ + JERRY_DEBUGGER_WEBSOCKET_PING = 9, /**< ping (keep alive) frame */ + JERRY_DEBUGGER_WEBSOCKET_PONG = 10, /**< reply to ping frame */ +} jerry_websocket_opcode_type_t; /** * Header for incoming packets. @@ -321,6 +342,25 @@ jerry_debugger_accept_connection (void) struct sockaddr_in addr; socklen_t sin_size = sizeof (struct sockaddr_in); + uint8_t *payload_p = JERRY_CONTEXT (debugger_send_buffer) + JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE; + JERRY_CONTEXT (debugger_send_buffer_payload_p) = payload_p; + + uint8_t max_send_size = (JERRY_DEBUGGER_MAX_BUFFER_SIZE - JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE); + if (max_send_size > JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX) + { + max_send_size = JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX; + } + JERRY_CONTEXT (debugger_max_send_size) = max_send_size; + + uint8_t receive_header_size = (JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE + JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE); + uint8_t max_receive_size = (uint8_t) (JERRY_DEBUGGER_MAX_BUFFER_SIZE - receive_header_size); + + if (max_receive_size > JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX) + { + max_receive_size = JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX; + } + JERRY_CONTEXT (debugger_max_receive_size) = max_receive_size; + addr.sin_family = AF_INET; addr.sin_port = htons (JERRY_CONTEXT (debugger_port)); addr.sin_addr.s_addr = INADDR_ANY; @@ -384,7 +424,7 @@ jerry_debugger_accept_connection (void) return false; } - if (!jerry_debugger_send_configuration (JERRY_DEBUGGER_MAX_RECEIVE_SIZE)) + if (!jerry_debugger_send_configuration (max_receive_size)) { return false; } @@ -430,14 +470,14 @@ jerry_debugger_close_connection (void) bool jerry_debugger_send (size_t data_size) /**< data size */ { - jerry_debugger_send_type_t *message_p = (jerry_debugger_send_type_t *) JERRY_CONTEXT (debugger_send_buffer); - message_p->header.ws_opcode = JERRY_DEBUGGER_WEBSOCKET_FIN_BIT | JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME; - message_p->header.size = (uint8_t) (data_size - sizeof (jerry_debugger_send_header_t)); - return jerry_debugger_send_tcp (JERRY_CONTEXT (debugger_send_buffer), data_size); -} /* jerry_debugger_send */ + JERRY_ASSERT (data_size <= JERRY_CONTEXT (debugger_max_send_size)); -JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MAX_RECEIVE_SIZE < 126, - maximum_debug_message_receive_size_must_be_smaller_than_126); + uint8_t *header_p = JERRY_CONTEXT (debugger_send_buffer); + header_p[0] = JERRY_DEBUGGER_WEBSOCKET_FIN_BIT | JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME; + header_p[1] = (uint8_t) data_size; + + return jerry_debugger_send_tcp (header_p, data_size + JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE); +} /* jerry_debugger_send */ /** * Receive message from the client. @@ -453,6 +493,7 @@ bool jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] data received from client */ { JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); + JERRY_ASSERT (JERRY_CONTEXT (debugger_max_receive_size) <= JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX); JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE) : !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)); @@ -497,7 +538,7 @@ jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] } if ((recv_buffer_p[0] & ~JERRY_DEBUGGER_WEBSOCKET_OPCODE_MASK) != JERRY_DEBUGGER_WEBSOCKET_FIN_BIT - || (recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK) > JERRY_DEBUGGER_MAX_RECEIVE_SIZE + || (recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK) > JERRY_CONTEXT (debugger_max_receive_size) || !(recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_MASK_BIT)) { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unsupported Websocket message.\n"); diff --git a/jerry-core/debugger/debugger-ws.h b/jerry-core/debugger/debugger-ws.h index 5d56743f20..3a7c97c807 100644 --- a/jerry-core/debugger/debugger-ws.h +++ b/jerry-core/debugger/debugger-ws.h @@ -27,37 +27,6 @@ */ #define JERRY_DEBUGGER_MAX_BUFFER_SIZE 128 -/** - * Maximum number of bytes that can be sent in a single message. - */ -#define JERRY_DEBUGGER_MAX_SEND_SIZE (JERRY_DEBUGGER_MAX_BUFFER_SIZE - 1) - -/** - * Maximum number of bytes that can be received in a single message. - */ -#define JERRY_DEBUGGER_MAX_RECEIVE_SIZE (JERRY_DEBUGGER_MAX_BUFFER_SIZE - 6) - -/** - * WebSocket opcode types. - */ -typedef enum -{ - JERRY_DEBUGGER_WEBSOCKET_TEXT_FRAME = 1, /**< text frame */ - JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME = 2, /**< binary frame */ - JERRY_DEBUGGER_WEBSOCKET_CLOSE_CONNECTION = 8, /**< close connection */ - JERRY_DEBUGGER_WEBSOCKET_PING = 9, /**< ping (keep alive) frame */ - JERRY_DEBUGGER_WEBSOCKET_PONG = 10, /**< reply to ping frame */ -} jerry_websocket_opcode_type_t; - -/** - * Header for outgoing packets. - */ -typedef struct -{ - uint8_t ws_opcode; /**< Websocket opcode */ - uint8_t size; /**< size of the message */ -} jerry_debugger_send_header_t; - /** * Incoming message: next message of string data. */ diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index 5df7e42d4b..0d4d45ebd4 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -37,7 +37,7 @@ JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27 * Type cast the debugger send buffer into a specific type. */ #define JERRY_DEBUGGER_SEND_BUFFER_AS(type, name_p) \ - type *name_p = (type *) (&JERRY_CONTEXT (debugger_send_buffer)) + type *name_p = (type *) (JERRY_CONTEXT (debugger_send_buffer_payload_p)) /** * Type cast the debugger receive buffer into a specific type. @@ -92,7 +92,9 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); - uint32_t current_frame = 0; + size_t current_frame = 0; + const size_t max_frame_count = JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t); + const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_frame_count, jerry_debugger_frame_t); while (frame_ctx_p != NULL && max_depth > 0) { @@ -102,9 +104,9 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei continue; } - if (current_frame >= JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t)) + if (current_frame >= max_frame_count) { - if (!jerry_debugger_send (sizeof (jerry_debugger_send_backtrace_t))) + if (!jerry_debugger_send (max_message_size)) { return; } @@ -533,7 +535,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece memcpy (&eval_size, eval_first_p->eval_size, sizeof (uint32_t)); bool is_eval = (recv_buffer_p[0] == JERRY_DEBUGGER_EVAL); - if (eval_size <= JERRY_DEBUGGER_MAX_RECEIVE_SIZE - sizeof (jerry_debugger_receive_eval_first_t)) + if (eval_size <= JERRY_CONTEXT (debugger_max_receive_size) - sizeof (jerry_debugger_receive_eval_first_t)) { if (eval_size != message_size - sizeof (jerry_debugger_receive_eval_first_t)) { @@ -590,8 +592,10 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece uint32_t client_source_size; memcpy (&client_source_size, client_source_first_p->code_size, sizeof (uint32_t)); - if (client_source_size <= JERRY_DEBUGGER_MAX_RECEIVE_SIZE - sizeof (jerry_debugger_receive_client_source_first_t) - && client_source_size != message_size - sizeof (jerry_debugger_receive_client_source_first_t)) + uint32_t header_size = sizeof (jerry_debugger_receive_client_source_first_t); + + if (client_source_size <= JERRY_CONTEXT (debugger_max_receive_size) - header_size + && client_source_size != message_size - header_size) { jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n"); jerry_debugger_close_connection (); @@ -796,37 +800,42 @@ jerry_debugger_send_string (uint8_t message_type, /**< message type */ { JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); - const size_t max_fragment_len = JERRY_DEBUGGER_SEND_MAX (uint8_t); + const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t); + const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t); JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p); message_string_p->type = message_type; - while (string_length > max_fragment_len) + if (sub_type != JERRY_DEBUGGER_NO_SUBTYPE) { - memcpy (message_string_p->string, string_p, max_fragment_len); + string_length += 1; + } - if (!jerry_debugger_send (sizeof (jerry_debugger_send_string_t))) + while (string_length > max_byte_count) + { + memcpy (message_string_p->string, string_p, max_byte_count); + + if (!jerry_debugger_send (max_message_size)) { return false; } - string_length -= max_fragment_len; - string_p += max_fragment_len; - } - - if (sub_type != JERRY_DEBUGGER_NO_SUBTYPE) - { - string_length += 1; + string_length -= max_byte_count; + string_p += max_byte_count; } message_string_p->type = (uint8_t) (message_type + 1); - memcpy (message_string_p->string, string_p, string_length); if (sub_type != JERRY_DEBUGGER_NO_SUBTYPE) { + memcpy (message_string_p->string, string_p, string_length - 1); message_string_p->string[string_length - 1] = sub_type; } + else + { + memcpy (message_string_p->string, string_p, string_length); + } return jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + string_length); } /* jerry_debugger_send_string */ diff --git a/jerry-core/debugger/debugger.h b/jerry-core/debugger/debugger.h index ff7dba2047..8e4ac0964e 100644 --- a/jerry-core/debugger/debugger.h +++ b/jerry-core/debugger/debugger.h @@ -53,10 +53,16 @@ /** * Calculate the maximum number of items for a given type - * which can be transmitted by one message. + * which can be transmitted in one message. */ #define JERRY_DEBUGGER_SEND_MAX(type) \ - ((JERRY_DEBUGGER_MAX_SEND_SIZE - sizeof (jerry_debugger_send_header_t) - 1) / sizeof (type)) + ((size_t) ((JERRY_CONTEXT (debugger_max_send_size) - sizeof (jerry_debugger_send_type_t)) / sizeof (type))) + +/** + * Calculate the size of a message when a count number of items transmitted. + */ +#define JERRY_DEBUGGER_SEND_SIZE(count, type) \ + ((size_t) ((count * sizeof (type)) + sizeof (jerry_debugger_send_type_t))) /** * Debugger operation modes: @@ -226,7 +232,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ uint8_t max_message_size; /**< maximum incoming message size */ uint8_t cpointer_size; /**< size of compressed pointers */ @@ -239,7 +244,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ } jerry_debugger_send_type_t; @@ -256,9 +260,8 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ - uint8_t string[JERRY_DEBUGGER_SEND_MAX (uint8_t)]; /**< string data */ + uint8_t string[]; /**< string data */ } jerry_debugger_send_string_t; /** @@ -266,7 +269,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ uint8_t line[sizeof (uint32_t)]; /**< value data */ uint8_t column[sizeof (uint32_t)]; /**< value data */ @@ -277,7 +279,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */ } jerry_debugger_send_byte_code_cp_t; @@ -307,7 +308,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ uint8_t allocated_bytes[sizeof (uint32_t)]; /**< allocated bytes */ uint8_t byte_code_bytes[sizeof (uint32_t)]; /**< byte code bytes */ @@ -321,7 +321,6 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */ uint8_t offset[sizeof (uint32_t)]; /**< breakpoint offset */ @@ -341,9 +340,8 @@ typedef struct */ typedef struct { - jerry_debugger_send_header_t header; /**< message header */ uint8_t type; /**< type of the message */ - jerry_debugger_frame_t frames[JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t)]; /**< frames */ + jerry_debugger_frame_t frames[]; /**< frames */ } jerry_debugger_send_backtrace_t; /** diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 148af8f0c9..f37ac27d2c 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -111,6 +111,7 @@ typedef struct #ifdef JERRY_DEBUGGER uint8_t debugger_send_buffer[JERRY_DEBUGGER_MAX_BUFFER_SIZE]; /**< buffer for sending messages */ uint8_t debugger_receive_buffer[JERRY_DEBUGGER_MAX_BUFFER_SIZE]; /**< buffer for receiving messages */ + uint8_t *debugger_send_buffer_payload_p; /**< start where the outgoing message can be written */ 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 */ @@ -118,6 +119,8 @@ typedef struct uint16_t debugger_receive_buffer_offset; /**< receive buffer offset */ uint16_t debugger_port; /**< debugger socket communication port */ uint8_t debugger_message_delay; /**< call receive message when reaches zero */ + uint8_t debugger_max_send_size; /**< maximum amount of data that can be written */ + uint8_t debugger_max_receive_size; /**< maximum amount of data that can be received */ int debugger_connection; /**< holds the file descriptor of the socket communication */ #endif /* JERRY_DEBUGGER */ diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h index 06f5873dc5..dd3a7cd526 100644 --- a/jerry-core/parser/js/js-parser-internal.h +++ b/jerry-core/parser/js/js-parser-internal.h @@ -305,7 +305,8 @@ typedef struct #endif /* PARSER_DUMP_BYTE_CODE */ #ifdef JERRY_DEBUGGER - parser_breakpoint_info_t breakpoint_info[JERRY_DEBUGGER_SEND_MAX (parser_list_t)]; /**< extra data for breakpoints */ + /** extra data for each breakpoint */ + parser_breakpoint_info_t breakpoint_info[JERRY_DEBUGGER_MAX_BUFFER_SIZE / sizeof (parser_breakpoint_info_t)]; uint16_t breakpoint_info_count; /**< current breakpoint index */ parser_line_counter_t last_breakpoint_line; /**< last line where breakpoint was inserted */ #endif /* JERRY_DEBUGGER */ diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 1b31be1739..37519c3eb7 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -2700,7 +2700,7 @@ parser_append_breakpoint_info (parser_context_t *context_p, /**< context */ context_p->status_flags |= PARSER_DEBUGGER_BREAKPOINT_APPENDED; - if (context_p->breakpoint_info_count >= JERRY_DEBUGGER_SEND_MAX (parser_list_t)) + if (context_p->breakpoint_info_count >= JERRY_DEBUGGER_SEND_MAX (parser_breakpoint_info_t)) { parser_send_breakpoints (context_p, type); }