mirror of
https://github.com/carp-lang/Carp.git
synced 2024-10-11 20:49:05 +03:00
can detect stack overflow in bytecode
This commit is contained in:
parent
14c64cf63b
commit
9e094d3864
@ -34,4 +34,8 @@
|
||||
|
||||
|
||||
(eb '(def fi (macro [a b c] (list 'if a c b))))
|
||||
(eb '(fi true 10 20))
|
||||
;; (eb '(fi true 10 20))
|
||||
|
||||
(eb '(def recur (fn [] (do (println (str 123)) (recur)))))
|
||||
|
||||
(eb '(recur))
|
||||
|
@ -309,7 +309,7 @@ Obj *bytecode_eval_internal(Process *process, Obj *bytecodeObj, int steps) {
|
||||
for(int step = 0; step < steps; step++) {
|
||||
|
||||
if(eval_error) {
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Obj **literals_array = process->frames[process->frame].bytecodeObj->bytecode_literals->array;
|
||||
@ -357,7 +357,7 @@ Obj *bytecode_eval_internal(Process *process, Obj *bytecodeObj, int steps) {
|
||||
} else {
|
||||
eval_error = obj_new_string("reset! can't find variable to reset: ");
|
||||
obj_string_mut_append(eval_error, obj_to_string(process, literal)->s);
|
||||
return nil;
|
||||
return NULL;
|
||||
}
|
||||
process->frames[process->frame].p += 2;
|
||||
break;
|
||||
@ -392,7 +392,7 @@ Obj *bytecode_eval_internal(Process *process, Obj *bytecodeObj, int steps) {
|
||||
//printf("Looking up literal "); obj_print_cout(literal); printf("\n");
|
||||
lookup = env_lookup(process, process->frames[process->frame].env, literal);
|
||||
if(!lookup) {
|
||||
set_error_return_nil("Failed to lookup ", literal);
|
||||
set_error_return_null("Failed to lookup ", literal);
|
||||
}
|
||||
stack_push(process, lookup);
|
||||
process->frames[process->frame].p += 2;
|
||||
@ -453,28 +453,30 @@ Obj *bytecode_eval_internal(Process *process, Obj *bytecodeObj, int steps) {
|
||||
}
|
||||
}
|
||||
else if(function->tag == 'L') {
|
||||
if(process->frame >= BYTECODE_FRAME_SIZE - 1) {
|
||||
set_error_return_null("Bytecode stack overflow. ", nil);
|
||||
}
|
||||
|
||||
Obj *calling_env = obj_new_environment(function->env);
|
||||
//printf("arg_count = %d\n", arg_count);
|
||||
env_extend_with_args(process, calling_env, function, arg_count, args, true);
|
||||
process->frame++;
|
||||
process->frames[process->frame].p = 0;
|
||||
if(function->body->tag != 'X') {
|
||||
set_error_return_nil("The body of the lambda must be bytecode, ", function);
|
||||
set_error_return_null("The body of the lambda must be bytecode, ", function);
|
||||
}
|
||||
process->frames[process->frame].bytecodeObj = function->body;
|
||||
process->frames[process->frame].env = calling_env;
|
||||
//printf("Pushing new stack frame with bytecode '%s'\n", process->frames[process->frame].bytecode); // and env %s\n", process->frames[process->frame].bytecode, obj_to_string(process, calling_env)->s);
|
||||
}
|
||||
else {
|
||||
printf("Can't call Obj of type '%c'\n", function->tag);
|
||||
obj_print_cout(function);
|
||||
return nil;
|
||||
set_error_return_null("Can't call \n", function);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
process->frame--;
|
||||
if(process->frame < 0) {
|
||||
goto done;
|
||||
return stack_pop(process);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -483,8 +485,7 @@ Obj *bytecode_eval_internal(Process *process, Obj *bytecodeObj, int steps) {
|
||||
}
|
||||
}
|
||||
|
||||
done:;
|
||||
return stack_pop(process);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Obj *bytecode_eval(Process *process, Obj *bytecodeObj, bool restart) {
|
||||
@ -505,8 +506,13 @@ Obj *bytecode_eval(Process *process, Obj *bytecodeObj, bool restart) {
|
||||
|
||||
Obj *final_result = NULL;
|
||||
while(!final_result) {
|
||||
final_result = bytecode_eval_internal(process, bytecodeObj, 1000);
|
||||
final_result = bytecode_eval_internal(process, bytecodeObj, 20);
|
||||
if(eval_error) {
|
||||
final_result = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//printf("Final result = %s\n", obj_to_string(process, final_result)->s);
|
||||
|
||||
shadow_stack_pop(process);
|
||||
return final_result;
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "constants.h"
|
||||
#include "../shared/types.h"
|
||||
|
||||
#define BYTECODE_FRAME_SIZE 256
|
||||
|
||||
typedef void (*VoidFn)(void);
|
||||
|
||||
/* Type tags
|
||||
@ -141,7 +143,7 @@ typedef struct {
|
||||
struct Obj *global_env;
|
||||
|
||||
Obj *bytecodeObj;
|
||||
BytecodeFrame frames[256];
|
||||
BytecodeFrame frames[BYTECODE_FRAME_SIZE];
|
||||
int frame;
|
||||
} Process;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user