diff options
Diffstat (limited to 'pit')
| -rw-r--r-- | pit/include/lcq/pit/runtime.h | 2 | ||||
| -rw-r--r-- | pit/src/main.c | 1 | ||||
| -rw-r--r-- | pit/src/runtime.c | 5 | ||||
| -rw-r--r-- | pit/src/runtime/eval.c | 2 |
4 files changed, 10 insertions, 0 deletions
diff --git a/pit/include/lcq/pit/runtime.h b/pit/include/lcq/pit/runtime.h index feeb267..96d0351 100644 --- a/pit/include/lcq/pit/runtime.h +++ b/pit/include/lcq/pit/runtime.h @@ -98,6 +98,7 @@ typedef struct pit_runtime { pit_vec(pit_traversal_entry) *traversal; /* intermediate stack used during tree traversal */ pit_vec(pit_callstack_entry) *callstack; /* stack of enclosing function calls */ /* bookkeeping */ + i64 fuel; /* fuel total - ignored if negative. decrements on each instruction executed. */ /* "frozen" values offsets: values before these offsets are immutable, and we can reset here later */ i64 frozen_values, frozen_symtab; pit_value error; /* error value - if this is non-nil, an error has occured! only tracks the first error */ @@ -108,6 +109,7 @@ typedef struct pit_runtime { } pit_runtime; pit_runtime *pit_runtime_new(u8 *buf, i64 len); +void pit_runtime_set_fuel(pit_runtime *rt, i64 fuel); void pit_runtime_freeze(pit_runtime *rt); /* freeze the runtime at the current point - everything currently defined becomes immutable */ void pit_runtime_reset(pit_runtime *rt); /* restore the runtime to the frozen point, resetting everything that has happened since */ bool pit_runtime_print_error(pit_runtime *rt); /* return true if an error has occured, and print to stderr */ diff --git a/pit/src/main.c b/pit/src/main.c index 157ad87..2b741c1 100644 --- a/pit/src/main.c +++ b/pit/src/main.c @@ -11,6 +11,7 @@ int main(int argc, char **argv) { i64 sz = 256 * 1024 * 1024; u8 *buf = malloc((size_t) sz); pit_runtime *rt = pit_runtime_new(buf, sz); + rt->fuel = 10000000; pit_install_library_essential(rt); pit_install_library_io(rt); pit_install_library_plist(rt); diff --git a/pit/src/runtime.c b/pit/src/runtime.c index d4a0a62..ab65d71 100644 --- a/pit/src/runtime.c +++ b/pit/src/runtime.c @@ -45,6 +45,7 @@ pit_runtime *pit_runtime_new(u8 *buf, i64 len) { ret->traversal = pit_vec_new(pit_traversal_entry)(pit_arena_alloc_back(a, stack_size), stack_size); ret->callstack = pit_vec_new(pit_callstack_entry)(pit_arena_alloc_back(a, stack_size), stack_size); ret->saved_bindings = pit_vec_new(pit_value)(pit_arena_alloc_back(a, stack_size), stack_size); + ret->fuel = -1; ret->frozen_values = 0; ret->frozen_symtab = 0; ret->error = PIT_NIL; @@ -60,6 +61,10 @@ pit_runtime *pit_runtime_new(u8 *buf, i64 len) { return ret; } +void pit_runtime_set_fuel(pit_runtime *rt, i64 fuel) { + rt->fuel = fuel; +} + void pit_runtime_freeze(pit_runtime *rt) { rt->frozen_values = rt->heap->next; rt->frozen_symtab = rt->symtab->next; diff --git a/pit/src/runtime/eval.c b/pit/src/runtime/eval.c index eba9715..a2ed166 100644 --- a/pit/src/runtime/eval.c +++ b/pit/src/runtime/eval.c @@ -155,6 +155,8 @@ bool pit_vm_run_one(pit_runtime *rt) { if (rt->callstack->next < 1 || rt->error != PIT_NIL) return false; pit_callstack_entry *ent = pit_vec_get(pit_callstack_entry)(rt->callstack, rt->callstack->next - 1); if (ent == NULL) { pit_error(rt, "malformed call stack"); return false; } + if (rt->fuel == 0) { pit_error(rt, "out of fuel"); return false; } + rt->fuel -= 1; pit_value ins = pit_value_cons_car(rt, ent->code); if (ins == PIT_NIL) { pit_error(rt, "malformed vm instruction: %v %v", ins); return false; } ent->code = pit_value_cons_cdr(rt, ent->code); |
