1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "byte-code.h" 17425bb815Sopenharmony_ci#include "debugger.h" 18425bb815Sopenharmony_ci#include "ecma-array-object.h" 19425bb815Sopenharmony_ci#include "ecma-builtin-helpers.h" 20425bb815Sopenharmony_ci#include "ecma-conversion.h" 21425bb815Sopenharmony_ci#include "ecma-eval.h" 22425bb815Sopenharmony_ci#include "ecma-function-object.h" 23425bb815Sopenharmony_ci#include "ecma-objects.h" 24425bb815Sopenharmony_ci#include "jcontext.h" 25425bb815Sopenharmony_ci#include "jerryscript-port.h" 26425bb815Sopenharmony_ci#include "lit-char-helpers.h" 27425bb815Sopenharmony_ci#if defined (__APPLE__) 28425bb815Sopenharmony_ci#include <time.h> 29425bb815Sopenharmony_ci#endif 30425bb815Sopenharmony_ci 31425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 32425bb815Sopenharmony_ci 33425bb815Sopenharmony_ci/** 34425bb815Sopenharmony_ci * Incoming message: next message of string data. 35425bb815Sopenharmony_ci */ 36425bb815Sopenharmony_citypedef struct 37425bb815Sopenharmony_ci{ 38425bb815Sopenharmony_ci uint8_t type; /**< type of the message */ 39425bb815Sopenharmony_ci} jerry_debugger_receive_uint8_data_part_t; 40425bb815Sopenharmony_ci 41425bb815Sopenharmony_ci/** 42425bb815Sopenharmony_ci * The number of message types in the debugger should reflect the 43425bb815Sopenharmony_ci * debugger versioning. 44425bb815Sopenharmony_ci */ 45425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 33 46425bb815Sopenharmony_ci && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 21 47425bb815Sopenharmony_ci && JERRY_DEBUGGER_VERSION == 9, 48425bb815Sopenharmony_ci debugger_version_correlates_to_message_type_count); 49425bb815Sopenharmony_ci 50425bb815Sopenharmony_ci/** 51425bb815Sopenharmony_ci * Waiting for data from the client. 52425bb815Sopenharmony_ci */ 53425bb815Sopenharmony_ci#define JERRY_DEBUGGER_RECEIVE_DATA_MODE \ 54425bb815Sopenharmony_ci (JERRY_DEBUGGER_BREAKPOINT_MODE | JERRY_DEBUGGER_CLIENT_SOURCE_MODE) 55425bb815Sopenharmony_ci 56425bb815Sopenharmony_ci/** 57425bb815Sopenharmony_ci * Type cast the debugger send buffer into a specific type. 58425bb815Sopenharmony_ci */ 59425bb815Sopenharmony_ci#define JERRY_DEBUGGER_SEND_BUFFER_AS(type, name_p) \ 60425bb815Sopenharmony_ci type *name_p = (type *) (JERRY_CONTEXT (debugger_send_buffer_payload_p)) 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci/** 63425bb815Sopenharmony_ci * Type cast the debugger receive buffer into a specific type. 64425bb815Sopenharmony_ci */ 65425bb815Sopenharmony_ci#define JERRY_DEBUGGER_RECEIVE_BUFFER_AS(type, name_p) \ 66425bb815Sopenharmony_ci type *name_p = ((type *) recv_buffer_p) 67425bb815Sopenharmony_ci 68425bb815Sopenharmony_ci/** 69425bb815Sopenharmony_ci * Free all unreferenced byte code structures which 70425bb815Sopenharmony_ci * were not acknowledged by the debugger client. 71425bb815Sopenharmony_ci */ 72425bb815Sopenharmony_civoid 73425bb815Sopenharmony_cijerry_debugger_free_unreferenced_byte_code (void) 74425bb815Sopenharmony_ci{ 75425bb815Sopenharmony_ci jerry_debugger_byte_code_free_t *byte_code_free_p; 76425bb815Sopenharmony_ci 77425bb815Sopenharmony_ci byte_code_free_p = JMEM_CP_GET_POINTER (jerry_debugger_byte_code_free_t, 78425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_tail)); 79425bb815Sopenharmony_ci 80425bb815Sopenharmony_ci while (byte_code_free_p != NULL) 81425bb815Sopenharmony_ci { 82425bb815Sopenharmony_ci jerry_debugger_byte_code_free_t *prev_byte_code_free_p; 83425bb815Sopenharmony_ci prev_byte_code_free_p = JMEM_CP_GET_POINTER (jerry_debugger_byte_code_free_t, 84425bb815Sopenharmony_ci byte_code_free_p->prev_cp); 85425bb815Sopenharmony_ci 86425bb815Sopenharmony_ci jmem_heap_free_block (byte_code_free_p, 87425bb815Sopenharmony_ci ((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG); 88425bb815Sopenharmony_ci 89425bb815Sopenharmony_ci byte_code_free_p = prev_byte_code_free_p; 90425bb815Sopenharmony_ci } 91425bb815Sopenharmony_ci} /* jerry_debugger_free_unreferenced_byte_code */ 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci/** 94425bb815Sopenharmony_ci * Send data over an active connection. 95425bb815Sopenharmony_ci * 96425bb815Sopenharmony_ci * @return true - if the data was sent successfully 97425bb815Sopenharmony_ci * false - otherwise 98425bb815Sopenharmony_ci */ 99425bb815Sopenharmony_cistatic bool 100425bb815Sopenharmony_cijerry_debugger_send (size_t message_length) /**< message length in bytes */ 101425bb815Sopenharmony_ci{ 102425bb815Sopenharmony_ci#ifdef ACE_DEBUGGER_CUSTOM 103425bb815Sopenharmony_ci if (!((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_TRANSPORT_STARTED))) { 104425bb815Sopenharmony_ci return false; // do not send any debugger data before the hand shake done 105425bb815Sopenharmony_ci } 106425bb815Sopenharmony_ci#endif 107425bb815Sopenharmony_ci 108425bb815Sopenharmony_ci JERRY_ASSERT (message_length <= JERRY_CONTEXT (debugger_max_send_size)); 109425bb815Sopenharmony_ci 110425bb815Sopenharmony_ci jerry_debugger_transport_header_t *header_p = JERRY_CONTEXT (debugger_transport_header_p); 111425bb815Sopenharmony_ci uint8_t *payload_p = JERRY_CONTEXT (debugger_send_buffer_payload_p); 112425bb815Sopenharmony_ci 113425bb815Sopenharmony_ci return header_p->send (header_p, payload_p, message_length); 114425bb815Sopenharmony_ci} /* jerry_debugger_send */ 115425bb815Sopenharmony_ci 116425bb815Sopenharmony_ci/** 117425bb815Sopenharmony_ci * Send backtrace. 118425bb815Sopenharmony_ci */ 119425bb815Sopenharmony_cistatic void 120425bb815Sopenharmony_cijerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the received data */ 121425bb815Sopenharmony_ci{ 122425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_get_backtrace_t, get_backtrace_p); 123425bb815Sopenharmony_ci 124425bb815Sopenharmony_ci uint32_t min_depth; 125425bb815Sopenharmony_ci memcpy (&min_depth, get_backtrace_p->min_depth, sizeof (uint32_t)); 126425bb815Sopenharmony_ci uint32_t max_depth; 127425bb815Sopenharmony_ci memcpy (&max_depth, get_backtrace_p->max_depth, sizeof (uint32_t)); 128425bb815Sopenharmony_ci 129425bb815Sopenharmony_ci if (max_depth == 0) 130425bb815Sopenharmony_ci { 131425bb815Sopenharmony_ci max_depth = UINT32_MAX; 132425bb815Sopenharmony_ci } 133425bb815Sopenharmony_ci 134425bb815Sopenharmony_ci if (get_backtrace_p->get_total_frame_count != 0) 135425bb815Sopenharmony_ci { 136425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_total_t, backtrace_total_p); 137425bb815Sopenharmony_ci backtrace_total_p->type = JERRY_DEBUGGER_BACKTRACE_TOTAL; 138425bb815Sopenharmony_ci 139425bb815Sopenharmony_ci vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); 140425bb815Sopenharmony_ci uint32_t frame_count = 0; 141425bb815Sopenharmony_ci while (iter_frame_ctx_p != NULL) 142425bb815Sopenharmony_ci { 143425bb815Sopenharmony_ci if (!(iter_frame_ctx_p->bytecode_header_p->status_flags & (CBC_CODE_FLAGS_STATIC_FUNCTION))) 144425bb815Sopenharmony_ci { 145425bb815Sopenharmony_ci frame_count++; 146425bb815Sopenharmony_ci } 147425bb815Sopenharmony_ci iter_frame_ctx_p = iter_frame_ctx_p->prev_context_p; 148425bb815Sopenharmony_ci } 149425bb815Sopenharmony_ci memcpy (backtrace_total_p->frame_count, &frame_count, sizeof (frame_count)); 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + sizeof (frame_count)); 152425bb815Sopenharmony_ci } 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_t, backtrace_p); 155425bb815Sopenharmony_ci 156425bb815Sopenharmony_ci backtrace_p->type = JERRY_DEBUGGER_BACKTRACE; 157425bb815Sopenharmony_ci 158425bb815Sopenharmony_ci vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); 159425bb815Sopenharmony_ci 160425bb815Sopenharmony_ci size_t current_frame = 0; 161425bb815Sopenharmony_ci const size_t max_frame_count = JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t); 162425bb815Sopenharmony_ci const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_frame_count, jerry_debugger_frame_t); 163425bb815Sopenharmony_ci 164425bb815Sopenharmony_ci if (min_depth <= max_depth) 165425bb815Sopenharmony_ci { 166425bb815Sopenharmony_ci uint32_t min_depth_offset = 0; 167425bb815Sopenharmony_ci 168425bb815Sopenharmony_ci while (frame_ctx_p != NULL && min_depth_offset < min_depth) 169425bb815Sopenharmony_ci { 170425bb815Sopenharmony_ci frame_ctx_p = frame_ctx_p->prev_context_p; 171425bb815Sopenharmony_ci min_depth_offset++; 172425bb815Sopenharmony_ci } 173425bb815Sopenharmony_ci 174425bb815Sopenharmony_ci while (frame_ctx_p != NULL && min_depth_offset++ < max_depth) 175425bb815Sopenharmony_ci { 176425bb815Sopenharmony_ci if (frame_ctx_p->bytecode_header_p->status_flags 177425bb815Sopenharmony_ci & (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION)) 178425bb815Sopenharmony_ci { 179425bb815Sopenharmony_ci frame_ctx_p = frame_ctx_p->prev_context_p; 180425bb815Sopenharmony_ci continue; 181425bb815Sopenharmony_ci } 182425bb815Sopenharmony_ci 183425bb815Sopenharmony_ci if (current_frame >= max_frame_count) 184425bb815Sopenharmony_ci { 185425bb815Sopenharmony_ci if (!jerry_debugger_send (max_message_size)) 186425bb815Sopenharmony_ci { 187425bb815Sopenharmony_ci return; 188425bb815Sopenharmony_ci } 189425bb815Sopenharmony_ci current_frame = 0; 190425bb815Sopenharmony_ci } 191425bb815Sopenharmony_ci 192425bb815Sopenharmony_ci jerry_debugger_frame_t *frame_p = backtrace_p->frames + current_frame; 193425bb815Sopenharmony_ci 194425bb815Sopenharmony_ci jmem_cpointer_t byte_code_cp; 195425bb815Sopenharmony_ci JMEM_CP_SET_NON_NULL_POINTER (byte_code_cp, frame_ctx_p->bytecode_header_p); 196425bb815Sopenharmony_ci memcpy (frame_p->byte_code_cp, &byte_code_cp, sizeof (jmem_cpointer_t)); 197425bb815Sopenharmony_ci 198425bb815Sopenharmony_ci uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p); 199425bb815Sopenharmony_ci memcpy (frame_p->offset, &offset, sizeof (uint32_t)); 200425bb815Sopenharmony_ci 201425bb815Sopenharmony_ci frame_ctx_p = frame_ctx_p->prev_context_p; 202425bb815Sopenharmony_ci current_frame++; 203425bb815Sopenharmony_ci } 204425bb815Sopenharmony_ci } 205425bb815Sopenharmony_ci 206425bb815Sopenharmony_ci size_t message_size = current_frame * sizeof (jerry_debugger_frame_t); 207425bb815Sopenharmony_ci 208425bb815Sopenharmony_ci backtrace_p->type = JERRY_DEBUGGER_BACKTRACE_END; 209425bb815Sopenharmony_ci 210425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + message_size); 211425bb815Sopenharmony_ci} /* jerry_debugger_send_backtrace */ 212425bb815Sopenharmony_ci 213425bb815Sopenharmony_ci/** 214425bb815Sopenharmony_ci * Send the scope chain types. 215425bb815Sopenharmony_ci */ 216425bb815Sopenharmony_cistatic void 217425bb815Sopenharmony_cijerry_debugger_send_scope_chain (void) 218425bb815Sopenharmony_ci{ 219425bb815Sopenharmony_ci vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); 220425bb815Sopenharmony_ci 221425bb815Sopenharmony_ci const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t); 222425bb815Sopenharmony_ci const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t); 223425bb815Sopenharmony_ci 224425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_type_p); 225425bb815Sopenharmony_ci message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN; 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci size_t buffer_pos = 0; 228425bb815Sopenharmony_ci bool next_func_is_local = true; 229425bb815Sopenharmony_ci ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p; 230425bb815Sopenharmony_ci 231425bb815Sopenharmony_ci while (true) 232425bb815Sopenharmony_ci { 233425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (lex_env_p)); 234425bb815Sopenharmony_ci 235425bb815Sopenharmony_ci if (buffer_pos == max_byte_count) 236425bb815Sopenharmony_ci { 237425bb815Sopenharmony_ci if (!jerry_debugger_send (max_message_size)) 238425bb815Sopenharmony_ci { 239425bb815Sopenharmony_ci return; 240425bb815Sopenharmony_ci } 241425bb815Sopenharmony_ci 242425bb815Sopenharmony_ci buffer_pos = 0; 243425bb815Sopenharmony_ci } 244425bb815Sopenharmony_ci 245425bb815Sopenharmony_ci if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 246425bb815Sopenharmony_ci { 247425bb815Sopenharmony_ci if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) != 0) 248425bb815Sopenharmony_ci { 249425bb815Sopenharmony_ci message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_NON_CLOSURE; 250425bb815Sopenharmony_ci } 251425bb815Sopenharmony_ci else if (next_func_is_local) 252425bb815Sopenharmony_ci { 253425bb815Sopenharmony_ci message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_LOCAL; 254425bb815Sopenharmony_ci next_func_is_local = false; 255425bb815Sopenharmony_ci } 256425bb815Sopenharmony_ci else 257425bb815Sopenharmony_ci { 258425bb815Sopenharmony_ci message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_CLOSURE; 259425bb815Sopenharmony_ci } 260425bb815Sopenharmony_ci } 261425bb815Sopenharmony_ci else if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) 262425bb815Sopenharmony_ci { 263425bb815Sopenharmony_ci if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL) 264425bb815Sopenharmony_ci { 265425bb815Sopenharmony_ci message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_GLOBAL; 266425bb815Sopenharmony_ci break; 267425bb815Sopenharmony_ci } 268425bb815Sopenharmony_ci else 269425bb815Sopenharmony_ci { 270425bb815Sopenharmony_ci message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_WITH; 271425bb815Sopenharmony_ci } 272425bb815Sopenharmony_ci } 273425bb815Sopenharmony_ci 274425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 275425bb815Sopenharmony_ci lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 276425bb815Sopenharmony_ci } 277425bb815Sopenharmony_ci 278425bb815Sopenharmony_ci message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN_END; 279425bb815Sopenharmony_ci 280425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + buffer_pos); 281425bb815Sopenharmony_ci} /* jerry_debugger_send_scope_chain */ 282425bb815Sopenharmony_ci 283425bb815Sopenharmony_ci/** 284425bb815Sopenharmony_ci * Get type of the scope variable property. 285425bb815Sopenharmony_ci * @return (jerry_debugger_scope_variable_type_t) 286425bb815Sopenharmony_ci */ 287425bb815Sopenharmony_cistatic uint8_t 288425bb815Sopenharmony_cijerry_debugger_get_variable_type (ecma_value_t value) /**< input ecma value */ 289425bb815Sopenharmony_ci{ 290425bb815Sopenharmony_ci uint8_t ret_value = JERRY_DEBUGGER_VALUE_NONE; 291425bb815Sopenharmony_ci 292425bb815Sopenharmony_ci if (ecma_is_value_undefined (value)) 293425bb815Sopenharmony_ci { 294425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_UNDEFINED; 295425bb815Sopenharmony_ci } 296425bb815Sopenharmony_ci else if (ecma_is_value_null (value)) 297425bb815Sopenharmony_ci { 298425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_NULL; 299425bb815Sopenharmony_ci } 300425bb815Sopenharmony_ci else if (ecma_is_value_boolean (value)) 301425bb815Sopenharmony_ci { 302425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_BOOLEAN; 303425bb815Sopenharmony_ci } 304425bb815Sopenharmony_ci else if (ecma_is_value_number (value)) 305425bb815Sopenharmony_ci { 306425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_NUMBER; 307425bb815Sopenharmony_ci } 308425bb815Sopenharmony_ci else if (ecma_is_value_string (value)) 309425bb815Sopenharmony_ci { 310425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_STRING; 311425bb815Sopenharmony_ci } 312425bb815Sopenharmony_ci else 313425bb815Sopenharmony_ci { 314425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (value)); 315425bb815Sopenharmony_ci 316425bb815Sopenharmony_ci if (ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY) 317425bb815Sopenharmony_ci { 318425bb815Sopenharmony_ci ret_value = JERRY_DEBUGGER_VALUE_ARRAY; 319425bb815Sopenharmony_ci } 320425bb815Sopenharmony_ci else 321425bb815Sopenharmony_ci { 322425bb815Sopenharmony_ci ret_value = ecma_op_is_callable (value) ? JERRY_DEBUGGER_VALUE_FUNCTION : JERRY_DEBUGGER_VALUE_OBJECT; 323425bb815Sopenharmony_ci } 324425bb815Sopenharmony_ci } 325425bb815Sopenharmony_ci 326425bb815Sopenharmony_ci JERRY_ASSERT (ret_value != JERRY_DEBUGGER_VALUE_NONE); 327425bb815Sopenharmony_ci 328425bb815Sopenharmony_ci return ret_value; 329425bb815Sopenharmony_ci} /* jerry_debugger_get_variable_type */ 330425bb815Sopenharmony_ci 331425bb815Sopenharmony_ci/** 332425bb815Sopenharmony_ci * Helper function for jerry_debugger_send_scope_variables. 333425bb815Sopenharmony_ci * 334425bb815Sopenharmony_ci * It will copies the given scope values type, length and value into the outgoing message string. 335425bb815Sopenharmony_ci * 336425bb815Sopenharmony_ci * @param variable_type type (jerry_debugger_scope_variable_type_t) 337425bb815Sopenharmony_ci * @return true - if the copy was successfully 338425bb815Sopenharmony_ci * false - otherwise 339425bb815Sopenharmony_ci */ 340425bb815Sopenharmony_cistatic bool 341425bb815Sopenharmony_cijerry_debugger_copy_variables_to_string_message (uint8_t variable_type, /**< type */ 342425bb815Sopenharmony_ci ecma_string_t *value_str, /**< property name or value string */ 343425bb815Sopenharmony_ci jerry_debugger_send_string_t *message_string_p, /**< msg pointer */ 344425bb815Sopenharmony_ci size_t *buffer_pos) /**< string data position of the message */ 345425bb815Sopenharmony_ci{ 346425bb815Sopenharmony_ci const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t); 347425bb815Sopenharmony_ci const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t); 348425bb815Sopenharmony_ci 349425bb815Sopenharmony_ci ECMA_STRING_TO_UTF8_STRING (value_str, str_buff, str_buff_size); 350425bb815Sopenharmony_ci 351425bb815Sopenharmony_ci size_t str_size = 0; 352425bb815Sopenharmony_ci size_t str_limit = 255; 353425bb815Sopenharmony_ci bool result = true; 354425bb815Sopenharmony_ci 355425bb815Sopenharmony_ci bool type_processed = false; 356425bb815Sopenharmony_ci 357425bb815Sopenharmony_ci while (true) 358425bb815Sopenharmony_ci { 359425bb815Sopenharmony_ci if (*buffer_pos == max_byte_count) 360425bb815Sopenharmony_ci { 361425bb815Sopenharmony_ci if (!jerry_debugger_send (max_message_size)) 362425bb815Sopenharmony_ci { 363425bb815Sopenharmony_ci result = false; 364425bb815Sopenharmony_ci break; 365425bb815Sopenharmony_ci } 366425bb815Sopenharmony_ci 367425bb815Sopenharmony_ci *buffer_pos = 0; 368425bb815Sopenharmony_ci } 369425bb815Sopenharmony_ci 370425bb815Sopenharmony_ci if (!type_processed) 371425bb815Sopenharmony_ci { 372425bb815Sopenharmony_ci if (variable_type != JERRY_DEBUGGER_VALUE_NONE) 373425bb815Sopenharmony_ci { 374425bb815Sopenharmony_ci message_string_p->string[*buffer_pos] = variable_type; 375425bb815Sopenharmony_ci *buffer_pos += 1; 376425bb815Sopenharmony_ci } 377425bb815Sopenharmony_ci type_processed = true; 378425bb815Sopenharmony_ci continue; 379425bb815Sopenharmony_ci } 380425bb815Sopenharmony_ci 381425bb815Sopenharmony_ci if (variable_type == JERRY_DEBUGGER_VALUE_FUNCTION) 382425bb815Sopenharmony_ci { 383425bb815Sopenharmony_ci str_size = 0; // do not copy function values 384425bb815Sopenharmony_ci } 385425bb815Sopenharmony_ci else 386425bb815Sopenharmony_ci { 387425bb815Sopenharmony_ci str_size = (str_buff_size > str_limit) ? str_limit : str_buff_size; 388425bb815Sopenharmony_ci } 389425bb815Sopenharmony_ci 390425bb815Sopenharmony_ci message_string_p->string[*buffer_pos] = (uint8_t) str_size; 391425bb815Sopenharmony_ci *buffer_pos += 1; 392425bb815Sopenharmony_ci break; 393425bb815Sopenharmony_ci } 394425bb815Sopenharmony_ci 395425bb815Sopenharmony_ci if (result) 396425bb815Sopenharmony_ci { 397425bb815Sopenharmony_ci size_t free_bytes = max_byte_count - *buffer_pos; 398425bb815Sopenharmony_ci const uint8_t *string_p = str_buff; 399425bb815Sopenharmony_ci 400425bb815Sopenharmony_ci while (str_size > free_bytes) 401425bb815Sopenharmony_ci { 402425bb815Sopenharmony_ci memcpy (message_string_p->string + *buffer_pos, string_p, free_bytes); 403425bb815Sopenharmony_ci 404425bb815Sopenharmony_ci if (!jerry_debugger_send (max_message_size)) 405425bb815Sopenharmony_ci { 406425bb815Sopenharmony_ci result = false; 407425bb815Sopenharmony_ci break; 408425bb815Sopenharmony_ci } 409425bb815Sopenharmony_ci 410425bb815Sopenharmony_ci string_p += free_bytes; 411425bb815Sopenharmony_ci str_size -= free_bytes; 412425bb815Sopenharmony_ci free_bytes = max_byte_count; 413425bb815Sopenharmony_ci *buffer_pos = 0; 414425bb815Sopenharmony_ci } 415425bb815Sopenharmony_ci 416425bb815Sopenharmony_ci if (result) 417425bb815Sopenharmony_ci { 418425bb815Sopenharmony_ci memcpy (message_string_p->string + *buffer_pos, string_p, str_size); 419425bb815Sopenharmony_ci *buffer_pos += str_size; 420425bb815Sopenharmony_ci } 421425bb815Sopenharmony_ci } 422425bb815Sopenharmony_ci 423425bb815Sopenharmony_ci ECMA_FINALIZE_UTF8_STRING (str_buff, str_buff_size); 424425bb815Sopenharmony_ci 425425bb815Sopenharmony_ci return result; 426425bb815Sopenharmony_ci} /* jerry_debugger_copy_variables_to_string_message */ 427425bb815Sopenharmony_ci 428425bb815Sopenharmony_ci/** 429425bb815Sopenharmony_ci * Send variables of the given scope chain level. 430425bb815Sopenharmony_ci */ 431425bb815Sopenharmony_cistatic void 432425bb815Sopenharmony_cijerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer to the received data */ 433425bb815Sopenharmony_ci{ 434425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_get_scope_variables_t, get_scope_variables_p); 435425bb815Sopenharmony_ci 436425bb815Sopenharmony_ci uint32_t chain_index; 437425bb815Sopenharmony_ci memcpy (&chain_index, get_scope_variables_p->chain_index, sizeof (uint32_t)); 438425bb815Sopenharmony_ci 439425bb815Sopenharmony_ci vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); 440425bb815Sopenharmony_ci ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p; 441425bb815Sopenharmony_ci 442425bb815Sopenharmony_ci while (chain_index != 0) 443425bb815Sopenharmony_ci { 444425bb815Sopenharmony_ci if (JERRY_UNLIKELY (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)) 445425bb815Sopenharmony_ci { 446425bb815Sopenharmony_ci jerry_debugger_send_type (JERRY_DEBUGGER_SCOPE_VARIABLES_END); 447425bb815Sopenharmony_ci return; 448425bb815Sopenharmony_ci } 449425bb815Sopenharmony_ci 450425bb815Sopenharmony_ci lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 451425bb815Sopenharmony_ci 452425bb815Sopenharmony_ci if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) 453425bb815Sopenharmony_ci || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)) 454425bb815Sopenharmony_ci { 455425bb815Sopenharmony_ci chain_index--; 456425bb815Sopenharmony_ci } 457425bb815Sopenharmony_ci } 458425bb815Sopenharmony_ci 459425bb815Sopenharmony_ci jmem_cpointer_t prop_iter_cp; 460425bb815Sopenharmony_ci 461425bb815Sopenharmony_ci if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) 462425bb815Sopenharmony_ci { 463425bb815Sopenharmony_ci prop_iter_cp = lex_env_p->u1.property_list_cp; 464425bb815Sopenharmony_ci } 465425bb815Sopenharmony_ci else 466425bb815Sopenharmony_ci { 467425bb815Sopenharmony_ci JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); 468425bb815Sopenharmony_ci ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); 469425bb815Sopenharmony_ci 470425bb815Sopenharmony_ci if (JERRY_UNLIKELY (ecma_op_object_is_fast_array (binding_obj_p))) 471425bb815Sopenharmony_ci { 472425bb815Sopenharmony_ci ecma_fast_array_convert_to_normal (binding_obj_p); 473425bb815Sopenharmony_ci } 474425bb815Sopenharmony_ci 475425bb815Sopenharmony_ci prop_iter_cp = binding_obj_p->u1.property_list_cp; 476425bb815Sopenharmony_ci } 477425bb815Sopenharmony_ci 478425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p); 479425bb815Sopenharmony_ci message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES; 480425bb815Sopenharmony_ci 481425bb815Sopenharmony_ci size_t buffer_pos = 0; 482425bb815Sopenharmony_ci 483425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL) 484425bb815Sopenharmony_ci { 485425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 486425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 487425bb815Sopenharmony_ci 488425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 489425bb815Sopenharmony_ci 490425bb815Sopenharmony_ci for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) 491425bb815Sopenharmony_ci { 492425bb815Sopenharmony_ci if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i])) 493425bb815Sopenharmony_ci { 494425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[i]) == ECMA_DIRECT_STRING_MAGIC 495425bb815Sopenharmony_ci && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT) 496425bb815Sopenharmony_ci { 497425bb815Sopenharmony_ci continue; 498425bb815Sopenharmony_ci } 499425bb815Sopenharmony_ci 500425bb815Sopenharmony_ci ecma_string_t *prop_name = ecma_string_from_property_name (prop_iter_p->types[i], 501425bb815Sopenharmony_ci prop_pair_p->names_cp[i]); 502425bb815Sopenharmony_ci 503425bb815Sopenharmony_ci if (!jerry_debugger_copy_variables_to_string_message (JERRY_DEBUGGER_VALUE_NONE, 504425bb815Sopenharmony_ci prop_name, 505425bb815Sopenharmony_ci message_string_p, 506425bb815Sopenharmony_ci &buffer_pos)) 507425bb815Sopenharmony_ci { 508425bb815Sopenharmony_ci ecma_deref_ecma_string (prop_name); 509425bb815Sopenharmony_ci return; 510425bb815Sopenharmony_ci } 511425bb815Sopenharmony_ci 512425bb815Sopenharmony_ci ecma_deref_ecma_string (prop_name); 513425bb815Sopenharmony_ci 514425bb815Sopenharmony_ci ecma_property_value_t prop_value_p = prop_pair_p->values[i]; 515425bb815Sopenharmony_ci 516425bb815Sopenharmony_ci uint8_t variable_type = jerry_debugger_get_variable_type (prop_value_p.value); 517425bb815Sopenharmony_ci 518425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_op_to_string (prop_value_p.value); 519425bb815Sopenharmony_ci JERRY_ASSERT (str_p != NULL); 520425bb815Sopenharmony_ci 521425bb815Sopenharmony_ci if (!jerry_debugger_copy_variables_to_string_message (variable_type, 522425bb815Sopenharmony_ci str_p, 523425bb815Sopenharmony_ci message_string_p, 524425bb815Sopenharmony_ci &buffer_pos)) 525425bb815Sopenharmony_ci { 526425bb815Sopenharmony_ci ecma_deref_ecma_string (str_p); 527425bb815Sopenharmony_ci return; 528425bb815Sopenharmony_ci } 529425bb815Sopenharmony_ci 530425bb815Sopenharmony_ci ecma_deref_ecma_string (str_p); 531425bb815Sopenharmony_ci } 532425bb815Sopenharmony_ci } 533425bb815Sopenharmony_ci 534425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 535425bb815Sopenharmony_ci } 536425bb815Sopenharmony_ci 537425bb815Sopenharmony_ci message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES_END; 538425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + buffer_pos); 539425bb815Sopenharmony_ci} /* jerry_debugger_send_scope_variables */ 540425bb815Sopenharmony_ci 541425bb815Sopenharmony_ci/** 542425bb815Sopenharmony_ci * Send result of evaluated expression or throw an error. 543425bb815Sopenharmony_ci * 544425bb815Sopenharmony_ci * @return true - if execution should be resumed 545425bb815Sopenharmony_ci * false - otherwise 546425bb815Sopenharmony_ci */ 547425bb815Sopenharmony_cistatic bool 548425bb815Sopenharmony_cijerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated string */ 549425bb815Sopenharmony_ci size_t eval_string_size) /**< evaluated string size */ 550425bb815Sopenharmony_ci{ 551425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 552425bb815Sopenharmony_ci JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)); 553425bb815Sopenharmony_ci 554425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE); 555425bb815Sopenharmony_ci 556425bb815Sopenharmony_ci uint32_t chain_index; 557425bb815Sopenharmony_ci memcpy (&chain_index, eval_string_p, sizeof (uint32_t)); 558425bb815Sopenharmony_ci uint32_t parse_opts = ECMA_PARSE_DIRECT_EVAL | (chain_index << ECMA_PARSE_CHAIN_INDEX_SHIFT); 559425bb815Sopenharmony_ci 560425bb815Sopenharmony_ci ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p + 5, eval_string_size - 5, parse_opts); 561425bb815Sopenharmony_ci 562425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (result)) 563425bb815Sopenharmony_ci { 564425bb815Sopenharmony_ci if (eval_string_p[4] != JERRY_DEBUGGER_EVAL_EVAL) 565425bb815Sopenharmony_ci { 566425bb815Sopenharmony_ci JERRY_ASSERT (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW || eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT); 567425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 568425bb815Sopenharmony_ci 569425bb815Sopenharmony_ci /* Stop where the error is caught. */ 570425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); 571425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = NULL; 572425bb815Sopenharmony_ci 573425bb815Sopenharmony_ci jcontext_raise_exception (result); 574425bb815Sopenharmony_ci jcontext_set_abort_flag (eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT); 575425bb815Sopenharmony_ci 576425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE); 577425bb815Sopenharmony_ci return true; 578425bb815Sopenharmony_ci } 579425bb815Sopenharmony_ci 580425bb815Sopenharmony_ci if (!ecma_is_value_string (result)) 581425bb815Sopenharmony_ci { 582425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_op_to_string (result); 583425bb815Sopenharmony_ci ecma_value_t to_string_value = ecma_make_string_value (str_p); 584425bb815Sopenharmony_ci ecma_free_value (result); 585425bb815Sopenharmony_ci result = to_string_value; 586425bb815Sopenharmony_ci } 587425bb815Sopenharmony_ci } 588425bb815Sopenharmony_ci 589425bb815Sopenharmony_ci ecma_value_t message = result; 590425bb815Sopenharmony_ci uint8_t type = JERRY_DEBUGGER_EVAL_OK; 591425bb815Sopenharmony_ci 592425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (result)) 593425bb815Sopenharmony_ci { 594425bb815Sopenharmony_ci type = JERRY_DEBUGGER_EVAL_ERROR; 595425bb815Sopenharmony_ci result = JERRY_CONTEXT (error_value); 596425bb815Sopenharmony_ci 597425bb815Sopenharmony_ci if (ecma_is_value_object (result)) 598425bb815Sopenharmony_ci { 599425bb815Sopenharmony_ci message = ecma_op_object_find (ecma_get_object_from_value (result), 600425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE)); 601425bb815Sopenharmony_ci 602425bb815Sopenharmony_ci if (!ecma_is_value_string (message) 603425bb815Sopenharmony_ci || ecma_string_is_empty (ecma_get_string_from_value (message))) 604425bb815Sopenharmony_ci { 605425bb815Sopenharmony_ci ecma_free_value (message); 606425bb815Sopenharmony_ci lit_magic_string_id_t id = ecma_object_get_class_name (ecma_get_object_from_value (result)); 607425bb815Sopenharmony_ci ecma_free_value (result); 608425bb815Sopenharmony_ci 609425bb815Sopenharmony_ci const lit_utf8_byte_t *string_p = lit_get_magic_string_utf8 (id); 610425bb815Sopenharmony_ci jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT, 611425bb815Sopenharmony_ci type, 612425bb815Sopenharmony_ci string_p, 613425bb815Sopenharmony_ci strlen ((const char *) string_p)); 614425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE); 615425bb815Sopenharmony_ci return false; 616425bb815Sopenharmony_ci } 617425bb815Sopenharmony_ci } 618425bb815Sopenharmony_ci else 619425bb815Sopenharmony_ci { 620425bb815Sopenharmony_ci /* Primitive type. */ 621425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_op_to_string (result); 622425bb815Sopenharmony_ci JERRY_ASSERT (str_p != NULL); 623425bb815Sopenharmony_ci 624425bb815Sopenharmony_ci message = ecma_make_string_value (str_p); 625425bb815Sopenharmony_ci } 626425bb815Sopenharmony_ci 627425bb815Sopenharmony_ci ecma_free_value (result); 628425bb815Sopenharmony_ci } 629425bb815Sopenharmony_ci 630425bb815Sopenharmony_ci ecma_string_t *string_p = ecma_get_string_from_value (message); 631425bb815Sopenharmony_ci 632425bb815Sopenharmony_ci ECMA_STRING_TO_UTF8_STRING (string_p, buffer_p, buffer_size); 633425bb815Sopenharmony_ci jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT, type, buffer_p, buffer_size); 634425bb815Sopenharmony_ci ECMA_FINALIZE_UTF8_STRING (buffer_p, buffer_size); 635425bb815Sopenharmony_ci 636425bb815Sopenharmony_ci ecma_free_value (message); 637425bb815Sopenharmony_ci 638425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE); 639425bb815Sopenharmony_ci return false; 640425bb815Sopenharmony_ci} /* jerry_debugger_send_eval */ 641425bb815Sopenharmony_ci 642425bb815Sopenharmony_ci/** 643425bb815Sopenharmony_ci * Check received packet size. 644425bb815Sopenharmony_ci */ 645425bb815Sopenharmony_ci#define JERRY_DEBUGGER_CHECK_PACKET_SIZE(type) \ 646425bb815Sopenharmony_ci if (message_size != sizeof (type)) \ 647425bb815Sopenharmony_ci { \ 648425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); \ 649425bb815Sopenharmony_ci jerry_debugger_transport_close (); \ 650425bb815Sopenharmony_ci return false; \ 651425bb815Sopenharmony_ci } 652425bb815Sopenharmony_ci 653425bb815Sopenharmony_ci#ifdef ACE_DEBUGGER_CUSTOM 654425bb815Sopenharmony_ci#define ENUM_TYPE_TO_STRING_CASE(x) case x: return(#x); 655425bb815Sopenharmony_cistatic inline const char *jerry_debugger_package_type_string(jerry_debugger_header_type_t type) 656425bb815Sopenharmony_ci{ 657425bb815Sopenharmony_ci switch (type) 658425bb815Sopenharmony_ci { 659425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_FREE_BYTE_CODE_CP) 660425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_UPDATE_BREAKPOINT) 661425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_EXCEPTION_CONFIG) 662425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_PARSER_CONFIG) 663425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_MEMSTATS) 664425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_STOP) 665425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_PARSER_RESUME) 666425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_CLIENT_SOURCE) 667425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_CLIENT_SOURCE_PART) 668425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_NO_MORE_SOURCES) 669425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_CONTEXT_RESET) 670425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_CONTINUE) 671425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_STEP) 672425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_NEXT) 673425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_FINISH) 674425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_GET_BACKTRACE) 675425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_EVAL) 676425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_EVAL_PART) 677425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_GET_SCOPE_CHAIN) 678425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_GET_SCOPE_VARIABLES) 679425bb815Sopenharmony_ci ENUM_TYPE_TO_STRING_CASE(JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT) 680425bb815Sopenharmony_ci default: 681425bb815Sopenharmony_ci return "Unsupported jerry_debugger request from client"; 682425bb815Sopenharmony_ci } 683425bb815Sopenharmony_ci return "Unsupported jerry_debugger request from client"; 684425bb815Sopenharmony_ci} 685425bb815Sopenharmony_ci#endif 686425bb815Sopenharmony_ci 687425bb815Sopenharmony_ci/** 688425bb815Sopenharmony_ci * Receive message from the client. 689425bb815Sopenharmony_ci * 690425bb815Sopenharmony_ci * @return true - if message is processed successfully 691425bb815Sopenharmony_ci * false - otherwise 692425bb815Sopenharmony_ci */ 693425bb815Sopenharmony_cistatic inline bool JERRY_ATTR_ALWAYS_INLINE 694425bb815Sopenharmony_cijerry_debugger_process_message (const uint8_t *recv_buffer_p, /**< pointer to the received data */ 695425bb815Sopenharmony_ci uint32_t message_size, /**< message size */ 696425bb815Sopenharmony_ci bool *resume_exec_p, /**< pointer to the resume exec flag */ 697425bb815Sopenharmony_ci uint8_t *expected_message_type_p, /**< message type */ 698425bb815Sopenharmony_ci jerry_debugger_uint8_data_t **message_data_p) /**< custom message data */ 699425bb815Sopenharmony_ci{ 700425bb815Sopenharmony_ci /* Process the received message. */ 701425bb815Sopenharmony_ci 702425bb815Sopenharmony_ci if (recv_buffer_p[0] >= JERRY_DEBUGGER_CONTINUE 703425bb815Sopenharmony_ci && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE)) 704425bb815Sopenharmony_ci { 705425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Message requires breakpoint mode\n"); 706425bb815Sopenharmony_ci jerry_debugger_transport_close (); 707425bb815Sopenharmony_ci return false; 708425bb815Sopenharmony_ci } 709425bb815Sopenharmony_ci 710425bb815Sopenharmony_ci#ifdef ACE_DEBUGGER_CUSTOM 711425bb815Sopenharmony_ci JERRY_DEBUG_MSG("debugger server: received [%s] from client\n", jerry_debugger_package_type_string(recv_buffer_p[0])); 712425bb815Sopenharmony_ci#endif 713425bb815Sopenharmony_ci 714425bb815Sopenharmony_ci if (*expected_message_type_p != 0) 715425bb815Sopenharmony_ci { 716425bb815Sopenharmony_ci JERRY_ASSERT (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART 717425bb815Sopenharmony_ci || *expected_message_type_p == JERRY_DEBUGGER_CLIENT_SOURCE_PART); 718425bb815Sopenharmony_ci 719425bb815Sopenharmony_ci jerry_debugger_uint8_data_t *uint8_data_p = (jerry_debugger_uint8_data_t *) *message_data_p; 720425bb815Sopenharmony_ci 721425bb815Sopenharmony_ci if (recv_buffer_p[0] != *expected_message_type_p) 722425bb815Sopenharmony_ci { 723425bb815Sopenharmony_ci jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t)); 724425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Unexpected message\n"); 725425bb815Sopenharmony_ci jerry_debugger_transport_close (); 726425bb815Sopenharmony_ci return false; 727425bb815Sopenharmony_ci } 728425bb815Sopenharmony_ci 729425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_uint8_data_part_t, uint8_data_part_p); 730425bb815Sopenharmony_ci 731425bb815Sopenharmony_ci if (message_size < sizeof (jerry_debugger_receive_uint8_data_part_t) + 1) 732425bb815Sopenharmony_ci { 733425bb815Sopenharmony_ci jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t)); 734425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 735425bb815Sopenharmony_ci jerry_debugger_transport_close (); 736425bb815Sopenharmony_ci return false; 737425bb815Sopenharmony_ci } 738425bb815Sopenharmony_ci 739425bb815Sopenharmony_ci uint32_t expected_data = uint8_data_p->uint8_size - uint8_data_p->uint8_offset; 740425bb815Sopenharmony_ci 741425bb815Sopenharmony_ci message_size -= (uint32_t) sizeof (jerry_debugger_receive_uint8_data_part_t); 742425bb815Sopenharmony_ci 743425bb815Sopenharmony_ci if (message_size > expected_data) 744425bb815Sopenharmony_ci { 745425bb815Sopenharmony_ci jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t)); 746425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 747425bb815Sopenharmony_ci jerry_debugger_transport_close (); 748425bb815Sopenharmony_ci return false; 749425bb815Sopenharmony_ci } 750425bb815Sopenharmony_ci 751425bb815Sopenharmony_ci lit_utf8_byte_t *string_p = (lit_utf8_byte_t *) (uint8_data_p + 1); 752425bb815Sopenharmony_ci memcpy (string_p + uint8_data_p->uint8_offset, 753425bb815Sopenharmony_ci (lit_utf8_byte_t *) (uint8_data_part_p + 1), 754425bb815Sopenharmony_ci message_size); 755425bb815Sopenharmony_ci 756425bb815Sopenharmony_ci if (message_size < expected_data) 757425bb815Sopenharmony_ci { 758425bb815Sopenharmony_ci uint8_data_p->uint8_offset += message_size; 759425bb815Sopenharmony_ci return true; 760425bb815Sopenharmony_ci } 761425bb815Sopenharmony_ci 762425bb815Sopenharmony_ci bool result; 763425bb815Sopenharmony_ci 764425bb815Sopenharmony_ci if (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART) 765425bb815Sopenharmony_ci { 766425bb815Sopenharmony_ci if (jerry_debugger_send_eval (string_p, uint8_data_p->uint8_size)) 767425bb815Sopenharmony_ci { 768425bb815Sopenharmony_ci *resume_exec_p = true; 769425bb815Sopenharmony_ci } 770425bb815Sopenharmony_ci result = (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0; 771425bb815Sopenharmony_ci } 772425bb815Sopenharmony_ci else 773425bb815Sopenharmony_ci { 774425bb815Sopenharmony_ci result = true; 775425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); 776425bb815Sopenharmony_ci *resume_exec_p = true; 777425bb815Sopenharmony_ci } 778425bb815Sopenharmony_ci 779425bb815Sopenharmony_ci *expected_message_type_p = 0; 780425bb815Sopenharmony_ci return result; 781425bb815Sopenharmony_ci } 782425bb815Sopenharmony_ci 783425bb815Sopenharmony_ci switch (recv_buffer_p[0]) 784425bb815Sopenharmony_ci { 785425bb815Sopenharmony_ci case JERRY_DEBUGGER_FREE_BYTE_CODE_CP: 786425bb815Sopenharmony_ci { 787425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_byte_code_cp_t); 788425bb815Sopenharmony_ci 789425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_byte_code_cp_t, byte_code_p); 790425bb815Sopenharmony_ci 791425bb815Sopenharmony_ci jmem_cpointer_t byte_code_free_cp; 792425bb815Sopenharmony_ci memcpy (&byte_code_free_cp, byte_code_p->byte_code_cp, sizeof (jmem_cpointer_t)); 793425bb815Sopenharmony_ci 794425bb815Sopenharmony_ci if (byte_code_free_cp != JERRY_CONTEXT (debugger_byte_code_free_tail)) 795425bb815Sopenharmony_ci { 796425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid byte code free order\n"); 797425bb815Sopenharmony_ci jerry_debugger_transport_close (); 798425bb815Sopenharmony_ci return false; 799425bb815Sopenharmony_ci } 800425bb815Sopenharmony_ci 801425bb815Sopenharmony_ci jerry_debugger_byte_code_free_t *byte_code_free_p; 802425bb815Sopenharmony_ci byte_code_free_p = JMEM_CP_GET_NON_NULL_POINTER (jerry_debugger_byte_code_free_t, 803425bb815Sopenharmony_ci byte_code_free_cp); 804425bb815Sopenharmony_ci 805425bb815Sopenharmony_ci if (byte_code_free_p->prev_cp != ECMA_NULL_POINTER) 806425bb815Sopenharmony_ci { 807425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_tail) = byte_code_free_p->prev_cp; 808425bb815Sopenharmony_ci } 809425bb815Sopenharmony_ci else 810425bb815Sopenharmony_ci { 811425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_head) = ECMA_NULL_POINTER; 812425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_tail) = ECMA_NULL_POINTER; 813425bb815Sopenharmony_ci } 814425bb815Sopenharmony_ci 815425bb815Sopenharmony_ci#if ENABLED (JERRY_MEM_STATS) 816425bb815Sopenharmony_ci jmem_stats_free_byte_code_bytes (((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG); 817425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_MEM_STATS) */ 818425bb815Sopenharmony_ci 819425bb815Sopenharmony_ci jmem_heap_free_block (byte_code_free_p, 820425bb815Sopenharmony_ci ((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG); 821425bb815Sopenharmony_ci return true; 822425bb815Sopenharmony_ci } 823425bb815Sopenharmony_ci 824425bb815Sopenharmony_ci case JERRY_DEBUGGER_UPDATE_BREAKPOINT: 825425bb815Sopenharmony_ci { 826425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_update_breakpoint_t); 827425bb815Sopenharmony_ci 828425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_update_breakpoint_t, update_breakpoint_p); 829425bb815Sopenharmony_ci 830425bb815Sopenharmony_ci jmem_cpointer_t byte_code_cp; 831425bb815Sopenharmony_ci memcpy (&byte_code_cp, update_breakpoint_p->byte_code_cp, sizeof (jmem_cpointer_t)); 832425bb815Sopenharmony_ci uint8_t *byte_code_p = JMEM_CP_GET_NON_NULL_POINTER (uint8_t, byte_code_cp); 833425bb815Sopenharmony_ci 834425bb815Sopenharmony_ci uint32_t offset; 835425bb815Sopenharmony_ci memcpy (&offset, update_breakpoint_p->offset, sizeof (uint32_t)); 836425bb815Sopenharmony_ci byte_code_p += offset; 837425bb815Sopenharmony_ci 838425bb815Sopenharmony_ci JERRY_ASSERT (*byte_code_p == CBC_BREAKPOINT_ENABLED || *byte_code_p == CBC_BREAKPOINT_DISABLED); 839425bb815Sopenharmony_ci 840425bb815Sopenharmony_ci *byte_code_p = update_breakpoint_p->is_set_breakpoint ? CBC_BREAKPOINT_ENABLED : CBC_BREAKPOINT_DISABLED; 841425bb815Sopenharmony_ci return true; 842425bb815Sopenharmony_ci } 843425bb815Sopenharmony_ci 844425bb815Sopenharmony_ci case JERRY_DEBUGGER_MEMSTATS: 845425bb815Sopenharmony_ci { 846425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 847425bb815Sopenharmony_ci 848425bb815Sopenharmony_ci jerry_debugger_send_memstats (); 849425bb815Sopenharmony_ci return true; 850425bb815Sopenharmony_ci } 851425bb815Sopenharmony_ci 852425bb815Sopenharmony_ci case JERRY_DEBUGGER_STOP: 853425bb815Sopenharmony_ci { 854425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 855425bb815Sopenharmony_ci 856425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); 857425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = NULL; 858425bb815Sopenharmony_ci *resume_exec_p = false; 859425bb815Sopenharmony_ci return true; 860425bb815Sopenharmony_ci } 861425bb815Sopenharmony_ci 862425bb815Sopenharmony_ci case JERRY_DEBUGGER_CONTINUE: 863425bb815Sopenharmony_ci { 864425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 865425bb815Sopenharmony_ci 866425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP); 867425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = NULL; 868425bb815Sopenharmony_ci *resume_exec_p = true; 869425bb815Sopenharmony_ci return true; 870425bb815Sopenharmony_ci } 871425bb815Sopenharmony_ci 872425bb815Sopenharmony_ci case JERRY_DEBUGGER_STEP: 873425bb815Sopenharmony_ci { 874425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 875425bb815Sopenharmony_ci 876425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); 877425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = NULL; 878425bb815Sopenharmony_ci *resume_exec_p = true; 879425bb815Sopenharmony_ci return true; 880425bb815Sopenharmony_ci } 881425bb815Sopenharmony_ci 882425bb815Sopenharmony_ci case JERRY_DEBUGGER_NEXT: 883425bb815Sopenharmony_ci { 884425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 885425bb815Sopenharmony_ci 886425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); 887425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p); 888425bb815Sopenharmony_ci *resume_exec_p = true; 889425bb815Sopenharmony_ci return true; 890425bb815Sopenharmony_ci } 891425bb815Sopenharmony_ci 892425bb815Sopenharmony_ci case JERRY_DEBUGGER_FINISH: 893425bb815Sopenharmony_ci { 894425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 895425bb815Sopenharmony_ci 896425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP); 897425bb815Sopenharmony_ci 898425bb815Sopenharmony_ci /* This will point to the current context's parent (where the function was called) 899425bb815Sopenharmony_ci * and in case of NULL the result will the same as in case of STEP. */ 900425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_stop_context) = JERRY_CONTEXT (vm_top_context_p->prev_context_p); 901425bb815Sopenharmony_ci *resume_exec_p = true; 902425bb815Sopenharmony_ci return true; 903425bb815Sopenharmony_ci } 904425bb815Sopenharmony_ci 905425bb815Sopenharmony_ci case JERRY_DEBUGGER_GET_BACKTRACE: 906425bb815Sopenharmony_ci { 907425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_get_backtrace_t); 908425bb815Sopenharmony_ci 909425bb815Sopenharmony_ci jerry_debugger_send_backtrace (recv_buffer_p); 910425bb815Sopenharmony_ci return true; 911425bb815Sopenharmony_ci } 912425bb815Sopenharmony_ci 913425bb815Sopenharmony_ci case JERRY_DEBUGGER_GET_SCOPE_CHAIN: 914425bb815Sopenharmony_ci { 915425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 916425bb815Sopenharmony_ci 917425bb815Sopenharmony_ci jerry_debugger_send_scope_chain (); 918425bb815Sopenharmony_ci 919425bb815Sopenharmony_ci return true; 920425bb815Sopenharmony_ci } 921425bb815Sopenharmony_ci 922425bb815Sopenharmony_ci case JERRY_DEBUGGER_GET_SCOPE_VARIABLES: 923425bb815Sopenharmony_ci { 924425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_get_scope_variables_t); 925425bb815Sopenharmony_ci 926425bb815Sopenharmony_ci jerry_debugger_send_scope_variables (recv_buffer_p); 927425bb815Sopenharmony_ci 928425bb815Sopenharmony_ci return true; 929425bb815Sopenharmony_ci } 930425bb815Sopenharmony_ci 931425bb815Sopenharmony_ci case JERRY_DEBUGGER_EXCEPTION_CONFIG: 932425bb815Sopenharmony_ci { 933425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t); 934425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_exception_config_t, exception_config_p); 935425bb815Sopenharmony_ci 936425bb815Sopenharmony_ci if (exception_config_p->enable == 0) 937425bb815Sopenharmony_ci { 938425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); 939425bb815Sopenharmony_ci JERRY_DEBUG_MSG ("Stop at exception disabled\n"); 940425bb815Sopenharmony_ci } 941425bb815Sopenharmony_ci else 942425bb815Sopenharmony_ci { 943425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION); 944425bb815Sopenharmony_ci JERRY_DEBUG_MSG ("Stop at exception enabled\n"); 945425bb815Sopenharmony_ci } 946425bb815Sopenharmony_ci 947425bb815Sopenharmony_ci return true; 948425bb815Sopenharmony_ci } 949425bb815Sopenharmony_ci 950425bb815Sopenharmony_ci case JERRY_DEBUGGER_PARSER_CONFIG: 951425bb815Sopenharmony_ci { 952425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_parser_config_t); 953425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_parser_config_t, parser_config_p); 954425bb815Sopenharmony_ci 955425bb815Sopenharmony_ci if (parser_config_p->enable_wait != 0) 956425bb815Sopenharmony_ci { 957425bb815Sopenharmony_ci JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT); 958425bb815Sopenharmony_ci JERRY_DEBUG_MSG ("Waiting after parsing enabled\n"); 959425bb815Sopenharmony_ci } 960425bb815Sopenharmony_ci else 961425bb815Sopenharmony_ci { 962425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT); 963425bb815Sopenharmony_ci JERRY_DEBUG_MSG ("Waiting after parsing disabled\n"); 964425bb815Sopenharmony_ci } 965425bb815Sopenharmony_ci 966425bb815Sopenharmony_ci return true; 967425bb815Sopenharmony_ci } 968425bb815Sopenharmony_ci 969425bb815Sopenharmony_ci case JERRY_DEBUGGER_PARSER_RESUME: 970425bb815Sopenharmony_ci { 971425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 972425bb815Sopenharmony_ci 973425bb815Sopenharmony_ci if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE)) 974425bb815Sopenharmony_ci { 975425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Not in parser wait mode\n"); 976425bb815Sopenharmony_ci jerry_debugger_transport_close (); 977425bb815Sopenharmony_ci return false; 978425bb815Sopenharmony_ci } 979425bb815Sopenharmony_ci 980425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT_MODE); 981425bb815Sopenharmony_ci return true; 982425bb815Sopenharmony_ci } 983425bb815Sopenharmony_ci 984425bb815Sopenharmony_ci case JERRY_DEBUGGER_EVAL: 985425bb815Sopenharmony_ci { 986425bb815Sopenharmony_ci if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 5) 987425bb815Sopenharmony_ci { 988425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 989425bb815Sopenharmony_ci jerry_debugger_transport_close (); 990425bb815Sopenharmony_ci return false; 991425bb815Sopenharmony_ci } 992425bb815Sopenharmony_ci 993425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_eval_first_t, eval_first_p); 994425bb815Sopenharmony_ci 995425bb815Sopenharmony_ci uint32_t eval_size; 996425bb815Sopenharmony_ci memcpy (&eval_size, eval_first_p->eval_size, sizeof (uint32_t)); 997425bb815Sopenharmony_ci 998425bb815Sopenharmony_ci if (eval_size <= JERRY_CONTEXT (debugger_max_receive_size) - sizeof (jerry_debugger_receive_eval_first_t)) 999425bb815Sopenharmony_ci { 1000425bb815Sopenharmony_ci if (eval_size != message_size - sizeof (jerry_debugger_receive_eval_first_t)) 1001425bb815Sopenharmony_ci { 1002425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 1003425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1004425bb815Sopenharmony_ci return false; 1005425bb815Sopenharmony_ci } 1006425bb815Sopenharmony_ci 1007425bb815Sopenharmony_ci if (jerry_debugger_send_eval ((lit_utf8_byte_t *) (eval_first_p + 1), eval_size)) 1008425bb815Sopenharmony_ci { 1009425bb815Sopenharmony_ci *resume_exec_p = true; 1010425bb815Sopenharmony_ci } 1011425bb815Sopenharmony_ci 1012425bb815Sopenharmony_ci return (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0; 1013425bb815Sopenharmony_ci } 1014425bb815Sopenharmony_ci 1015425bb815Sopenharmony_ci jerry_debugger_uint8_data_t *eval_uint8_data_p; 1016425bb815Sopenharmony_ci size_t eval_data_size = sizeof (jerry_debugger_uint8_data_t) + eval_size; 1017425bb815Sopenharmony_ci 1018425bb815Sopenharmony_ci eval_uint8_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (eval_data_size); 1019425bb815Sopenharmony_ci 1020425bb815Sopenharmony_ci eval_uint8_data_p->uint8_size = eval_size; 1021425bb815Sopenharmony_ci eval_uint8_data_p->uint8_offset = (uint32_t) (message_size - sizeof (jerry_debugger_receive_eval_first_t)); 1022425bb815Sopenharmony_ci 1023425bb815Sopenharmony_ci lit_utf8_byte_t *eval_string_p = (lit_utf8_byte_t *) (eval_uint8_data_p + 1); 1024425bb815Sopenharmony_ci memcpy (eval_string_p, 1025425bb815Sopenharmony_ci (lit_utf8_byte_t *) (eval_first_p + 1), 1026425bb815Sopenharmony_ci message_size - sizeof (jerry_debugger_receive_eval_first_t)); 1027425bb815Sopenharmony_ci 1028425bb815Sopenharmony_ci *message_data_p = eval_uint8_data_p; 1029425bb815Sopenharmony_ci *expected_message_type_p = JERRY_DEBUGGER_EVAL_PART; 1030425bb815Sopenharmony_ci 1031425bb815Sopenharmony_ci return true; 1032425bb815Sopenharmony_ci } 1033425bb815Sopenharmony_ci 1034425bb815Sopenharmony_ci case JERRY_DEBUGGER_CLIENT_SOURCE: 1035425bb815Sopenharmony_ci { 1036425bb815Sopenharmony_ci if (message_size <= sizeof (jerry_debugger_receive_client_source_first_t)) 1037425bb815Sopenharmony_ci { 1038425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 1039425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1040425bb815Sopenharmony_ci return false; 1041425bb815Sopenharmony_ci } 1042425bb815Sopenharmony_ci 1043425bb815Sopenharmony_ci if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)) 1044425bb815Sopenharmony_ci { 1045425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Not in client source mode\n"); 1046425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1047425bb815Sopenharmony_ci return false; 1048425bb815Sopenharmony_ci } 1049425bb815Sopenharmony_ci 1050425bb815Sopenharmony_ci JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_client_source_first_t, client_source_first_p); 1051425bb815Sopenharmony_ci 1052425bb815Sopenharmony_ci uint32_t client_source_size; 1053425bb815Sopenharmony_ci memcpy (&client_source_size, client_source_first_p->code_size, sizeof (uint32_t)); 1054425bb815Sopenharmony_ci 1055425bb815Sopenharmony_ci uint32_t header_size = sizeof (jerry_debugger_receive_client_source_first_t); 1056425bb815Sopenharmony_ci 1057425bb815Sopenharmony_ci if (client_source_size <= JERRY_CONTEXT (debugger_max_receive_size) - header_size 1058425bb815Sopenharmony_ci && client_source_size != message_size - header_size) 1059425bb815Sopenharmony_ci { 1060425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Invalid message size\n"); 1061425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1062425bb815Sopenharmony_ci return false; 1063425bb815Sopenharmony_ci } 1064425bb815Sopenharmony_ci 1065425bb815Sopenharmony_ci jerry_debugger_uint8_data_t *client_source_data_p; 1066425bb815Sopenharmony_ci size_t client_source_data_size = sizeof (jerry_debugger_uint8_data_t) + client_source_size; 1067425bb815Sopenharmony_ci 1068425bb815Sopenharmony_ci client_source_data_p = (jerry_debugger_uint8_data_t *) jmem_heap_alloc_block (client_source_data_size); 1069425bb815Sopenharmony_ci 1070425bb815Sopenharmony_ci client_source_data_p->uint8_size = client_source_size; 1071425bb815Sopenharmony_ci client_source_data_p->uint8_offset = (uint32_t) (message_size 1072425bb815Sopenharmony_ci - sizeof (jerry_debugger_receive_client_source_first_t)); 1073425bb815Sopenharmony_ci 1074425bb815Sopenharmony_ci lit_utf8_byte_t *client_source_string_p = (lit_utf8_byte_t *) (client_source_data_p + 1); 1075425bb815Sopenharmony_ci memcpy (client_source_string_p, 1076425bb815Sopenharmony_ci (lit_utf8_byte_t *) (client_source_first_p + 1), 1077425bb815Sopenharmony_ci message_size - sizeof (jerry_debugger_receive_client_source_first_t)); 1078425bb815Sopenharmony_ci 1079425bb815Sopenharmony_ci *message_data_p = client_source_data_p; 1080425bb815Sopenharmony_ci 1081425bb815Sopenharmony_ci if (client_source_data_p->uint8_size != client_source_data_p->uint8_offset) 1082425bb815Sopenharmony_ci { 1083425bb815Sopenharmony_ci *expected_message_type_p = JERRY_DEBUGGER_CLIENT_SOURCE_PART; 1084425bb815Sopenharmony_ci } 1085425bb815Sopenharmony_ci else 1086425bb815Sopenharmony_ci { 1087425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE); 1088425bb815Sopenharmony_ci *resume_exec_p = true; 1089425bb815Sopenharmony_ci } 1090425bb815Sopenharmony_ci return true; 1091425bb815Sopenharmony_ci } 1092425bb815Sopenharmony_ci 1093425bb815Sopenharmony_ci case JERRY_DEBUGGER_NO_MORE_SOURCES: 1094425bb815Sopenharmony_ci { 1095425bb815Sopenharmony_ci if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)) 1096425bb815Sopenharmony_ci { 1097425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Not in client source mode\n"); 1098425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1099425bb815Sopenharmony_ci return false; 1100425bb815Sopenharmony_ci } 1101425bb815Sopenharmony_ci 1102425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 1103425bb815Sopenharmony_ci 1104425bb815Sopenharmony_ci JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CLIENT_NO_SOURCE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE); 1105425bb815Sopenharmony_ci 1106425bb815Sopenharmony_ci *resume_exec_p = true; 1107425bb815Sopenharmony_ci 1108425bb815Sopenharmony_ci return true; 1109425bb815Sopenharmony_ci } 1110425bb815Sopenharmony_ci 1111425bb815Sopenharmony_ci case JERRY_DEBUGGER_CONTEXT_RESET: 1112425bb815Sopenharmony_ci { 1113425bb815Sopenharmony_ci if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)) 1114425bb815Sopenharmony_ci { 1115425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Not in client source mode\n"); 1116425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1117425bb815Sopenharmony_ci return false; 1118425bb815Sopenharmony_ci } 1119425bb815Sopenharmony_ci 1120425bb815Sopenharmony_ci JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t); 1121425bb815Sopenharmony_ci 1122425bb815Sopenharmony_ci JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE, JERRY_DEBUGGER_CLIENT_SOURCE_MODE); 1123425bb815Sopenharmony_ci 1124425bb815Sopenharmony_ci *resume_exec_p = true; 1125425bb815Sopenharmony_ci 1126425bb815Sopenharmony_ci return true; 1127425bb815Sopenharmony_ci } 1128425bb815Sopenharmony_ci 1129425bb815Sopenharmony_ci default: 1130425bb815Sopenharmony_ci { 1131425bb815Sopenharmony_ci JERRY_ERROR_MSG ("Unexpected message."); 1132425bb815Sopenharmony_ci jerry_debugger_transport_close (); 1133425bb815Sopenharmony_ci return false; 1134425bb815Sopenharmony_ci } 1135425bb815Sopenharmony_ci } 1136425bb815Sopenharmony_ci} /* jerry_debugger_process_message */ 1137425bb815Sopenharmony_ci 1138425bb815Sopenharmony_ci/** 1139425bb815Sopenharmony_ci * Receive message from the client. 1140425bb815Sopenharmony_ci * 1141425bb815Sopenharmony_ci * Note: 1142425bb815Sopenharmony_ci * If the function returns with true, the value of 1143425bb815Sopenharmony_ci * JERRY_DEBUGGER_VM_STOP flag should be ignored. 1144425bb815Sopenharmony_ci * 1145425bb815Sopenharmony_ci * @return true - if execution should be resumed, 1146425bb815Sopenharmony_ci * false - otherwise 1147425bb815Sopenharmony_ci */ 1148425bb815Sopenharmony_cibool 1149425bb815Sopenharmony_cijerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] data received from client */ 1150425bb815Sopenharmony_ci{ 1151425bb815Sopenharmony_ci JERRY_ASSERT (jerry_debugger_transport_is_connected ()); 1152425bb815Sopenharmony_ci 1153425bb815Sopenharmony_ci JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE) 1154425bb815Sopenharmony_ci : !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)); 1155425bb815Sopenharmony_ci 1156425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY; 1157425bb815Sopenharmony_ci 1158425bb815Sopenharmony_ci bool resume_exec = false; 1159425bb815Sopenharmony_ci uint8_t expected_message_type = 0; 1160425bb815Sopenharmony_ci 1161425bb815Sopenharmony_ci while (true) 1162425bb815Sopenharmony_ci { 1163425bb815Sopenharmony_ci#if defined (__APPLE__) 1164425bb815Sopenharmony_ci // wait at here for 0.5ms 1165425bb815Sopenharmony_ci usleep(500); 1166425bb815Sopenharmony_ci#endif /* __APPLE__ */ 1167425bb815Sopenharmony_ci 1168425bb815Sopenharmony_ci jerry_debugger_transport_receive_context_t context; 1169425bb815Sopenharmony_ci if (!jerry_debugger_transport_receive (&context)) 1170425bb815Sopenharmony_ci { 1171425bb815Sopenharmony_ci JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)); 1172425bb815Sopenharmony_ci return true; 1173425bb815Sopenharmony_ci } 1174425bb815Sopenharmony_ci 1175425bb815Sopenharmony_ci if (context.message_p == NULL) 1176425bb815Sopenharmony_ci { 1177425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_received_length) = (uint16_t) context.received_length; 1178425bb815Sopenharmony_ci 1179425bb815Sopenharmony_ci if (expected_message_type != 0) 1180425bb815Sopenharmony_ci { 1181425bb815Sopenharmony_ci jerry_debugger_transport_sleep (); 1182425bb815Sopenharmony_ci continue; 1183425bb815Sopenharmony_ci } 1184425bb815Sopenharmony_ci 1185425bb815Sopenharmony_ci return resume_exec; 1186425bb815Sopenharmony_ci } 1187425bb815Sopenharmony_ci 1188425bb815Sopenharmony_ci /* Only datagram packets are supported. */ 1189425bb815Sopenharmony_ci JERRY_ASSERT (context.message_total_length > 0); 1190425bb815Sopenharmony_ci 1191425bb815Sopenharmony_ci /* The jerry_debugger_process_message function is inlined 1192425bb815Sopenharmony_ci * so passing these arguments is essentially free. */ 1193425bb815Sopenharmony_ci if (!jerry_debugger_process_message (context.message_p, 1194425bb815Sopenharmony_ci (uint32_t) context.message_length, 1195425bb815Sopenharmony_ci &resume_exec, 1196425bb815Sopenharmony_ci &expected_message_type, 1197425bb815Sopenharmony_ci message_data_p)) 1198425bb815Sopenharmony_ci { 1199425bb815Sopenharmony_ci JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)); 1200425bb815Sopenharmony_ci return true; 1201425bb815Sopenharmony_ci } 1202425bb815Sopenharmony_ci 1203425bb815Sopenharmony_ci jerry_debugger_transport_receive_completed (&context); 1204425bb815Sopenharmony_ci } 1205425bb815Sopenharmony_ci} /* jerry_debugger_receive */ 1206425bb815Sopenharmony_ci 1207425bb815Sopenharmony_ci#undef JERRY_DEBUGGER_CHECK_PACKET_SIZE 1208425bb815Sopenharmony_ci 1209425bb815Sopenharmony_ci/** 1210425bb815Sopenharmony_ci * Tell the client that a breakpoint has been hit and wait for further debugger commands. 1211425bb815Sopenharmony_ci */ 1212425bb815Sopenharmony_civoid 1213425bb815Sopenharmony_cijerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */ 1214425bb815Sopenharmony_ci{ 1215425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1216425bb815Sopenharmony_ci 1217425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_breakpoint_hit_t, breakpoint_hit_p); 1218425bb815Sopenharmony_ci 1219425bb815Sopenharmony_ci breakpoint_hit_p->type = message_type; 1220425bb815Sopenharmony_ci 1221425bb815Sopenharmony_ci vm_frame_ctx_t *frame_ctx_p = JERRY_CONTEXT (vm_top_context_p); 1222425bb815Sopenharmony_ci 1223425bb815Sopenharmony_ci jmem_cpointer_t byte_code_header_cp; 1224425bb815Sopenharmony_ci JMEM_CP_SET_NON_NULL_POINTER (byte_code_header_cp, frame_ctx_p->bytecode_header_p); 1225425bb815Sopenharmony_ci memcpy (breakpoint_hit_p->byte_code_cp, &byte_code_header_cp, sizeof (jmem_cpointer_t)); 1226425bb815Sopenharmony_ci 1227425bb815Sopenharmony_ci uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p); 1228425bb815Sopenharmony_ci memcpy (breakpoint_hit_p->offset, &offset, sizeof (uint32_t)); 1229425bb815Sopenharmony_ci 1230425bb815Sopenharmony_ci if (!jerry_debugger_send (sizeof (jerry_debugger_send_breakpoint_hit_t))) 1231425bb815Sopenharmony_ci { 1232425bb815Sopenharmony_ci return; 1233425bb815Sopenharmony_ci } 1234425bb815Sopenharmony_ci 1235425bb815Sopenharmony_ci JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE, JERRY_DEBUGGER_VM_EXCEPTION_THROWN); 1236425bb815Sopenharmony_ci 1237425bb815Sopenharmony_ci jerry_debugger_uint8_data_t *uint8_data = NULL; 1238425bb815Sopenharmony_ci 1239425bb815Sopenharmony_ci while (!jerry_debugger_receive (&uint8_data)) 1240425bb815Sopenharmony_ci { 1241425bb815Sopenharmony_ci jerry_debugger_transport_sleep (); 1242425bb815Sopenharmony_ci } 1243425bb815Sopenharmony_ci 1244425bb815Sopenharmony_ci if (uint8_data != NULL) 1245425bb815Sopenharmony_ci { 1246425bb815Sopenharmony_ci jmem_heap_free_block (uint8_data, 1247425bb815Sopenharmony_ci uint8_data->uint8_size + sizeof (jerry_debugger_uint8_data_t)); 1248425bb815Sopenharmony_ci } 1249425bb815Sopenharmony_ci 1250425bb815Sopenharmony_ci JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE); 1251425bb815Sopenharmony_ci 1252425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY; 1253425bb815Sopenharmony_ci} /* jerry_debugger_breakpoint_hit */ 1254425bb815Sopenharmony_ci 1255425bb815Sopenharmony_ci/** 1256425bb815Sopenharmony_ci * Send the type signal to the client. 1257425bb815Sopenharmony_ci */ 1258425bb815Sopenharmony_civoid 1259425bb815Sopenharmony_cijerry_debugger_send_type (jerry_debugger_header_type_t type) /**< message type */ 1260425bb815Sopenharmony_ci{ 1261425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1262425bb815Sopenharmony_ci 1263425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_type_t, message_type_p); 1264425bb815Sopenharmony_ci 1265425bb815Sopenharmony_ci message_type_p->type = (uint8_t) type; 1266425bb815Sopenharmony_ci 1267425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t)); 1268425bb815Sopenharmony_ci} /* jerry_debugger_send_type */ 1269425bb815Sopenharmony_ci 1270425bb815Sopenharmony_ci/** 1271425bb815Sopenharmony_ci * Send the type signal to the client. 1272425bb815Sopenharmony_ci * 1273425bb815Sopenharmony_ci * @return true - if the data sent successfully to the debugger client, 1274425bb815Sopenharmony_ci * false - otherwise 1275425bb815Sopenharmony_ci */ 1276425bb815Sopenharmony_cibool 1277425bb815Sopenharmony_cijerry_debugger_send_configuration (uint8_t max_message_size) /**< maximum message size */ 1278425bb815Sopenharmony_ci{ 1279425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_configuration_t, configuration_p); 1280425bb815Sopenharmony_ci 1281425bb815Sopenharmony_ci /* Helper structure for endianness check. */ 1282425bb815Sopenharmony_ci union 1283425bb815Sopenharmony_ci { 1284425bb815Sopenharmony_ci uint16_t uint16_value; /**< a 16-bit value */ 1285425bb815Sopenharmony_ci uint8_t uint8_value[2]; /**< lower and upper byte of a 16-bit value */ 1286425bb815Sopenharmony_ci } endian_data; 1287425bb815Sopenharmony_ci 1288425bb815Sopenharmony_ci endian_data.uint16_value = 1; 1289425bb815Sopenharmony_ci 1290425bb815Sopenharmony_ci configuration_p->type = JERRY_DEBUGGER_CONFIGURATION; 1291425bb815Sopenharmony_ci configuration_p->configuration = 0; 1292425bb815Sopenharmony_ci 1293425bb815Sopenharmony_ci if (endian_data.uint8_value[0] == 1) 1294425bb815Sopenharmony_ci { 1295425bb815Sopenharmony_ci configuration_p->configuration |= (uint8_t) JERRY_DEBUGGER_LITTLE_ENDIAN; 1296425bb815Sopenharmony_ci } 1297425bb815Sopenharmony_ci 1298425bb815Sopenharmony_ci uint32_t version = JERRY_DEBUGGER_VERSION; 1299425bb815Sopenharmony_ci memcpy (configuration_p->version, &version, sizeof (uint32_t)); 1300425bb815Sopenharmony_ci 1301425bb815Sopenharmony_ci configuration_p->max_message_size = max_message_size; 1302425bb815Sopenharmony_ci configuration_p->cpointer_size = sizeof (jmem_cpointer_t); 1303425bb815Sopenharmony_ci 1304425bb815Sopenharmony_ci return jerry_debugger_send (sizeof (jerry_debugger_send_configuration_t)); 1305425bb815Sopenharmony_ci} /* jerry_debugger_send_configuration */ 1306425bb815Sopenharmony_ci 1307425bb815Sopenharmony_ci/** 1308425bb815Sopenharmony_ci * Send raw data to the debugger client. 1309425bb815Sopenharmony_ci */ 1310425bb815Sopenharmony_civoid 1311425bb815Sopenharmony_cijerry_debugger_send_data (jerry_debugger_header_type_t type, /**< message type */ 1312425bb815Sopenharmony_ci const void *data, /**< raw data */ 1313425bb815Sopenharmony_ci size_t size) /**< size of data */ 1314425bb815Sopenharmony_ci{ 1315425bb815Sopenharmony_ci JERRY_ASSERT (size <= JERRY_DEBUGGER_SEND_MAX (uint8_t)); 1316425bb815Sopenharmony_ci 1317425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_type_t, message_type_p); 1318425bb815Sopenharmony_ci 1319425bb815Sopenharmony_ci message_type_p->type = (uint8_t) type; 1320425bb815Sopenharmony_ci memcpy (message_type_p + 1, data, size); 1321425bb815Sopenharmony_ci 1322425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + size); 1323425bb815Sopenharmony_ci} /* jerry_debugger_send_data */ 1324425bb815Sopenharmony_ci 1325425bb815Sopenharmony_ci/** 1326425bb815Sopenharmony_ci * Send string to the debugger client. 1327425bb815Sopenharmony_ci * 1328425bb815Sopenharmony_ci * @return true - if the data sent successfully to the debugger client, 1329425bb815Sopenharmony_ci * false - otherwise 1330425bb815Sopenharmony_ci */ 1331425bb815Sopenharmony_cibool 1332425bb815Sopenharmony_cijerry_debugger_send_string (uint8_t message_type, /**< message type */ 1333425bb815Sopenharmony_ci uint8_t sub_type, /**< subtype of the string */ 1334425bb815Sopenharmony_ci const uint8_t *string_p, /**< string data */ 1335425bb815Sopenharmony_ci size_t string_length) /**< length of string */ 1336425bb815Sopenharmony_ci{ 1337425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1338425bb815Sopenharmony_ci 1339425bb815Sopenharmony_ci const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t); 1340425bb815Sopenharmony_ci const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t); 1341425bb815Sopenharmony_ci 1342425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p); 1343425bb815Sopenharmony_ci 1344425bb815Sopenharmony_ci message_string_p->type = message_type; 1345425bb815Sopenharmony_ci 1346425bb815Sopenharmony_ci if (sub_type != JERRY_DEBUGGER_NO_SUBTYPE) 1347425bb815Sopenharmony_ci { 1348425bb815Sopenharmony_ci string_length += 1; 1349425bb815Sopenharmony_ci } 1350425bb815Sopenharmony_ci 1351425bb815Sopenharmony_ci while (string_length > max_byte_count) 1352425bb815Sopenharmony_ci { 1353425bb815Sopenharmony_ci memcpy (message_string_p->string, string_p, max_byte_count); 1354425bb815Sopenharmony_ci 1355425bb815Sopenharmony_ci if (!jerry_debugger_send (max_message_size)) 1356425bb815Sopenharmony_ci { 1357425bb815Sopenharmony_ci return false; 1358425bb815Sopenharmony_ci } 1359425bb815Sopenharmony_ci 1360425bb815Sopenharmony_ci string_length -= max_byte_count; 1361425bb815Sopenharmony_ci string_p += max_byte_count; 1362425bb815Sopenharmony_ci } 1363425bb815Sopenharmony_ci 1364425bb815Sopenharmony_ci message_string_p->type = (uint8_t) (message_type + 1); 1365425bb815Sopenharmony_ci 1366425bb815Sopenharmony_ci if (sub_type != JERRY_DEBUGGER_NO_SUBTYPE) 1367425bb815Sopenharmony_ci { 1368425bb815Sopenharmony_ci memcpy (message_string_p->string, string_p, string_length - 1); 1369425bb815Sopenharmony_ci message_string_p->string[string_length - 1] = sub_type; 1370425bb815Sopenharmony_ci } 1371425bb815Sopenharmony_ci else 1372425bb815Sopenharmony_ci { 1373425bb815Sopenharmony_ci memcpy (message_string_p->string, string_p, string_length); 1374425bb815Sopenharmony_ci } 1375425bb815Sopenharmony_ci 1376425bb815Sopenharmony_ci return jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + string_length); 1377425bb815Sopenharmony_ci} /* jerry_debugger_send_string */ 1378425bb815Sopenharmony_ci 1379425bb815Sopenharmony_ci/** 1380425bb815Sopenharmony_ci * Send the function compressed pointer to the debugger client. 1381425bb815Sopenharmony_ci * 1382425bb815Sopenharmony_ci * @return true - if the data was sent successfully to the debugger client, 1383425bb815Sopenharmony_ci * false - otherwise 1384425bb815Sopenharmony_ci */ 1385425bb815Sopenharmony_cibool 1386425bb815Sopenharmony_cijerry_debugger_send_function_cp (jerry_debugger_header_type_t type, /**< message type */ 1387425bb815Sopenharmony_ci ecma_compiled_code_t *compiled_code_p) /**< byte code pointer */ 1388425bb815Sopenharmony_ci{ 1389425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1390425bb815Sopenharmony_ci 1391425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_byte_code_cp_t, byte_code_cp_p); 1392425bb815Sopenharmony_ci 1393425bb815Sopenharmony_ci byte_code_cp_p->type = (uint8_t) type; 1394425bb815Sopenharmony_ci 1395425bb815Sopenharmony_ci jmem_cpointer_t compiled_code_cp; 1396425bb815Sopenharmony_ci JMEM_CP_SET_NON_NULL_POINTER (compiled_code_cp, compiled_code_p); 1397425bb815Sopenharmony_ci memcpy (byte_code_cp_p->byte_code_cp, &compiled_code_cp, sizeof (jmem_cpointer_t)); 1398425bb815Sopenharmony_ci 1399425bb815Sopenharmony_ci return jerry_debugger_send (sizeof (jerry_debugger_send_byte_code_cp_t)); 1400425bb815Sopenharmony_ci} /* jerry_debugger_send_function_cp */ 1401425bb815Sopenharmony_ci 1402425bb815Sopenharmony_ci/** 1403425bb815Sopenharmony_ci * Send function data to the debugger client. 1404425bb815Sopenharmony_ci * 1405425bb815Sopenharmony_ci * @return true - if the data sent successfully to the debugger client, 1406425bb815Sopenharmony_ci * false - otherwise 1407425bb815Sopenharmony_ci */ 1408425bb815Sopenharmony_cibool 1409425bb815Sopenharmony_cijerry_debugger_send_parse_function (uint32_t line, /**< line */ 1410425bb815Sopenharmony_ci uint32_t column) /**< column */ 1411425bb815Sopenharmony_ci{ 1412425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1413425bb815Sopenharmony_ci 1414425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_parse_function_t, message_parse_function_p); 1415425bb815Sopenharmony_ci 1416425bb815Sopenharmony_ci message_parse_function_p->type = JERRY_DEBUGGER_PARSE_FUNCTION; 1417425bb815Sopenharmony_ci memcpy (message_parse_function_p->line, &line, sizeof (uint32_t)); 1418425bb815Sopenharmony_ci memcpy (message_parse_function_p->column, &column, sizeof (uint32_t)); 1419425bb815Sopenharmony_ci 1420425bb815Sopenharmony_ci return jerry_debugger_send (sizeof (jerry_debugger_send_parse_function_t)); 1421425bb815Sopenharmony_ci} /* jerry_debugger_send_parse_function */ 1422425bb815Sopenharmony_ci 1423425bb815Sopenharmony_ci/** 1424425bb815Sopenharmony_ci * Send memory statistics to the debugger client. 1425425bb815Sopenharmony_ci */ 1426425bb815Sopenharmony_civoid 1427425bb815Sopenharmony_cijerry_debugger_send_memstats (void) 1428425bb815Sopenharmony_ci{ 1429425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED); 1430425bb815Sopenharmony_ci 1431425bb815Sopenharmony_ci JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_memstats_t, memstats_p); 1432425bb815Sopenharmony_ci 1433425bb815Sopenharmony_ci memstats_p->type = JERRY_DEBUGGER_MEMSTATS_RECEIVE; 1434425bb815Sopenharmony_ci 1435425bb815Sopenharmony_ci#if ENABLED (JERRY_MEM_STATS) /* if memory statistics feature is enabled */ 1436425bb815Sopenharmony_ci jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); 1437425bb815Sopenharmony_ci 1438425bb815Sopenharmony_ci uint32_t allocated_bytes = (uint32_t) heap_stats->allocated_bytes; 1439425bb815Sopenharmony_ci memcpy (memstats_p->allocated_bytes, &allocated_bytes, sizeof (uint32_t)); 1440425bb815Sopenharmony_ci uint32_t byte_code_bytes = (uint32_t) heap_stats->byte_code_bytes; 1441425bb815Sopenharmony_ci memcpy (memstats_p->byte_code_bytes, &byte_code_bytes, sizeof (uint32_t)); 1442425bb815Sopenharmony_ci uint32_t string_bytes = (uint32_t) heap_stats->string_bytes; 1443425bb815Sopenharmony_ci memcpy (memstats_p->string_bytes, &string_bytes, sizeof (uint32_t)); 1444425bb815Sopenharmony_ci uint32_t object_bytes = (uint32_t) heap_stats->object_bytes; 1445425bb815Sopenharmony_ci memcpy (memstats_p->object_bytes, &object_bytes, sizeof (uint32_t)); 1446425bb815Sopenharmony_ci uint32_t property_bytes = (uint32_t) heap_stats->property_bytes; 1447425bb815Sopenharmony_ci memcpy (memstats_p->property_bytes, &property_bytes, sizeof (uint32_t)); 1448425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_MEM_STATS) if not, just put zeros */ 1449425bb815Sopenharmony_ci memset (memstats_p->allocated_bytes, 0, sizeof (uint32_t)); 1450425bb815Sopenharmony_ci memset (memstats_p->byte_code_bytes, 0, sizeof (uint32_t)); 1451425bb815Sopenharmony_ci memset (memstats_p->string_bytes, 0, sizeof (uint32_t)); 1452425bb815Sopenharmony_ci memset (memstats_p->object_bytes, 0, sizeof (uint32_t)); 1453425bb815Sopenharmony_ci memset (memstats_p->property_bytes, 0, sizeof (uint32_t)); 1454425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_MEM_STATS) */ 1455425bb815Sopenharmony_ci 1456425bb815Sopenharmony_ci jerry_debugger_send (sizeof (jerry_debugger_send_memstats_t)); 1457425bb815Sopenharmony_ci} /* jerry_debugger_send_memstats */ 1458425bb815Sopenharmony_ci 1459425bb815Sopenharmony_ci/* 1460425bb815Sopenharmony_ci * Converts an standard error into a string. 1461425bb815Sopenharmony_ci * 1462425bb815Sopenharmony_ci * @return standard error string 1463425bb815Sopenharmony_ci */ 1464425bb815Sopenharmony_cistatic ecma_string_t * 1465425bb815Sopenharmony_cijerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**< exception object */ 1466425bb815Sopenharmony_ci{ 1467425bb815Sopenharmony_ci ecma_object_t *object_p = ecma_get_object_from_value (exception_obj_value); 1468425bb815Sopenharmony_ci 1469425bb815Sopenharmony_ci jmem_cpointer_t prototype_cp = object_p->u2.prototype_cp; 1470425bb815Sopenharmony_ci 1471425bb815Sopenharmony_ci if (prototype_cp == JMEM_CP_NULL) 1472425bb815Sopenharmony_ci { 1473425bb815Sopenharmony_ci return NULL; 1474425bb815Sopenharmony_ci } 1475425bb815Sopenharmony_ci 1476425bb815Sopenharmony_ci ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp); 1477425bb815Sopenharmony_ci 1478425bb815Sopenharmony_ci if (ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL 1479425bb815Sopenharmony_ci || !ecma_get_object_is_builtin (prototype_p)) 1480425bb815Sopenharmony_ci { 1481425bb815Sopenharmony_ci return NULL; 1482425bb815Sopenharmony_ci } 1483425bb815Sopenharmony_ci 1484425bb815Sopenharmony_ci lit_magic_string_id_t string_id; 1485425bb815Sopenharmony_ci 1486425bb815Sopenharmony_ci switch (((ecma_extended_object_t *) prototype_p)->u.built_in.id) 1487425bb815Sopenharmony_ci { 1488425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_ERRORS) 1489425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE: 1490425bb815Sopenharmony_ci { 1491425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_EVAL_ERROR_UL; 1492425bb815Sopenharmony_ci break; 1493425bb815Sopenharmony_ci } 1494425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE: 1495425bb815Sopenharmony_ci { 1496425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_RANGE_ERROR_UL; 1497425bb815Sopenharmony_ci break; 1498425bb815Sopenharmony_ci } 1499425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE: 1500425bb815Sopenharmony_ci { 1501425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_REFERENCE_ERROR_UL; 1502425bb815Sopenharmony_ci break; 1503425bb815Sopenharmony_ci } 1504425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE: 1505425bb815Sopenharmony_ci { 1506425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_SYNTAX_ERROR_UL; 1507425bb815Sopenharmony_ci break; 1508425bb815Sopenharmony_ci } 1509425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE: 1510425bb815Sopenharmony_ci { 1511425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_TYPE_ERROR_UL; 1512425bb815Sopenharmony_ci break; 1513425bb815Sopenharmony_ci } 1514425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE: 1515425bb815Sopenharmony_ci { 1516425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_URI_ERROR_UL; 1517425bb815Sopenharmony_ci break; 1518425bb815Sopenharmony_ci } 1519425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_ERRORS) */ 1520425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_ERROR_PROTOTYPE: 1521425bb815Sopenharmony_ci { 1522425bb815Sopenharmony_ci string_id = LIT_MAGIC_STRING_ERROR_UL; 1523425bb815Sopenharmony_ci break; 1524425bb815Sopenharmony_ci } 1525425bb815Sopenharmony_ci default: 1526425bb815Sopenharmony_ci { 1527425bb815Sopenharmony_ci return NULL; 1528425bb815Sopenharmony_ci } 1529425bb815Sopenharmony_ci } 1530425bb815Sopenharmony_ci 1531425bb815Sopenharmony_ci ecma_stringbuilder_t builder = ecma_stringbuilder_create (); 1532425bb815Sopenharmony_ci 1533425bb815Sopenharmony_ci ecma_stringbuilder_append_magic (&builder, string_id); 1534425bb815Sopenharmony_ci 1535425bb815Sopenharmony_ci ecma_property_t *property_p; 1536425bb815Sopenharmony_ci property_p = ecma_find_named_property (ecma_get_object_from_value (exception_obj_value), 1537425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE)); 1538425bb815Sopenharmony_ci 1539425bb815Sopenharmony_ci if (property_p == NULL 1540425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) 1541425bb815Sopenharmony_ci { 1542425bb815Sopenharmony_ci return ecma_stringbuilder_finalize (&builder); 1543425bb815Sopenharmony_ci } 1544425bb815Sopenharmony_ci 1545425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 1546425bb815Sopenharmony_ci 1547425bb815Sopenharmony_ci if (!ecma_is_value_string (prop_value_p->value)) 1548425bb815Sopenharmony_ci { 1549425bb815Sopenharmony_ci return ecma_stringbuilder_finalize (&builder); 1550425bb815Sopenharmony_ci } 1551425bb815Sopenharmony_ci 1552425bb815Sopenharmony_ci ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COLON); 1553425bb815Sopenharmony_ci ecma_stringbuilder_append_byte (&builder, LIT_CHAR_SP); 1554425bb815Sopenharmony_ci ecma_stringbuilder_append (&builder, ecma_get_string_from_value (prop_value_p->value)); 1555425bb815Sopenharmony_ci 1556425bb815Sopenharmony_ci return ecma_stringbuilder_finalize (&builder); 1557425bb815Sopenharmony_ci} /* jerry_debugger_exception_object_to_string */ 1558425bb815Sopenharmony_ci 1559425bb815Sopenharmony_ci/** 1560425bb815Sopenharmony_ci * Send string representation of exception to the client. 1561425bb815Sopenharmony_ci * 1562425bb815Sopenharmony_ci * @return true - if the data sent successfully to the debugger client, 1563425bb815Sopenharmony_ci * false - otherwise 1564425bb815Sopenharmony_ci */ 1565425bb815Sopenharmony_cibool 1566425bb815Sopenharmony_cijerry_debugger_send_exception_string (ecma_value_t exception_value) 1567425bb815Sopenharmony_ci{ 1568425bb815Sopenharmony_ci JERRY_ASSERT (jcontext_has_pending_exception ()); 1569425bb815Sopenharmony_ci ecma_string_t *string_p = NULL; 1570425bb815Sopenharmony_ci 1571425bb815Sopenharmony_ci if (ecma_is_value_object (exception_value)) 1572425bb815Sopenharmony_ci { 1573425bb815Sopenharmony_ci string_p = jerry_debugger_exception_object_to_string (exception_value); 1574425bb815Sopenharmony_ci 1575425bb815Sopenharmony_ci if (string_p == NULL) 1576425bb815Sopenharmony_ci { 1577425bb815Sopenharmony_ci string_p = ecma_get_string_from_value (ecma_builtin_helper_object_to_string (exception_value)); 1578425bb815Sopenharmony_ci } 1579425bb815Sopenharmony_ci } 1580425bb815Sopenharmony_ci else if (ecma_is_value_string (exception_value)) 1581425bb815Sopenharmony_ci { 1582425bb815Sopenharmony_ci string_p = ecma_get_string_from_value (exception_value); 1583425bb815Sopenharmony_ci ecma_ref_ecma_string (string_p); 1584425bb815Sopenharmony_ci } 1585425bb815Sopenharmony_ci else 1586425bb815Sopenharmony_ci { 1587425bb815Sopenharmony_ci string_p = ecma_op_to_string (exception_value); 1588425bb815Sopenharmony_ci } 1589425bb815Sopenharmony_ci 1590425bb815Sopenharmony_ci ECMA_STRING_TO_UTF8_STRING (string_p, string_data_p, string_size); 1591425bb815Sopenharmony_ci 1592425bb815Sopenharmony_ci bool result = jerry_debugger_send_string (JERRY_DEBUGGER_EXCEPTION_STR, 1593425bb815Sopenharmony_ci JERRY_DEBUGGER_NO_SUBTYPE, 1594425bb815Sopenharmony_ci string_data_p, 1595425bb815Sopenharmony_ci string_size); 1596425bb815Sopenharmony_ci 1597425bb815Sopenharmony_ci ECMA_FINALIZE_UTF8_STRING (string_data_p, string_size); 1598425bb815Sopenharmony_ci 1599425bb815Sopenharmony_ci ecma_deref_ecma_string (string_p); 1600425bb815Sopenharmony_ci return result; 1601425bb815Sopenharmony_ci} /* jerry_debugger_send_exception_string */ 1602425bb815Sopenharmony_ci 1603425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 1604