1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-22 21:23:16 +00:00

Enable debug opcode in vm and debug state for fibers.

This commit is contained in:
Calvin Rose 2018-03-09 17:14:26 -05:00
parent eee453d2c0
commit 0c3b0673ff
7 changed files with 70 additions and 43 deletions

View File

@ -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},

View File

@ -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 */

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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()

View File

@ -118,6 +118,7 @@ enum DstOpCode {
DOP_GET_INDEX,
DOP_PUT_INDEX,
DOP_LENGTH,
DOP_DEBUG,
DOP_INSTRUCTION_COUNT
};

View File

@ -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;
};