Rework jerry_debugger_wait_for_client_source to use a callback.

The jerry_debugger_wait_and_run_client_source function is renamed to
jerry_debugger_wait_for_client_source and a callback is added which
is called when the source is received. Inside the callback the
application is free to do anything with the received source code.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2017-09-21 00:15:09 -07:00
committed by yichoi
parent 9c3f814357
commit 7713d30702
4 changed files with 174 additions and 56 deletions
+87 -18
View File
@@ -83,6 +83,35 @@ debugger is disabled.
The following section describes the debugger functions The following section describes the debugger functions
available for the host application. available for the host application.
## JerryScript debugger types
## jerry_debugger_wait_for_source_callback_t
**Summary**
This callback function is called by
[jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
when a source code is received successfully.
**Prototype**
```c
typedef jerry_value_t
(*jerry_debugger_wait_for_source_callback_t) (const jerry_char_t *resource_name_p,
size_t resource_name_size,
const jerry_char_t *source_p,
size_t source_size, void *user_p);
```
- `resource_name_p` - resource (usually a file) name of the source code
- `resource_name_size` - size of resource name
- `source_p` - source code character data
- `source_size` - size of source code
- `user_p` - custom pointer passed to [jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
## JerryScript debugger functions
### jerry_debugger_init ### jerry_debugger_init
**Summary** **Summary**
@@ -244,46 +273,86 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
} }
``` ```
### jerry_debugger_wait_and_run_client_source ### jerry_debugger_wait_for_client_source
**Summary** **Summary**
Stops the engine and puts it into a waiting loop. If the client sends Asks the client to provide the next source code. The function
a source code and JerryScript receives that, then the function will waits until the whole source code is received. As a reply the
run the source with the initialized options, after that the engine will the client may request a context reset or notify that no more
wait for a new source until the client send a close signal. source is available. These notifications are passed back as the
return value of the function.
**Prototype** **Prototype**
```c ```c
jerry_debugger_wait_and_run_type_t jerry_debugger_wait_for_source_status_t
jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p,
void *user_p, jerry_value_t *return_value)
``` ```
**Example** **Example**
```c ```c
jerry_init (JERRY_INIT_EMPTY); /**
jerry_debugger_init (5001); * Runs the source code received by jerry_debugger_wait_for_client_source.
*/
static jerry_value_t
wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */
size_t resource_name_size, /**< size of resource name */
const jerry_char_t *source_p, /**< source code */
size_t source_size, /**< source code size */
void *user_p __attribute__((unused))) /**< user pointer */
{
jerry_value_t ret_val = jerry_parse_named_resource (resource_name_p,
resource_name_size,
source_p,
source_size,
false);
jerry_value_t run_result; if (!jerry_value_has_error_flag (ret_val))
jerry_debugger_wait_and_run_type_t receive_status; {
jerry_value_t func_val = ret_val;
ret_val = jerry_run (func_val);
jerry_release_value (func_val);
}
return ret_val;
} /* wait_for_source_callback */
int main ()
{
do do
{ {
receive_status = jerry_debugger_wait_and_run_client_source (&run_result); /* Create a new JerryScript instance when a context reset is
* received. Applications usually registers their core bindings
* here as well (e.g. print, setTimeout). */
jerry_init (JERRY_INIT_EMPTY);
jerry_debugger_init (5001);
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED) do
{ {
// Handle the failure (e.g. create an error). jerry_value_t run_result;
jerry_debugger_wait_for_source_status_t receive_status;
receive_status = jerry_debugger_wait_and_run_client_source (wait_for_source_callback,
NULL,
&run_result);
jerry_release_value (run_result);
} }
} while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
jerry_release_value (run_result); jerry_cleanup ();
} }
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED); while (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED);
jerry_cleanup (); if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
{
// Handle the failure (e.g. display an error).
}
return 0;
}
``` ```
### jerry_debugger_send_output ### jerry_debugger_send_output
+18 -20
View File
@@ -111,8 +111,10 @@ jerry_debugger_init (uint16_t port) /**< server port number */
* JERRY_DEBUGGER_SOURCE_END - the end of the source codes * JERRY_DEBUGGER_SOURCE_END - the end of the source codes
* JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED - the end of the context * JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED - the end of the context
*/ */
jerry_debugger_wait_and_run_type_t jerry_debugger_wait_for_source_status_t
jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [out] parse and run return value */ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p, /**< callback function */
void *user_p, /**< user pointer passed to the callback */
jerry_value_t *return_value) /**< [out] parse and run return value */
{ {
*return_value = jerry_create_undefined (); *return_value = jerry_create_undefined ();
@@ -122,7 +124,7 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [ou
{ {
JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_SOURCE_MODE); JERRY_CONTEXT (debugger_flags) = (uint8_t) (JERRY_CONTEXT (debugger_flags) | JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
jerry_debugger_uint8_data_t *client_source_data_p = NULL; jerry_debugger_uint8_data_t *client_source_data_p = NULL;
jerry_debugger_wait_and_run_type_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED; jerry_debugger_wait_for_source_status_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
/* Notify the client about that the engine is waiting for a source. */ /* Notify the client about that the engine is waiting for a source. */
jerry_debugger_send_type (JERRY_DEBUGGER_WAIT_FOR_SOURCE); jerry_debugger_send_type (JERRY_DEBUGGER_WAIT_FOR_SOURCE);
@@ -159,24 +161,17 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [ou
{ {
JERRY_ASSERT (client_source_data_p != NULL); JERRY_ASSERT (client_source_data_p != NULL);
jerry_char_t *string_p = (jerry_char_t *) (client_source_data_p + 1); jerry_char_t *resource_name_p = (jerry_char_t *) (client_source_data_p + 1);
size_t name_size = strlen ((const char *) string_p); size_t resource_name_size = strlen ((const char *) resource_name_p);
*return_value = jerry_parse_named_resource (string_p, *return_value = callback_p (resource_name_p,
name_size, resource_name_size,
(string_p + name_size + 1), resource_name_p + resource_name_size + 1,
(client_source_data_p->uint8_size - name_size - 1), client_source_data_p->uint8_size - resource_name_size - 1,
false); user_p);
if (!jerry_value_has_error_flag (*return_value)) ret_type = JERRY_DEBUGGER_SOURCE_RECEIVED;
{ break;
jerry_value_t func_val = *return_value;
*return_value = jerry_run (func_val);
jerry_release_value (func_val);
ret_type = JERRY_DEBUGGER_SOURCE_RECEIVED;
break;
}
} }
} }
@@ -198,9 +193,12 @@ jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value) /**< [ou
return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED; return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
#else #else
JERRY_UNUSED (callback_p);
JERRY_UNUSED (user_p);
return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED; return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
#endif /* JERRY_DEBUGGER */ #endif /* JERRY_DEBUGGER */
} /* jerry_debugger_wait_and_run_client_source */ } /* jerry_debugger_wait_for_client_source */
/** /**
* Send the output of the program to the debugger client. * Send the output of the program to the debugger client.
+16 -2
View File
@@ -36,7 +36,19 @@ typedef enum
JERRY_DEBUGGER_SOURCE_RECEIVED = 1, /**< a source has been received */ JERRY_DEBUGGER_SOURCE_RECEIVED = 1, /**< a source has been received */
JERRY_DEBUGGER_SOURCE_END = 2, /**< the end of the sources signal received */ JERRY_DEBUGGER_SOURCE_END = 2, /**< the end of the sources signal received */
JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED, /**< the context reset request has been received */ JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED, /**< the context reset request has been received */
} jerry_debugger_wait_and_run_type_t; } jerry_debugger_wait_for_source_status_t;
/**
* Callback for jerry_debugger_wait_and_run_client_source
*
* The callback receives the resource name, source code and a user pointer.
*
* @return this value is passed back by jerry_debugger_wait_and_run_client_source
*/
typedef jerry_value_t (*jerry_debugger_wait_for_source_callback_t) (const jerry_char_t *resource_name_p,
size_t resource_name_size,
const jerry_char_t *source_p,
size_t source_size, void *user_p);
/** /**
* Engine debugger functions. * Engine debugger functions.
@@ -46,7 +58,9 @@ bool jerry_debugger_is_connected (void);
void jerry_debugger_stop (void); void jerry_debugger_stop (void);
void jerry_debugger_continue (void); void jerry_debugger_continue (void);
void jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint); void jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint);
jerry_debugger_wait_and_run_type_t jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value); 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);
void jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t str_size, uint8_t type); void jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t str_size, uint8_t type);
/** /**
+53 -16
View File
@@ -268,6 +268,38 @@ register_js_function (const char *name_p, /**< name of the function */
jerry_release_value (result_val); jerry_release_value (result_val);
} /* register_js_function */ } /* register_js_function */
#ifdef JERRY_DEBUGGER
/**
* Runs the source code received by jerry_debugger_wait_for_client_source.
*
* @return result fo the source code execution
*/
static jerry_value_t
wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */
size_t resource_name_size, /**< size of resource name */
const jerry_char_t *source_p, /**< source code */
size_t source_size, /**< source code size */
void *user_p __attribute__((unused))) /**< user pointer */
{
jerry_value_t ret_val = jerry_parse_named_resource (resource_name_p,
resource_name_size,
source_p,
source_size,
false);
if (!jerry_value_has_error_flag (ret_val))
{
jerry_value_t func_val = ret_val;
ret_val = jerry_run (func_val);
jerry_release_value (func_val);
}
return ret_val;
} /* wait_for_source_callback */
#endif /* JERRY_DEBUGGER */
/** /**
* Command line option IDs * Command line option IDs
*/ */
@@ -723,14 +755,18 @@ main (int argc,
{ {
is_repl_mode = false; is_repl_mode = false;
#ifdef JERRY_DEBUGGER #ifdef JERRY_DEBUGGER
jerry_value_t run_result;
jerry_debugger_wait_and_run_type_t receive_status;
do while (true)
{ {
jerry_debugger_wait_for_source_status_t receive_status;
do do
{ {
receive_status = jerry_debugger_wait_and_run_client_source (&run_result); jerry_value_t run_result;
receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
NULL,
&run_result);
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED) if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
{ {
@@ -747,21 +783,22 @@ main (int argc,
} }
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED); while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
if (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED) if (receive_status != JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED)
{ {
jerry_cleanup (); break;
jerry_init (flags);
jerry_debugger_init (debug_port);
register_js_function ("assert", jerryx_handler_assert);
register_js_function ("gc", jerryx_handler_gc);
register_js_function ("print", jerryx_handler_print);
ret_value = jerry_create_undefined ();
} }
jerry_cleanup ();
jerry_init (flags);
jerry_debugger_init (debug_port);
register_js_function ("assert", jerryx_handler_assert);
register_js_function ("gc", jerryx_handler_gc);
register_js_function ("print", jerryx_handler_print);
ret_value = jerry_create_undefined ();
} }
while (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED);
#endif /* JERRY_DEBUGGER */ #endif /* JERRY_DEBUGGER */
} }