Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions libraries/dylan/library.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ define module Builtin-Stuff
initialize, instance?, invoke-debugger,
kill-thread,
limited, limited-integer-base-class, limited-integer-minimum,
limited-integer-maximum,
limited-integer-maximum, limited-instance?, limited-subtype?,
type-limitations,
list, load, load-library,
locked?, logand, logbit?, logior, lognot, logxor,
main, make, make-generic-function, make-ratio, merge-hash-ids,
Expand Down Expand Up @@ -190,7 +191,8 @@ define module Dylan
generic-function-mandatory-keywords, generic-function-methods,
head, head-setter,
initialize, instance?,
limited, list, logand, logbit?, logior, lognot, logxor,
limited, limited-instance?, limited-subtype?, type-limitations,
list, logand, logbit?, logior, lognot, logxor,
make, merge-hash-ids, function-specializers,
function-return-values,
negative, negative?,
Expand Down
37 changes: 33 additions & 4 deletions mindy/interpreter/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "driver.h"
#include "bool.h"
#include "gc.h"
#include "debug.h"
#ifdef MINDY_SLOW_FUNCTION_POINTERS
# include "interp.h"
#endif
Expand All @@ -54,7 +55,7 @@
#endif

static bool InInterpreter = false;
static jmp_buf Catcher;
static jmp_buf* Catcher;
static enum pause_reason PauseReason;

#define OPS_PER_TIME_SLICE 100
Expand Down Expand Up @@ -300,7 +301,7 @@ enum pause_reason do_stuff(void)
timer = OPS_PER_TIME_SLICE;
InInterpreter = true;
set_interrupt_handler(set_pause_interrupted);
_setjmp(Catcher);
_setjmp(*Catcher);
if (PauseReason == pause_NoReason)
while (timer-- > 0) {
#ifdef MINDY_SLOW_FUNCTION_POINTERS
Expand Down Expand Up @@ -343,7 +344,7 @@ enum pause_reason single_step(struct thread *thread)
InInterpreter = true;
PauseReason = pause_NoReason;
set_interrupt_handler(set_pause_interrupted);
if (_setjmp(Catcher) == 0) {
if (_setjmp(*Catcher) == 0) {
#ifdef MINDY_SLOW_FUNCTION_POINTERS
if (thread->advance)
thread->advance(thread);
Expand All @@ -363,7 +364,21 @@ enum pause_reason single_step(struct thread *thread)
void go_on(void)
{
assert(InInterpreter);
_longjmp(Catcher, 1);
if (Catcher)
{
_longjmp(*Catcher, 1);
} else {
Catcher = malloc(sizeof(jmp_buf));
InInterpreter = false;
clear_interrupt_handler();
if (TimeToGC)
collect_garbage(false);
while (1) {
enum pause_reason reason = do_stuff();
if (reason != pause_NothingToRun)
invoke_debugger(reason);
}
}
}

void mindy_pause(enum pause_reason reason)
Expand All @@ -374,6 +389,19 @@ void mindy_pause(enum pause_reason reason)
go_on();
}

void* preserve_stack()
{
jmp_buf *rv = Catcher;
Catcher = NULL;
return rv;
}

void release_stack(void *stack)
{
free(Catcher);
Catcher = (jmp_buf*)stack;
}


/* GC stuff. */

Expand Down Expand Up @@ -408,5 +436,6 @@ void init_driver()
init_waiters(&Readers);
init_waiters(&Writers);
NumFds = 0;
Catcher = malloc(sizeof(jmp_buf));
set_interrupt_handler(NULL);
}
3 changes: 3 additions & 0 deletions mindy/interpreter/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@ extern void unblock_signal_handler(int sig);
extern void set_interrupt_handler(void (*handler)(void));
extern void clear_interrupt_handler(void);
extern void unblock_interrupt_handler(void);

void release_stack(void *stack);
void* preserve_stack();
58 changes: 58 additions & 0 deletions mindy/interpreter/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
#include "coll.h"
#include "func.h"

#include "setjmp.h"

obj_t obj_FunctionClass = NULL;
static obj_t obj_RawFunctionClass = NULL;
obj_t obj_MethodClass = NULL;
Expand Down Expand Up @@ -422,6 +424,7 @@ static bool
obj_t arg_class = *cached_classes++;
obj_t specializer = HEAD(specializers);

// TODO: limited classes support here!
/* arg_class may be either a singleton, a limited_int, or a class.
This stuff has been worked out on a case by case basis. It could
certainly be made clearer, but this could potentially reduce
Expand Down Expand Up @@ -2203,3 +2206,58 @@ void init_func_functions(void)
true, obj_False, false, obj_ObjectClass,
constrain_c_function);
}

static void invoke_simple_method_return(struct thread *thread, obj_t *vals)
{
jmp_buf *buf;
size_t number_of_retvals = thread->sp - vals;

thread->sp = vals; // Remove return values from stack.
obj_t return_vector = make_vector(number_of_retvals, thread->sp);
thread->sp[0] = return_vector;

buf = (jmp_buf*)(thread->sp[-1]);

_longjmp(*buf, 1);
}

// This only works for functions without #rest.
obj_t invoke_simple_method(struct thread *thread, obj_t method, obj_t arg_list)
{
jmp_buf buf;
if (! instancep(arg_list, obj_ListClass))
lose("Argument list is not a list.");
if (thread == NULL)
thread = thread_current();

push_linkage(thread, NULL);
*thread->sp++ = (obj_t)&buf;

int argc = 0;
*thread->sp++ = method;
for (; arg_list != obj_Nil; arg_list = TAIL(arg_list))
{
*thread->sp++ = HEAD(arg_list);
argc++;
}
set_c_continuation(thread, invoke_simple_method_return);
void *stack = preserve_stack();

if (_setjmp(buf) == 0)
{
invoke(thread, argc);
}
else
{
// Return from longjmp.
release_stack(stack);
obj_t retvals = thread->sp[0];
thread->sp--; // Remove jmp_buf* from stack
pop_linkage(thread);
return retvals;
}
int *die = NULL;
*die = 10;
lose("Should never reach this point.");
return obj_Nil;
}
2 changes: 2 additions & 0 deletions mindy/interpreter/func.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,5 @@ extern obj_t function_keywords(obj_t func);
extern bool function_all_keywords_p(obj_t func);

extern obj_t function_specializers(obj_t method);

extern obj_t invoke_simple_method(struct thread *thread, obj_t method, obj_t arg_list);
3 changes: 2 additions & 1 deletion mindy/interpreter/mindy.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ enum type_Id {
id_LimFixnum,
id_LimBignum,
id_Union,
id_NoneOf
id_NoneOf,
id_LimClass
};

extern MINDY_NORETURN void lose(const char *fmt, ...) MINDY_FORMATLIKE(1, 2);
Expand Down
Loading