-
Notifications
You must be signed in to change notification settings - Fork 683
Support ECMAScript stopping in JerryScript. #1753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ Possible compile time enabled feature types: | |
- JERRY_FEATURE_SNAPSHOT_SAVE - saving snapshot files | ||
- JERRY_FEATURE_SNAPSHOT_EXEC - executing snapshot files | ||
- JERRY_FEATURE_DEBUGGER - debugging | ||
- JERRY_FEATURE_VM_EXEC_STOP - stopping ECMAScript execution | ||
|
||
## jerry_char_t | ||
|
||
|
@@ -234,6 +235,28 @@ typedef bool (*jerry_object_property_foreach_t) (const jerry_value_t property_na | |
void *user_data_p); | ||
``` | ||
|
||
## jerry_vm_exec_stop_callback_t | ||
|
||
**Summary** | ||
|
||
Callback which tells whether the ECMAScript execution should be stopped. | ||
If it returns with undefined value the ECMAScript execution continues. | ||
Otherwise the result is thrown by the engine (if the error flag is not | ||
set for the returned value the engine automatically sets it). The | ||
callback function might be called again even if it threw an error. | ||
In this case the function must throw the same error again. | ||
|
||
**Prototype** | ||
|
||
```c | ||
typedef jerry_value_t (*jerry_vm_exec_stop_callback_t) (void *user_p); | ||
``` | ||
|
||
**See also** | ||
|
||
- [jerry_set_vm_exec_stop_callback](#jerry_set_vm_exec_stop_callback) | ||
|
||
|
||
# General engine functions | ||
|
||
## jerry_init | ||
|
@@ -3896,3 +3919,81 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, | |
- [jerry_init](#jerry_init) | ||
- [jerry_cleanup](#jerry_cleanup) | ||
- [jerry_register_magic_strings](#jerry_register_magic_strings) | ||
|
||
|
||
# Miscellaneous functions | ||
|
||
## jerry_set_vm_exec_stop_callback | ||
|
||
**Summary** | ||
|
||
When JERRY_FEATURE_VM_EXEC_STOP is enabled a callback function can be | ||
specified by this function. This callback is periodically called when | ||
JerryScript executes an ECMAScript program. | ||
|
||
If the callback returns with undefined value the ECMAScript execution | ||
continues. Otherwise the result is thrown by the engine (if the error | ||
flag is not set for the returned value the engine automatically sets | ||
it). The callback function might be called again even if it threw | ||
an error. In this case the function must throw the same error again. | ||
|
||
To reduce the CPU overhead of constantly checking the termination | ||
condition the callback is called when a backward jump is executed | ||
or an exception is caught. Setting the `frequency` to a greater | ||
than `1` value reduces this overhead further. If its value is N | ||
only every Nth event (backward jump, etc.) trigger the next check. | ||
|
||
|
||
**Prototype** | ||
|
||
```c | ||
void | ||
jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we document the signature of |
||
void *user_p, | ||
uint32_t frequency); | ||
``` | ||
|
||
- `stop_cb` - periodically called callback (passing NULL disables this feature) | ||
- `user_p` - user pointer passed to the `stop_cb` function | ||
- `frequency` - frequency of calling the `stop_cb` function | ||
|
||
**Example** | ||
|
||
```c | ||
static jerry_value_t | ||
vm_exec_stop_callback (void *user_p) | ||
{ | ||
static int countdown = 10; | ||
|
||
while (countdown > 0) | ||
{ | ||
countdown--; | ||
return jerry_create_undefined (); | ||
} | ||
|
||
// The error flag is added automatically. | ||
return jerry_create_string ((const jerry_char_t *) "Abort script"); | ||
} | ||
|
||
{ | ||
jerry_init (JERRY_INIT_EMPTY); | ||
|
||
jerry_set_vm_exec_stop_callback (vm_exec_stop_callback, &countdown, 16); | ||
|
||
// Inifinte loop. | ||
const char *src_p = "while(true) {}"; | ||
|
||
jerry_value_t src = jerry_parse ((jerry_char_t *) src_p, strlen (src_p), false); | ||
jerry_release_value (jerry_run (src)); | ||
jerry_release_value (src); | ||
jerry_cleanup (); | ||
} | ||
``` | ||
|
||
**See also** | ||
|
||
- [jerry_init](#jerry_init) | ||
- [jerry_cleanup](#jerry_cleanup) | ||
- [jerry_parse](#jerry_parse) | ||
- [jerry_run](#jerry_run) | ||
- [jerry_vm_exec_stop_callback_t](#jerry_vm_exec_stop_callback_t) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -618,6 +618,9 @@ bool jerry_is_feature_enabled (const jerry_feature_t feature) | |
#ifdef JERRY_DEBUGGER | ||
|| feature == JERRY_FEATURE_DEBUGGER | ||
#endif /* JERRY_DEBUGGER */ | ||
#ifdef JERRY_VM_EXEC_STOP | ||
|| feature == JERRY_FEATURE_VM_EXEC_STOP | ||
#endif /* JERRY_VM_EXEC_STOP */ | ||
); | ||
} /* jerry_is_feature_enabled */ | ||
|
||
|
@@ -2145,6 +2148,33 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string | |
(lit_utf8_size_t) buf_size); | ||
} /* jerry_is_valid_cesu8_string */ | ||
|
||
/** | ||
* If JERRY_VM_EXEC_STOP is defined the callback passed to this function is | ||
* periodically called with the user_p argument. If frequency is greater | ||
* than 1, the callback is only called at every frequency ticks. | ||
*/ | ||
void | ||
jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< periodically called user function */ | ||
void *user_p, /**< pointer passed to the function */ | ||
uint32_t frequency) /**< frequency of the function call */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the unit of frequency? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is described in the documentation. There is no real unit. If the callback could be called |
||
{ | ||
#ifdef JERRY_VM_EXEC_STOP | ||
if (frequency == 0) | ||
{ | ||
frequency = 1; | ||
} | ||
|
||
JERRY_CONTEXT (vm_exec_stop_frequency) = frequency; | ||
JERRY_CONTEXT (vm_exec_stop_counter) = frequency; | ||
JERRY_CONTEXT (vm_exec_stop_user_p) = user_p; | ||
JERRY_CONTEXT (vm_exec_stop_cb) = stop_cb; | ||
#else /* !JERRY_VM_EXEC_STOP */ | ||
JERRY_UNUSED (stop_cb); | ||
JERRY_UNUSED (user_p); | ||
JERRY_UNUSED (frequency); | ||
#endif /* JERRY_VM_EXEC_STOP */ | ||
} /* jerry_set_vm_exec_stop_callback */ | ||
|
||
/** | ||
* @} | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on
jerryscript.h
: add a new top level header here:# Miscellaneous functions.