Implement vm_throw callback (#4726)

Slightly improve the description of vm_exec_stop callback.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-08-10 15:50:26 +02:00
committed by GitHub
parent b6ec9275aa
commit 444806d78a
15 changed files with 399 additions and 22 deletions
+7 -2
View File
@@ -37,7 +37,8 @@ set(JERRY_SNAPSHOT_EXEC OFF CACHE BOOL "Enable executing
set(JERRY_SNAPSHOT_SAVE OFF CACHE BOOL "Enable saving snapshot files?")
set(JERRY_SYSTEM_ALLOCATOR OFF CACHE BOOL "Enable system allocator?")
set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stopping?")
set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stop callback?")
set(JERRY_VM_THROW OFF CACHE BOOL "Enable VM throw callback?")
set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes")
set(JERRY_GC_LIMIT "(0)" CACHE STRING "Heap usage limit to trigger garbage collection")
set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes")
@@ -96,6 +97,7 @@ message(STATUS "JERRY_SNAPSHOT_SAVE " ${JERRY_SNAPSHOT_SAVE} ${JERRY_
message(STATUS "JERRY_SYSTEM_ALLOCATOR " ${JERRY_SYSTEM_ALLOCATOR})
message(STATUS "JERRY_VALGRIND " ${JERRY_VALGRIND})
message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP})
message(STATUS "JERRY_VM_THROW " ${JERRY_VM_THROW})
message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE})
message(STATUS "JERRY_GC_LIMIT " ${JERRY_GC_LIMIT})
message(STATUS "JERRY_STACK_LIMIT " ${JERRY_STACK_LIMIT})
@@ -627,9 +629,12 @@ if(JERRY_VALGRIND)
set(INCLUDE_CORE_PRIVATE ${INCLUDE_CORE_PRIVATE} ${INCLUDE_THIRD_PARTY_VALGRIND})
endif()
# Enable VM execution stopping
# Enable VM execution stop callback
jerry_add_define01(JERRY_VM_EXEC_STOP)
# Enable VM throw callback
jerry_add_define01(JERRY_VM_THROW)
# Size of heap
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE})
+22 -3
View File
@@ -1800,6 +1800,9 @@ jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check *
#if JERRY_VM_EXEC_STOP
|| feature == JERRY_FEATURE_VM_EXEC_STOP
#endif /* JERRY_VM_EXEC_STOP */
#if JERRY_VM_THROW
|| feature == JERRY_FEATURE_VM_THROW
#endif /* JERRY_VM_THROW */
#if JERRY_BUILTIN_JSON
|| feature == JERRY_FEATURE_JSON
#endif /* JERRY_BUILTIN_JSON */
@@ -5202,8 +5205,8 @@ jerry_create_context (uint32_t heap_size, /**< the size of heap */
} /* jerry_create_context */
/**
* If JERRY_VM_EXEC_STOP is enabled the callback passed to this function is
* periodically called with the user_p argument. If frequency is greater
* When JERRY_VM_EXEC_STOP is enabled, 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
@@ -5219,8 +5222,8 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< per
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;
JERRY_CONTEXT (vm_exec_stop_user_p) = user_p;
#else /* !JERRY_VM_EXEC_STOP */
JERRY_UNUSED (stop_cb);
JERRY_UNUSED (user_p);
@@ -5228,6 +5231,22 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< per
#endif /* JERRY_VM_EXEC_STOP */
} /* jerry_set_vm_exec_stop_callback */
/**
* When JERRY_VM_THROW is enabled, the callback passed to this
* function is called when an error is thrown in ECMAScript code.
*/
void jerry_set_vm_throw_callback (jerry_vm_throw_callback_t throw_cb, /**< callback which is called on throws */
void *user_p) /**< pointer passed to the function */
{
#if JERRY_VM_THROW
JERRY_CONTEXT (vm_throw_callback_p) = throw_cb;
JERRY_CONTEXT (vm_throw_callback_user_p) = user_p;
#else /* !JERRY_VM_THROW */
JERRY_UNUSED (throw_cb);
JERRY_UNUSED (user_p);
#endif /* JERRY_VM_THROW */
} /* jerry_set_vm_throw_callback */
/**
* Get backtrace. The backtrace is an array of strings where
* each string contains the position of the corresponding frame.
+17 -2
View File
@@ -430,13 +430,24 @@
* Enable/Disable the vm execution stop callback function.
*
* Allowed values:
* 0: Disable vm exec stop callbacks.
* 1: Enable vm exec stop callback functionality.
* 0: Disable vm exec stop callback support.
* 1: Enable vm exec stop callback support.
*/
#ifndef JERRY_VM_EXEC_STOP
# define JERRY_VM_EXEC_STOP 0
#endif /* !defined (JERRY_VM_EXEC_STOP) */
/**
* Enable/Disable the vm throw callback function.
*
* Allowed values:
* 0: Disable vm throw callback support.
* 1: Enable vm throw callback support.
*/
#ifndef JERRY_VM_THROW
# define JERRY_VM_THROW 0
#endif /* !defined (JERRY_VM_THROW) */
/**
* Advanced section configurations.
*/
@@ -680,6 +691,10 @@
|| ((JERRY_VM_EXEC_STOP != 0) && (JERRY_VM_EXEC_STOP != 1))
# error "Invalid value for 'JERRY_VM_EXEC_STOP' macro."
#endif
#if !defined (JERRY_VM_THROW) \
|| ((JERRY_VM_THROW != 0) && (JERRY_VM_THROW != 1))
# error "Invalid value for 'JERRY_VM_THROW' macro."
#endif
/**
* Cross component requirements check.
+3
View File
@@ -63,6 +63,9 @@ typedef enum
ECMA_STATUS_EXCEPTION = (1u << 3), /**< last exception is a normal exception */
ECMA_STATUS_ABORT = (1u << 4), /**< last exception is an abort */
ECMA_STATUS_ERROR_UPDATE = (1u << 5), /**< the error_object_created_callback_p is called */
#if JERRY_VM_THROW
ECMA_STATUS_ERROR_THROWN = (1u << 6), /**< the vm_throw_callback_p is called */
#endif /* JERRY_VM_THROW */
} ecma_status_flag_t;
/**
+1
View File
@@ -360,6 +360,7 @@ bool jerry_backtrace_is_strict (jerry_backtrace_frame_t *frame_p);
* Miscellaneous functions.
*/
void jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, void *user_p, uint32_t frequency);
void jerry_set_vm_throw_callback (jerry_vm_throw_callback_t throw_cb, void *user_p);
jerry_value_t jerry_get_resource_name (const jerry_value_t value);
jerry_value_t jerry_get_user_value (const jerry_value_t value);
+10
View File
@@ -91,6 +91,7 @@ typedef enum
JERRY_FEATURE_SNAPSHOT_EXEC, /**< executing snapshot files */
JERRY_FEATURE_DEBUGGER, /**< debugging */
JERRY_FEATURE_VM_EXEC_STOP, /**< stopping ECMAScript execution */
JERRY_FEATURE_VM_THROW, /**< capturing ECMAScript throws */
JERRY_FEATURE_JSON, /**< JSON support */
JERRY_FEATURE_PROMISE, /**< promise support */
JERRY_FEATURE_TYPEDARRAY, /**< Typedarray support */
@@ -306,6 +307,15 @@ typedef void (*jerry_error_object_created_callback_t) (const jerry_value_t error
*/
typedef jerry_value_t (*jerry_vm_exec_stop_callback_t) (void *user_p);
/**
* Callback function which is called when an error is thrown in an ECMAScript code.
* The callback should not change the error_value. The callback is not called again
* until the value is caught.
*
* Note: the engine considers errors thrown by external functions as never caught.
*/
typedef void (*jerry_vm_throw_callback_t) (const jerry_value_t error_value, void *user_p);
/**
* Function type applied for each data property of an object.
*/
+5 -2
View File
@@ -113,8 +113,11 @@ jcontext_take_exception (void)
{
JERRY_ASSERT (jcontext_has_pending_exception ());
jcontext_set_abort_flag (false);
jcontext_set_exception_flag (false);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~(ECMA_STATUS_EXCEPTION
#if JERRY_VM_THROW
| ECMA_STATUS_ERROR_THROWN
#endif /* JERRY_VM_THROW */
| ECMA_STATUS_ABORT);
return JERRY_CONTEXT (error_value);
} /* jcontext_take_exception */
+5
View File
@@ -200,6 +200,11 @@ struct jerry_context_t
* ECMAScript execution should be stopped */
#endif /* JERRY_VM_EXEC_STOP */
#if JERRY_VM_THROW
void *vm_throw_callback_user_p; /**< user pointer for vm_throw_callback_p */
jerry_vm_throw_callback_t vm_throw_callback_p; /**< callback for capturing throws */
#endif /* JERRY_VM_THROW */
#if (JERRY_STACK_LIMIT != 0)
uintptr_t stack_base; /**< stack base marker */
#endif /* (JERRY_STACK_LIMIT != 0) */
+17
View File
@@ -4457,6 +4457,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (context_type == VM_CONTEXT_FINALLY_THROW)
{
jcontext_raise_exception (*stack_top_p);
#if JERRY_VM_THROW
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_ERROR_THROWN;
#endif /* JERRY_VM_THROW */
result = ECMA_VALUE_ERROR;
#if JERRY_DEBUGGER
@@ -4789,6 +4792,20 @@ error:
ecma_fast_free_value (stack_item);
}
#if JERRY_VM_THROW
if (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_ERROR_THROWN))
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_ERROR_THROWN;
jerry_vm_throw_callback_t vm_throw_callback_p = JERRY_CONTEXT (vm_throw_callback_p);
if (vm_throw_callback_p != NULL)
{
vm_throw_callback_p (JERRY_CONTEXT (error_value), JERRY_CONTEXT (vm_throw_callback_user_p));
}
}
#endif /* JERRY_VM_THROW */
#if JERRY_DEBUGGER
const uint32_t dont_stop = (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION
| JERRY_DEBUGGER_VM_IGNORE