• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "debugger.h"
17 #include "jcontext.h"
18 #include "jerryscript.h"
19 
20 /**
21  * Checks whether the debugger is connected.
22  *
23  * @return true - if the debugger is connected
24  *         false - otherwise
25  */
26 bool
jerry_debugger_is_connected(void)27 jerry_debugger_is_connected (void)
28 {
29 #if ENABLED (JERRY_DEBUGGER)
30   return JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED;
31 #else /* !ENABLED (JERRY_DEBUGGER) */
32   return false;
33 #endif /* ENABLED (JERRY_DEBUGGER) */
34 } /* jerry_debugger_is_connected */
35 
36 /**
37  * Stop execution at the next available breakpoint.
38  */
39 void
jerry_debugger_stop(void)40 jerry_debugger_stop (void)
41 {
42 #if ENABLED (JERRY_DEBUGGER)
43   if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
44       && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
45   {
46     JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
47     JERRY_CONTEXT (debugger_stop_context) = NULL;
48   }
49 #endif /* ENABLED (JERRY_DEBUGGER) */
50 } /* jerry_debugger_stop */
51 
52 /**
53  * Continue execution.
54  */
55 void
jerry_debugger_continue(void)56 jerry_debugger_continue (void)
57 {
58 #if ENABLED (JERRY_DEBUGGER)
59   if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
60       && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
61   {
62     JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
63     JERRY_CONTEXT (debugger_stop_context) = NULL;
64   }
65 #endif /* ENABLED (JERRY_DEBUGGER) */
66 } /* jerry_debugger_continue */
67 
68 /**
69  * Sets whether the engine should stop at breakpoints.
70  */
71 void
jerry_debugger_stop_at_breakpoint(bool enable_stop_at_breakpoint)72 jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) /**< enable/disable stop at breakpoint */
73 {
74 #if ENABLED (JERRY_DEBUGGER)
75   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED
76       && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
77   {
78     if (enable_stop_at_breakpoint)
79     {
80       JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
81     }
82     else
83     {
84       JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
85     }
86   }
87 #else /* !ENABLED (JERRY_DEBUGGER) */
88   JERRY_UNUSED (enable_stop_at_breakpoint);
89 #endif /* ENABLED (JERRY_DEBUGGER) */
90 } /* jerry_debugger_stop_at_breakpoint */
91 
92 /**
93  * Sets whether the engine should wait and run a source.
94  *
95  * @return enum JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED - if the source is not received
96  *              JERRY_DEBUGGER_SOURCE_RECEIVED - if a source code received
97  *              JERRY_DEBUGGER_SOURCE_END - the end of the source codes
98  *              JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED - the end of the context
99  */
100 jerry_debugger_wait_for_source_status_t
jerry_debugger_wait_for_client_source(jerry_debugger_wait_for_source_callback_t callback_p,void * user_p,jerry_value_t * return_value)101 jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p, /**< callback function */
102                                        void *user_p, /**< user pointer passed to the callback */
103                                        jerry_value_t *return_value) /**< [out] parse and run return value */
104 {
105   *return_value = jerry_create_undefined ();
106 
107 #if ENABLED (JERRY_DEBUGGER)
108   if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
109       && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
110   {
111     JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
112     jerry_debugger_uint8_data_t *client_source_data_p = NULL;
113     jerry_debugger_wait_for_source_status_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
114 
115     /* Notify the client about that the engine is waiting for a source. */
116     jerry_debugger_send_type (JERRY_DEBUGGER_WAIT_FOR_SOURCE);
117 
118     while (true)
119     {
120       if (jerry_debugger_receive (&client_source_data_p))
121       {
122         if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED))
123         {
124           break;
125         }
126 
127         /* Stop executing the current context. */
128         if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONTEXT_RESET_MODE))
129         {
130           ret_type = JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED;
131           JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE);
132           break;
133         }
134 
135         /* Stop waiting for a new source file. */
136         if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_NO_SOURCE))
137         {
138           ret_type = JERRY_DEBUGGER_SOURCE_END;
139           JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
140           break;
141         }
142 
143         /* The source arrived. */
144         if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
145         {
146           JERRY_ASSERT (client_source_data_p != NULL);
147 
148           jerry_char_t *resource_name_p = (jerry_char_t *) (client_source_data_p + 1);
149           size_t resource_name_size = strlen ((const char *) resource_name_p);
150 
151           *return_value = callback_p (resource_name_p,
152                                       resource_name_size,
153                                       resource_name_p + resource_name_size + 1,
154                                       client_source_data_p->uint8_size - resource_name_size - 1,
155                                       user_p);
156 
157           ret_type = JERRY_DEBUGGER_SOURCE_RECEIVED;
158           break;
159         }
160       }
161 
162       jerry_debugger_transport_sleep ();
163     }
164 
165     JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)
166                   || !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED));
167 
168     if (client_source_data_p != NULL)
169     {
170       /* The data may partly arrived. */
171       jmem_heap_free_block (client_source_data_p,
172                             client_source_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
173     }
174 
175     return ret_type;
176   }
177 
178   return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
179 #else /* !ENABLED (JERRY_DEBUGGER) */
180   JERRY_UNUSED (callback_p);
181   JERRY_UNUSED (user_p);
182 
183   return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
184 #endif /* ENABLED (JERRY_DEBUGGER) */
185 } /* jerry_debugger_wait_for_client_source */
186 
187 /**
188  * Send the output of the program to the debugger client.
189  * Currently only sends print output.
190  */
191 void
jerry_debugger_send_output(const jerry_char_t * buffer,jerry_size_t str_size)192 jerry_debugger_send_output (const jerry_char_t *buffer, /**< buffer */
193                             jerry_size_t str_size) /**< string size */
194 {
195 #if ENABLED (JERRY_DEBUGGER)
196   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
197   {
198     jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
199                                 JERRY_DEBUGGER_OUTPUT_OK,
200                                 (const uint8_t *) buffer,
201                                 sizeof (uint8_t) * str_size);
202   }
203 #else /* !ENABLED (JERRY_DEBUGGER) */
204   JERRY_UNUSED (buffer);
205   JERRY_UNUSED (str_size);
206 #endif /* ENABLED (JERRY_DEBUGGER) */
207 } /* jerry_debugger_send_output */
208 
209 /**
210  * Send the log of the program to the debugger client.
211  */
212 void
jerry_debugger_send_log(jerry_log_level_t level,const jerry_char_t * buffer,jerry_size_t str_size)213 jerry_debugger_send_log (jerry_log_level_t level, /**< level of the diagnostics message */
214                          const jerry_char_t *buffer, /**< buffer */
215                          jerry_size_t str_size) /**< string size */
216 {
217 #if ENABLED (JERRY_DEBUGGER)
218   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
219   {
220     jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
221                                 (uint8_t) (level + 2),
222                                 (const uint8_t *) buffer,
223                                 sizeof (uint8_t) * str_size);
224   }
225 #else /* !ENABLED (JERRY_DEBUGGER) */
226   JERRY_UNUSED (level);
227   JERRY_UNUSED (buffer);
228   JERRY_UNUSED (str_size);
229 #endif /* ENABLED (JERRY_DEBUGGER) */
230 } /* jerry_debugger_send_log */
231