mirror of
https://github.com/janet-lang/janet
synced 2025-01-12 16:40:27 +00:00
Enable debug opcode in vm and debug state for fibers.
This commit is contained in:
parent
eee453d2c0
commit
0c3b0673ff
@ -86,6 +86,7 @@ static const DstInstructionDef dst_ops[] = {
|
||||
{"call", DOP_CALL},
|
||||
{"clo", DOP_CLOSURE},
|
||||
{"cmp", DOP_COMPARE},
|
||||
{"debug", DOP_DEBUG},
|
||||
{"div", DOP_DIVIDE},
|
||||
{"divim", DOP_DIVIDE_IMMEDIATE},
|
||||
{"divi", DOP_DIVIDE_INTEGER},
|
||||
|
@ -85,7 +85,8 @@ enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = {
|
||||
DIT_SSS, /* DOP_PUT, */
|
||||
DIT_SSU, /* DOP_GET_INDEX, */
|
||||
DIT_SSU, /* DOP_PUT_INDEX, */
|
||||
DIT_SS /* DOP_LENGTH */
|
||||
DIT_SS, /* DOP_LENGTH */
|
||||
DIT_0 /* DOP_DEBUG */
|
||||
};
|
||||
|
||||
/* Verify some bytecode */
|
||||
|
@ -192,6 +192,9 @@ int dst_core_fiber_status(DstArgs args) {
|
||||
case DST_FIBER_ERROR:
|
||||
status = ":error";
|
||||
break;
|
||||
case DST_FIBER_DEBUG:
|
||||
status = ":debug";
|
||||
break;
|
||||
}
|
||||
return dst_return(args, dst_csymbolv(status));
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ DstFiber *dst_fiber(int32_t capacity) {
|
||||
}
|
||||
fiber->parent = NULL;
|
||||
fiber->maxstack = DST_STACK_MAX;
|
||||
fiber->flags = DST_FIBER_MASK_DEBUG;
|
||||
return dst_fiber_reset(fiber);
|
||||
}
|
||||
|
||||
|
@ -30,19 +30,16 @@ DstFiber *dst_vm_fiber = NULL;
|
||||
int dst_vm_stackn = 0;
|
||||
|
||||
/* Helper to ensure proper fiber is activated after returning */
|
||||
static int dst_update_fiber() {
|
||||
static int dst_update_fiber(uint32_t mask) {
|
||||
if (dst_vm_fiber->frame == 0) {
|
||||
dst_vm_fiber->status = DST_FIBER_DEAD;
|
||||
}
|
||||
while (dst_vm_fiber->status == DST_FIBER_DEAD ||
|
||||
dst_vm_fiber->status == DST_FIBER_ERROR) {
|
||||
dst_vm_fiber->status == DST_FIBER_ERROR ||
|
||||
dst_vm_fiber->status == DST_FIBER_DEBUG ||
|
||||
dst_vm_fiber->flags & mask) {
|
||||
if (NULL != dst_vm_fiber->parent) {
|
||||
dst_vm_fiber = dst_vm_fiber->parent;
|
||||
if (dst_vm_fiber->status == DST_FIBER_ALIVE) {
|
||||
/* If the parent thread is still alive,
|
||||
we are inside a cfunction */
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* The root thread has terminated */
|
||||
return 1;
|
||||
@ -139,6 +136,7 @@ static void *op_lookup[255] = {
|
||||
&&label_DOP_GET_INDEX,
|
||||
&&label_DOP_PUT_INDEX,
|
||||
&&label_DOP_LENGTH,
|
||||
&&label_DOP_DEBUG,
|
||||
&&label_unknown_op
|
||||
};
|
||||
#else
|
||||
@ -204,16 +202,13 @@ static void *op_lookup[255] = {
|
||||
|
||||
vm_init_fiber_state();
|
||||
|
||||
/* Main interpreter loop. It is large, but it is
|
||||
* is maintainable. Adding new opcodes is mostly just adding newcases
|
||||
* to this loop, adding the opcode to opcodes.h, and adding it to the assembler.
|
||||
* Some opcodes, especially ones that do arithmetic, are almost entirely
|
||||
* templated by the above macros. */
|
||||
/* Main interpreter loop. Sematically is a switch on
|
||||
* (*pc & 0xFF) inside of an infinte loop. */
|
||||
VM_START();
|
||||
|
||||
VM_DEFAULT();
|
||||
retreg = dst_wrap_string(dst_formatc("unknown opcode %d", *pc & 0xFF));
|
||||
goto vm_error;
|
||||
VM_OP(DOP_DEBUG)
|
||||
goto vm_debug;
|
||||
|
||||
VM_OP(DOP_NOOP)
|
||||
pc++;
|
||||
@ -707,60 +702,78 @@ static void *op_lookup[255] = {
|
||||
vm_return_cfunc:
|
||||
{
|
||||
dst_fiber_popframe(dst_vm_fiber);
|
||||
if (dst_update_fiber()) {
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 0;
|
||||
}
|
||||
if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value;
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
stack[oparg(1, 0xFF)] = retreg;
|
||||
pc++;
|
||||
vm_checkgc_next();
|
||||
}
|
||||
|
||||
/* Return from a cfunction that is in tail position (pop 2 stack frames) */
|
||||
vm_return_cfunc_tail:
|
||||
{
|
||||
dst_fiber_popframe(dst_vm_fiber);
|
||||
if (dst_update_fiber()) {
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 0;
|
||||
}
|
||||
/* Fall through to normal return */
|
||||
if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value;
|
||||
goto vm_return;
|
||||
}
|
||||
|
||||
/* Handle returning from stack frame. Expect return value in retreg */
|
||||
vm_return:
|
||||
{
|
||||
dst_fiber_popframe(dst_vm_fiber);
|
||||
if (dst_update_fiber()) {
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 0;
|
||||
}
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
func = dst_stack_frame(stack)->func;
|
||||
pc = dst_stack_frame(stack)->pc;
|
||||
stack[oparg(1, 0xFF)] = retreg;
|
||||
pc++;
|
||||
vm_checkgc_next();
|
||||
if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value;
|
||||
goto vm_reset;
|
||||
}
|
||||
|
||||
/* Handle errors from c functions and vm opcodes */
|
||||
vm_error:
|
||||
{
|
||||
dst_vm_fiber->status = DST_FIBER_ERROR;
|
||||
if (dst_update_fiber()) {
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 1;
|
||||
}
|
||||
if (dst_update_fiber(DST_FIBER_MASK_ERROR)) goto vm_exit_error;
|
||||
goto vm_reset;
|
||||
}
|
||||
|
||||
/* Handle debugger interrupts */
|
||||
vm_debug:
|
||||
{
|
||||
dst_vm_fiber->status = DST_FIBER_DEBUG;
|
||||
if (dst_update_fiber(DST_FIBER_MASK_DEBUG)) goto vm_exit_debug;
|
||||
goto vm_reset;
|
||||
}
|
||||
|
||||
/* Reset state of machine */
|
||||
vm_reset:
|
||||
{
|
||||
stack = dst_vm_fiber->data + dst_vm_fiber->frame;
|
||||
func = dst_stack_frame(stack)->func;
|
||||
pc = dst_stack_frame(stack)->pc;
|
||||
stack[oparg(1, 0xFF)] = retreg;
|
||||
pc++;
|
||||
vm_checkgc_next();
|
||||
}
|
||||
|
||||
/* Exit loop with return value */
|
||||
vm_exit_value:
|
||||
{
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Exit loop with error value */
|
||||
vm_exit_error:
|
||||
{
|
||||
*returnreg = retreg;
|
||||
dst_vm_stackn--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Exit loop with debug */
|
||||
vm_exit_debug:
|
||||
{
|
||||
*returnreg = dst_wrap_nil();
|
||||
dst_vm_stackn--;
|
||||
return 2;
|
||||
}
|
||||
|
||||
VM_END()
|
||||
|
@ -118,6 +118,7 @@ enum DstOpCode {
|
||||
DOP_GET_INDEX,
|
||||
DOP_PUT_INDEX,
|
||||
DOP_LENGTH,
|
||||
DOP_DEBUG,
|
||||
DOP_INSTRUCTION_COUNT
|
||||
};
|
||||
|
||||
|
@ -305,6 +305,11 @@ struct DstArgs {
|
||||
Dst *ret;
|
||||
};
|
||||
|
||||
/* Fiber signal masks */
|
||||
#define DST_FIBER_MASK_RETURN 1
|
||||
#define DST_FIBER_MASK_ERROR 2
|
||||
#define DST_FIBER_MASK_DEBUG 4
|
||||
|
||||
/* A lightweight green thread in dst. Does not correspond to
|
||||
* operating system threads. */
|
||||
struct DstFiber {
|
||||
@ -315,12 +320,14 @@ struct DstFiber {
|
||||
int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */
|
||||
int32_t capacity;
|
||||
int32_t maxstack; /* Arbitrary defined limit for stack overflow */
|
||||
uint32_t flags; /* Various flags */
|
||||
enum {
|
||||
DST_FIBER_PENDING,
|
||||
DST_FIBER_NEW,
|
||||
DST_FIBER_ALIVE,
|
||||
DST_FIBER_DEAD,
|
||||
DST_FIBER_ERROR
|
||||
DST_FIBER_ERROR,
|
||||
DST_FIBER_DEBUG
|
||||
} status;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user