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