Initial version of JerryScript debugger (#1557)
The debugger supports setting breakpoints, execution control (step, next, continue) and getting backtrace. The communication is WebSocket-based, so a browser can communicate with JerryScript without any intermediate application. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: Levente Orban orbanl@inf.u-szeged.hu
This commit is contained in:
committed by
Tilmann Scheller
parent
453066fcf1
commit
025a99ccbb
@@ -39,7 +39,7 @@ typedef const uint8_t *vm_instr_counter_t;
|
||||
/**
|
||||
* Context of interpreter, related to a JS stack frame
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct vm_frame_ctx_t
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
|
||||
uint8_t *byte_code_p; /**< current byte code pointer */
|
||||
@@ -48,6 +48,7 @@ typedef struct
|
||||
ecma_value_t *stack_top_p; /**< stack top pointer */
|
||||
jmem_cpointer_t *literal_start_p; /**< literal list start pointer */
|
||||
ecma_object_t *lex_env_p; /**< current lexical environment */
|
||||
struct vm_frame_ctx_t *prev_context_p; /**< previous context */
|
||||
ecma_value_t this_binding; /**< this binding */
|
||||
ecma_value_t call_block_result; /**< preserve block result during a call */
|
||||
uint16_t context_depth; /**< current context depth */
|
||||
|
||||
+64
-3
@@ -2305,6 +2305,59 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
|
||||
continue;
|
||||
}
|
||||
case VM_OC_BREAKPOINT_ENABLED:
|
||||
{
|
||||
#ifdef JERRY_DEBUGGER
|
||||
if (!(JERRY_CONTEXT (jerry_init_flags) & JERRY_INIT_DEBUGGER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
frame_ctx_p->byte_code_p = byte_code_start_p;
|
||||
|
||||
jerry_debugger_breakpoint_hit ();
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
continue;
|
||||
}
|
||||
case VM_OC_BREAKPOINT_DISABLED:
|
||||
{
|
||||
#ifdef JERRY_DEBUGGER
|
||||
if (!(JERRY_CONTEXT (jerry_init_flags) & JERRY_INIT_DEBUGGER))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
frame_ctx_p->byte_code_p = byte_code_start_p;
|
||||
|
||||
if (JERRY_CONTEXT (debugger_stop_exec)
|
||||
&& (JERRY_CONTEXT (debugger_stop_context) == NULL
|
||||
|| JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p)))
|
||||
{
|
||||
jerry_debugger_breakpoint_hit ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JERRY_CONTEXT (debugger_message_delay) > 0)
|
||||
{
|
||||
JERRY_CONTEXT (debugger_message_delay)--;
|
||||
continue;
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY;
|
||||
|
||||
if (jerry_debugger_receive ())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JERRY_CONTEXT (debugger_stop_exec))
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (debugger_stop_context) == NULL);
|
||||
jerry_debugger_breakpoint_hit ();
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
@@ -2532,7 +2585,6 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
{
|
||||
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
|
||||
ecma_value_t completion_value;
|
||||
vm_frame_ctx_t *prev_context_p;
|
||||
uint16_t argument_end;
|
||||
uint16_t register_end;
|
||||
|
||||
@@ -2577,7 +2629,6 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
|
||||
JERRY_CONTEXT (is_direct_eval_form_call) = false;
|
||||
|
||||
prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p;
|
||||
|
||||
vm_init_loop (frame_ctx_p);
|
||||
@@ -2608,7 +2659,16 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
ecma_fast_free_value (frame_ctx_p->registers_p[i]);
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (vm_top_context_p) = prev_context_p;
|
||||
#ifdef JERRY_DEBUGGER
|
||||
if (JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p))
|
||||
{
|
||||
/* The engine will stop when the next breakpoint is reached. */
|
||||
JERRY_ASSERT (JERRY_CONTEXT (debugger_stop_exec));
|
||||
JERRY_CONTEXT (debugger_stop_context) = NULL;
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
|
||||
JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p->prev_context_p;
|
||||
return completion_value;
|
||||
} /* vm_execute */
|
||||
|
||||
@@ -2654,6 +2714,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
|
||||
frame_ctx.byte_code_p = (uint8_t *) literal_p;
|
||||
frame_ctx.byte_code_start_p = (uint8_t *) literal_p;
|
||||
frame_ctx.lex_env_p = lex_env_p;
|
||||
frame_ctx.prev_context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
frame_ctx.this_binding = this_binding_value;
|
||||
frame_ctx.context_depth = 0;
|
||||
frame_ctx.is_eval_code = is_eval_code;
|
||||
|
||||
@@ -203,6 +203,8 @@ typedef enum
|
||||
VM_OC_FINALLY, /**< finally */
|
||||
VM_OC_CONTEXT_END, /**< context end */
|
||||
VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */
|
||||
VM_OC_BREAKPOINT_ENABLED, /**< enabled breakpoint for debugger */
|
||||
VM_OC_BREAKPOINT_DISABLED, /**< disabled breakpoint for debugger */
|
||||
} vm_oc_types;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user