added the ability to inspect the stack from the debugger
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
|
||||
fun k(k)
|
||||
return k();
|
||||
return k(k);
|
||||
|
||||
k(k);
|
||||
|
||||
|
||||
+42
-1
@@ -267,7 +267,8 @@ _Bool Debug_Callback(Runtime *runtime, void *userp)
|
||||
"step .............. Run an instruction\n"
|
||||
"quit .............. Stop execution\n"
|
||||
"continue .......... Run until a breakpoint or the end of the code is reached\n"
|
||||
"breakpoint ........ Add a breakpoint\n");
|
||||
"breakpoint ........ Add a breakpoint\n"
|
||||
"stack ............. Show the contents of the stack\n");
|
||||
}
|
||||
else if(!strcmp(argv[1], "help"))
|
||||
{
|
||||
@@ -339,6 +340,17 @@ _Bool Debug_Callback(Runtime *runtime, void *userp)
|
||||
" | a line number, a character offset or an instruction index.\n"
|
||||
"\n");
|
||||
}
|
||||
else if(!strcmp(argv[1], "stack"))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
" Command | stack\n"
|
||||
" | \n"
|
||||
" Usage | > stack\n"
|
||||
" | \n"
|
||||
" Description | Show the contents of the stack.\n"
|
||||
"\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "Unknown command \"%s\".\n", argv[1]);
|
||||
@@ -436,6 +448,35 @@ _Bool Debug_Callback(Runtime *runtime, void *userp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if(!strcmp(argv[0], "stack"))
|
||||
{
|
||||
Stack *stack = Runtime_GetStack(runtime);
|
||||
assert(stack != NULL);
|
||||
|
||||
Error error;
|
||||
Error_Init(&error);
|
||||
|
||||
if(Stack_Size(stack) == 0)
|
||||
fprintf(stderr, "The stack is empty.\n");
|
||||
|
||||
for(int i = 0; i < (int) Stack_Size(stack); i += 1)
|
||||
{
|
||||
Object *obj = Stack_Top(stack, -i);
|
||||
assert(obj != NULL);
|
||||
|
||||
fprintf(stderr, " %d | ", i);
|
||||
Object_Print(obj, stderr, &error);
|
||||
|
||||
if(error.occurred)
|
||||
{
|
||||
Error_Free(&error);
|
||||
Error_Init(&error);
|
||||
fprintf(stderr, "(unprintable)");
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
else if(!strcmp(argv[0], "quit"))
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "runtime.h"
|
||||
|
||||
#define MAX_FRAME_STACK 16
|
||||
#define MAX_FRAMES 1024
|
||||
#define MAX_FRAMES 16
|
||||
|
||||
typedef struct Frame Frame;
|
||||
|
||||
@@ -25,6 +25,11 @@ struct xRuntime {
|
||||
Heap *heap;
|
||||
};
|
||||
|
||||
Stack *Runtime_GetStack(Runtime *runtime)
|
||||
{
|
||||
return Stack_Copy(runtime->stack, 1);
|
||||
}
|
||||
|
||||
Heap *Runtime_GetHeap(Runtime *runtime)
|
||||
{
|
||||
return runtime->heap;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define RUNTIME_H
|
||||
#include <stdio.h> // meh.. just for the definition of FILE.
|
||||
#include "../utils/error.h"
|
||||
#include "../utils/stack.h"
|
||||
#include "../objects/objects.h"
|
||||
#include "../common/executable.h"
|
||||
|
||||
@@ -11,6 +12,7 @@ void Runtime_Free(Runtime *runtime);
|
||||
_Bool Runtime_Pop(Runtime *runtime, Error *error, unsigned int n);
|
||||
_Bool Runtime_Push(Runtime *runtime, Error *error, Object *obj);
|
||||
Heap* Runtime_GetHeap(Runtime *runtime);
|
||||
Stack* Runtime_GetStack(Runtime *runtime);
|
||||
Object* Runtime_GetBuiltins(Runtime *runtime, Error *error);
|
||||
int Runtime_GetCurrentIndex(Runtime *runtime);
|
||||
Executable *Runtime_GetCurrentExecutable(Runtime *runtime);
|
||||
|
||||
+60
-1
@@ -1,12 +1,20 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "stack.h"
|
||||
#include "defs.h"
|
||||
|
||||
struct xStack {
|
||||
unsigned int size, used;
|
||||
unsigned int size,
|
||||
used;
|
||||
int refs;
|
||||
void *body[];
|
||||
};
|
||||
|
||||
_Bool Stack_IsReadOnlyCopy(Stack *s)
|
||||
{
|
||||
return (uintptr_t) s & (uintptr_t) 1;
|
||||
}
|
||||
|
||||
void *Stack_New(int size)
|
||||
{
|
||||
if(size < 0)
|
||||
@@ -17,15 +25,26 @@ void *Stack_New(int size)
|
||||
if(s == NULL)
|
||||
return NULL;
|
||||
|
||||
assert((intptr_t) s % 8 == 0);
|
||||
|
||||
s->size = size;
|
||||
s->used = 0;
|
||||
s->refs = 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
static Stack *unmark(Stack *s)
|
||||
{
|
||||
return (Stack*) ((intptr_t) s & ~ (intptr_t) 1);
|
||||
}
|
||||
|
||||
void *Stack_Top(Stack *s, int n)
|
||||
{
|
||||
assert(n <= 0);
|
||||
|
||||
// Remove readonly bit.
|
||||
s = unmark(s);
|
||||
|
||||
if(s->used == 0)
|
||||
return NULL;
|
||||
|
||||
@@ -37,6 +56,9 @@ void *Stack_Top(Stack *s, int n)
|
||||
|
||||
_Bool Stack_Pop(Stack *s, unsigned int n)
|
||||
{
|
||||
if(Stack_IsReadOnlyCopy(s))
|
||||
return 0;
|
||||
|
||||
if(s->used < n)
|
||||
return 0;
|
||||
|
||||
@@ -49,6 +71,9 @@ _Bool Stack_Push(Stack *s, void *item)
|
||||
assert(s != NULL);
|
||||
assert(item != NULL);
|
||||
|
||||
if(Stack_IsReadOnlyCopy(s))
|
||||
return 0;
|
||||
|
||||
if(s->used == s->size)
|
||||
return 0;
|
||||
|
||||
@@ -57,17 +82,51 @@ _Bool Stack_Push(Stack *s, void *item)
|
||||
return 1;
|
||||
}
|
||||
|
||||
Stack *Stack_Copy(Stack *s, _Bool readonly)
|
||||
{
|
||||
if(Stack_IsReadOnlyCopy(s))
|
||||
{
|
||||
// Reference is readonly,
|
||||
// so the copy must be
|
||||
// readonly.
|
||||
readonly = 1;
|
||||
|
||||
// Remove readonly bit.
|
||||
s = unmark(s);
|
||||
}
|
||||
|
||||
s->refs += 1;
|
||||
|
||||
if(readonly)
|
||||
return (Stack*) ((uintptr_t) s | (intptr_t) 1);
|
||||
else
|
||||
return s;
|
||||
}
|
||||
|
||||
void Stack_Free(Stack *s)
|
||||
{
|
||||
// Remove readonly bit.
|
||||
s = unmark(s);
|
||||
|
||||
s->refs -= 1;
|
||||
assert(s->refs >= 0);
|
||||
|
||||
if(s->refs == 0)
|
||||
free(s);
|
||||
}
|
||||
|
||||
unsigned int Stack_Size(Stack *s)
|
||||
{
|
||||
// Remove readonly bit.
|
||||
s = unmark(s);
|
||||
|
||||
return s->used;
|
||||
}
|
||||
|
||||
unsigned int Stack_Capacity(Stack *s)
|
||||
{
|
||||
// Remove readonly bit.
|
||||
s = unmark(s);
|
||||
|
||||
return s->size;
|
||||
}
|
||||
@@ -7,5 +7,7 @@ _Bool Stack_Pop(Stack *s, unsigned int n);
|
||||
_Bool Stack_Push(Stack *s, void *item);
|
||||
void Stack_Free(Stack *s);
|
||||
unsigned int Stack_Size(Stack *s);
|
||||
Stack *Stack_Copy(Stack *s, _Bool readonly);
|
||||
unsigned int Stack_Capacity(Stack *s);
|
||||
_Bool Stack_IsReadOnlyCopy(Stack *s);
|
||||
#endif
|
||||
Reference in New Issue
Block a user