mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 14:19:18 +02:00
fixing some gc var preservation bugs
This commit is contained in:
parent
bddbaedfa7
commit
d6b850b5aa
4 changed files with 84 additions and 36 deletions
69
eval.c
69
eval.c
|
@ -264,7 +264,7 @@ static sexp sexp_make_context(sexp ctx, sexp stack, sexp env) {
|
||||||
sexp_bytecode_name(sexp_context_bc(res)) = SEXP_FALSE;
|
sexp_bytecode_name(sexp_context_bc(res)) = SEXP_FALSE;
|
||||||
sexp_bytecode_length(sexp_context_bc(res)) = INIT_BCODE_SIZE;
|
sexp_bytecode_length(sexp_context_bc(res)) = INIT_BCODE_SIZE;
|
||||||
sexp_bytecode_literals(sexp_context_bc(res)) = SEXP_NULL;
|
sexp_bytecode_literals(sexp_context_bc(res)) = SEXP_NULL;
|
||||||
sexp_context_parent(res) = SEXP_FALSE;
|
sexp_context_parent(res) = ctx;
|
||||||
sexp_context_lambda(res) = SEXP_FALSE;
|
sexp_context_lambda(res) = SEXP_FALSE;
|
||||||
sexp_context_fv(res) = SEXP_NULL;
|
sexp_context_fv(res) = SEXP_NULL;
|
||||||
sexp_context_saves(res) = 0;
|
sexp_context_saves(res) = 0;
|
||||||
|
@ -343,11 +343,12 @@ static sexp sexp_identifier_eq(sexp ctx, sexp e1, sexp id1, sexp e2, sexp id2) {
|
||||||
static sexp sexp_compile_error(sexp ctx, char *message, sexp obj) {
|
static sexp sexp_compile_error(sexp ctx, char *message, sexp obj) {
|
||||||
sexp exn;
|
sexp exn;
|
||||||
sexp_gc_var(ctx, irritants, s_irr);
|
sexp_gc_var(ctx, irritants, s_irr);
|
||||||
|
sexp_gc_var(ctx, msg, s_msg);
|
||||||
sexp_gc_preserve(ctx, irritants, s_irr);
|
sexp_gc_preserve(ctx, irritants, s_irr);
|
||||||
|
sexp_gc_preserve(ctx, msg, s_msg);
|
||||||
irritants = sexp_list1(ctx, obj);
|
irritants = sexp_list1(ctx, obj);
|
||||||
exn = sexp_make_exception(ctx, the_compile_error_symbol,
|
msg = sexp_c_string(ctx, message, -1);
|
||||||
sexp_c_string(ctx, message, -1),
|
exn = sexp_make_exception(ctx, the_compile_error_symbol, msg, irritants,
|
||||||
irritants,
|
|
||||||
SEXP_FALSE, SEXP_FALSE, SEXP_FALSE);
|
SEXP_FALSE, SEXP_FALSE, SEXP_FALSE);
|
||||||
sexp_gc_release(ctx, irritants, s_irr);
|
sexp_gc_release(ctx, irritants, s_irr);
|
||||||
return exn;
|
return exn;
|
||||||
|
@ -919,8 +920,7 @@ static void generate_general_app (sexp ctx, sexp app) {
|
||||||
|
|
||||||
/* push the arguments onto the stack */
|
/* push the arguments onto the stack */
|
||||||
sexp_context_tailp(ctx) = 0;
|
sexp_context_tailp(ctx) = 0;
|
||||||
for (ls = sexp_reverse(ctx, sexp_cdr(app)); sexp_pairp(ls);
|
for (ls=sexp_reverse(ctx, sexp_cdr(app)); sexp_pairp(ls); ls=sexp_cdr(ls))
|
||||||
ls = sexp_cdr(ls))
|
|
||||||
generate(ctx, sexp_car(ls));
|
generate(ctx, sexp_car(ls));
|
||||||
|
|
||||||
/* push the operator onto the stack */
|
/* push the operator onto the stack */
|
||||||
|
@ -942,10 +942,12 @@ static void generate_app (sexp ctx, sexp app) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_lambda (sexp ctx, sexp lambda) {
|
static void generate_lambda (sexp ctx, sexp lambda) {
|
||||||
sexp ctx2, fv, ls, flags, bc, len, ref, prev_lambda, prev_fv;
|
sexp ctx2, fv, ls, flags, len, ref, prev_lambda, prev_fv;
|
||||||
sexp_uint_t k;
|
sexp_uint_t k;
|
||||||
sexp_gc_var(ctx, tmp, s_tmp);
|
sexp_gc_var(ctx, tmp, s_tmp);
|
||||||
|
sexp_gc_var(ctx, bc, s_bc);
|
||||||
sexp_gc_preserve(ctx, tmp, s_tmp);
|
sexp_gc_preserve(ctx, tmp, s_tmp);
|
||||||
|
sexp_gc_preserve(ctx, bc, s_bc);
|
||||||
prev_lambda = sexp_context_lambda(ctx);
|
prev_lambda = sexp_context_lambda(ctx);
|
||||||
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
|
prev_fv = sexp_lambdap(prev_lambda) ? sexp_lambda_fv(prev_lambda) : SEXP_NULL;
|
||||||
fv = sexp_lambda_fv(lambda);
|
fv = sexp_lambda_fv(lambda);
|
||||||
|
@ -969,9 +971,9 @@ static void generate_lambda (sexp ctx, sexp lambda) {
|
||||||
}
|
}
|
||||||
sexp_context_tailp(ctx2) = 1;
|
sexp_context_tailp(ctx2) = 1;
|
||||||
generate(ctx2, sexp_lambda_body(lambda));
|
generate(ctx2, sexp_lambda_body(lambda));
|
||||||
flags = sexp_make_integer((sexp_listp(ctx, sexp_lambda_params(lambda))
|
flags = sexp_make_integer((sexp_listp(ctx2, sexp_lambda_params(lambda))
|
||||||
== SEXP_FALSE) ? 1 : 0);
|
== SEXP_FALSE) ? 1 : 0);
|
||||||
len = sexp_length(ctx, sexp_lambda_params(lambda));
|
len = sexp_length(ctx2, sexp_lambda_params(lambda));
|
||||||
bc = finalize_bytecode(ctx2);
|
bc = finalize_bytecode(ctx2);
|
||||||
sexp_bytecode_name(bc) = sexp_lambda_name(lambda);
|
sexp_bytecode_name(bc) = sexp_lambda_name(lambda);
|
||||||
if (sexp_nullp(fv)) {
|
if (sexp_nullp(fv)) {
|
||||||
|
@ -1034,9 +1036,9 @@ static sexp insert_free_var (sexp ctx, sexp x, sexp fv) {
|
||||||
|
|
||||||
static sexp union_free_vars (sexp ctx, sexp fv1, sexp fv2) {
|
static sexp union_free_vars (sexp ctx, sexp fv1, sexp fv2) {
|
||||||
sexp_gc_var(ctx, res, s_res);
|
sexp_gc_var(ctx, res, s_res);
|
||||||
sexp_gc_preserve(ctx, res, s_res);
|
|
||||||
if (sexp_nullp(fv2))
|
if (sexp_nullp(fv2))
|
||||||
return fv1;
|
return fv1;
|
||||||
|
sexp_gc_preserve(ctx, res, s_res);
|
||||||
for (res=fv2; sexp_pairp(fv1); fv1=sexp_cdr(fv1))
|
for (res=fv2; sexp_pairp(fv1); fv1=sexp_cdr(fv1))
|
||||||
res = insert_free_var(ctx, sexp_car(fv1), res);
|
res = insert_free_var(ctx, sexp_car(fv1), res);
|
||||||
sexp_gc_release(ctx, res, s_res);
|
sexp_gc_release(ctx, res, s_res);
|
||||||
|
@ -1107,7 +1109,7 @@ static sexp make_opcode_procedure (sexp ctx, sexp op, sexp_uint_t i) {
|
||||||
sexp_gc_var(ctx, ref, s_ref);
|
sexp_gc_var(ctx, ref, s_ref);
|
||||||
sexp_gc_var(ctx, refs, s_refs);
|
sexp_gc_var(ctx, refs, s_refs);
|
||||||
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
|
if (i == sexp_opcode_num_args(op) && sexp_opcode_proc(op))
|
||||||
return sexp_opcode_proc(op);
|
return sexp_opcode_proc(op); /* return before preserving */
|
||||||
sexp_gc_preserve(ctx, params, s_params);
|
sexp_gc_preserve(ctx, params, s_params);
|
||||||
sexp_gc_preserve(ctx, ref, s_ref);
|
sexp_gc_preserve(ctx, ref, s_ref);
|
||||||
sexp_gc_preserve(ctx, refs, s_refs);
|
sexp_gc_preserve(ctx, refs, s_refs);
|
||||||
|
@ -1176,7 +1178,7 @@ static sexp_uint_t sexp_restore_stack(sexp saved, sexp *current) {
|
||||||
goto call_error_handler;} \
|
goto call_error_handler;} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
sexp vm (sexp proc, sexp ctx) {
|
sexp vm (sexp ctx, sexp proc) {
|
||||||
sexp bc = sexp_procedure_code(proc), cp = sexp_procedure_vars(proc);
|
sexp bc = sexp_procedure_code(proc), cp = sexp_procedure_vars(proc);
|
||||||
sexp env = sexp_context_env(ctx),
|
sexp env = sexp_context_env(ctx),
|
||||||
*stack = sexp_stack_data(sexp_context_stack(ctx));
|
*stack = sexp_stack_data(sexp_context_stack(ctx));
|
||||||
|
@ -1199,6 +1201,7 @@ sexp vm (sexp proc, sexp ctx) {
|
||||||
fprintf(stderr, "%s\n", (*ip<=71)?reverse_opcode_names[*ip]:"UNKNOWN");
|
fprintf(stderr, "%s\n", (*ip<=71)?reverse_opcode_names[*ip]:"UNKNOWN");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
sexp_context_top(ctx) = top; /* debugging */
|
||||||
switch (*ip++) {
|
switch (*ip++) {
|
||||||
case OP_NOOP:
|
case OP_NOOP:
|
||||||
break;
|
break;
|
||||||
|
@ -1324,40 +1327,47 @@ sexp vm (sexp proc, sexp ctx) {
|
||||||
fp = top-4;
|
fp = top-4;
|
||||||
break;
|
break;
|
||||||
case OP_FCALL0:
|
case OP_FCALL0:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_PUSH(((sexp_proc1)_UWORD0)(ctx));
|
_PUSH(((sexp_proc1)_UWORD0)(ctx));
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL1:
|
case OP_FCALL1:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG1 = ((sexp_proc2)_UWORD0)(ctx, _ARG1);
|
_ARG1 = ((sexp_proc2)_UWORD0)(ctx, _ARG1);
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL2:
|
case OP_FCALL2:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG2 = ((sexp_proc3)_UWORD0)(ctx, _ARG1, _ARG2);
|
_ARG2 = ((sexp_proc3)_UWORD0)(ctx, _ARG1, _ARG2);
|
||||||
top--;
|
top--;
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL3:
|
case OP_FCALL3:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG3 =((sexp_proc4)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3);
|
_ARG3 =((sexp_proc4)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3);
|
||||||
top -= 2;
|
top -= 2;
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL4:
|
case OP_FCALL4:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG4 =((sexp_proc5)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4);
|
_ARG4 =((sexp_proc5)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4);
|
||||||
top -= 3;
|
top -= 3;
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL5:
|
case OP_FCALL5:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG5 =((sexp_proc6)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5);
|
_ARG5 =((sexp_proc6)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5);
|
||||||
top -= 4;
|
top -= 4;
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
case OP_FCALL6:
|
case OP_FCALL6:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG6 =((sexp_proc7)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6);
|
_ARG6 =((sexp_proc7)_UWORD0)(ctx, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6);
|
||||||
top -= 5;
|
top -= 5;
|
||||||
ip += sizeof(sexp);
|
ip += sizeof(sexp);
|
||||||
|
@ -1440,10 +1450,12 @@ sexp vm (sexp proc, sexp ctx) {
|
||||||
_ARG1 = sexp_make_integer(sexp_string_length(_ARG1));
|
_ARG1 = sexp_make_integer(sexp_string_length(_ARG1));
|
||||||
break;
|
break;
|
||||||
case OP_MAKE_PROCEDURE:
|
case OP_MAKE_PROCEDURE:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG4 = sexp_make_procedure(ctx, _ARG1, _ARG2, _ARG3, _ARG4);
|
_ARG4 = sexp_make_procedure(ctx, _ARG1, _ARG2, _ARG3, _ARG4);
|
||||||
top-=3;
|
top-=3;
|
||||||
break;
|
break;
|
||||||
case OP_MAKE_VECTOR:
|
case OP_MAKE_VECTOR:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG2 = sexp_make_vector(ctx, _ARG1, _ARG2);
|
_ARG2 = sexp_make_vector(ctx, _ARG1, _ARG2);
|
||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
|
@ -1702,6 +1714,7 @@ sexp vm (sexp proc, sexp ctx) {
|
||||||
_ARG1 = SEXP_VOID;
|
_ARG1 = SEXP_VOID;
|
||||||
break;
|
break;
|
||||||
case OP_READ:
|
case OP_READ:
|
||||||
|
sexp_context_top(ctx) = top;
|
||||||
_ARG1 = sexp_read(ctx, _ARG1);
|
_ARG1 = sexp_read(ctx, _ARG1);
|
||||||
sexp_check_exception();
|
sexp_check_exception();
|
||||||
break;
|
break;
|
||||||
|
@ -1791,12 +1804,12 @@ sexp sexp_load (sexp ctx, sexp source, sexp env) {
|
||||||
sexp_gc_preserve(ctx, ctx2, s_ctx2);
|
sexp_gc_preserve(ctx, ctx2, s_ctx2);
|
||||||
sexp_gc_preserve(ctx, x, s_x);
|
sexp_gc_preserve(ctx, x, s_x);
|
||||||
sexp_gc_preserve(ctx, in, s_in);
|
sexp_gc_preserve(ctx, in, s_in);
|
||||||
|
in = sexp_open_input_file(ctx, source);
|
||||||
|
out = env_global_ref(env, the_cur_err_symbol, SEXP_FALSE);
|
||||||
ctx2 = sexp_make_context(ctx, NULL, env);
|
ctx2 = sexp_make_context(ctx, NULL, env);
|
||||||
sexp_context_parent(ctx2) = ctx;
|
sexp_context_parent(ctx2) = ctx;
|
||||||
out = env_global_ref(env, the_cur_err_symbol, SEXP_FALSE);
|
|
||||||
tmp = sexp_env_bindings(env);
|
tmp = sexp_env_bindings(env);
|
||||||
sexp_context_tailp(ctx2) = 0;
|
sexp_context_tailp(ctx2) = 0;
|
||||||
in = sexp_open_input_file(ctx, source);
|
|
||||||
if (sexp_exceptionp(in)) {
|
if (sexp_exceptionp(in)) {
|
||||||
sexp_print_exception(ctx, in, out);
|
sexp_print_exception(ctx, in, out);
|
||||||
res = in;
|
res = in;
|
||||||
|
@ -1995,37 +2008,47 @@ sexp apply (sexp ctx, sexp proc, sexp args) {
|
||||||
stack[top++] = sexp_make_integer(sexp_bytecode_data(final_resumer));
|
stack[top++] = sexp_make_integer(sexp_bytecode_data(final_resumer));
|
||||||
stack[top++] = sexp_make_vector(ctx, 0, SEXP_VOID);
|
stack[top++] = sexp_make_vector(ctx, 0, SEXP_VOID);
|
||||||
stack[top++] = sexp_make_integer(0);
|
stack[top++] = sexp_make_integer(0);
|
||||||
return vm(proc, ctx);
|
return vm(ctx, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp compile (sexp ctx, sexp x) {
|
sexp compile (sexp ctx, sexp x) {
|
||||||
sexp res;
|
|
||||||
sexp_gc_var(ctx, ast, s_ast);
|
sexp_gc_var(ctx, ast, s_ast);
|
||||||
sexp_gc_var(ctx, ctx2, s_ctx2);
|
sexp_gc_var(ctx, ctx2, s_ctx2);
|
||||||
|
sexp_gc_var(ctx, vec, s_vec);
|
||||||
|
sexp_gc_var(ctx, res, s_res);
|
||||||
sexp_gc_preserve(ctx, ast, s_ast);
|
sexp_gc_preserve(ctx, ast, s_ast);
|
||||||
sexp_gc_preserve(ctx, ctx2, s_ctx2);
|
sexp_gc_preserve(ctx, ctx2, s_ctx2);
|
||||||
|
sexp_gc_preserve(ctx, vec, s_vec);
|
||||||
|
sexp_gc_preserve(ctx, res, s_res);
|
||||||
analyze_bind(ast, x, ctx);
|
analyze_bind(ast, x, ctx);
|
||||||
free_vars(ctx, ast, SEXP_NULL); /* should return SEXP_NULL */
|
free_vars(ctx, ast, SEXP_NULL); /* should return SEXP_NULL */
|
||||||
ctx2 = sexp_make_context(ctx, sexp_context_stack(ctx), sexp_context_env(ctx));
|
ctx2 = sexp_make_context(ctx, sexp_context_stack(ctx), sexp_context_env(ctx));
|
||||||
|
sexp_context_parent(ctx2) = ctx;
|
||||||
generate(ctx2, ast);
|
generate(ctx2, ast);
|
||||||
res = sexp_make_procedure(ctx, sexp_make_integer(0),
|
res = finalize_bytecode(ctx2);
|
||||||
sexp_make_integer(0),
|
vec = sexp_make_vector(ctx, 0, SEXP_VOID);
|
||||||
finalize_bytecode(ctx2),
|
res = sexp_make_procedure(ctx, sexp_make_integer(0), sexp_make_integer(0),
|
||||||
sexp_make_vector(ctx, 0, SEXP_VOID));
|
res, vec);
|
||||||
sexp_gc_release(ctx, ast, s_ast);
|
sexp_gc_release(ctx, ast, s_ast);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp eval_in_context (sexp ctx, sexp obj) {
|
sexp eval_in_context (sexp ctx, sexp obj) {
|
||||||
sexp thunk = compile(ctx, obj);
|
sexp res;
|
||||||
|
sexp_gc_var(ctx, thunk, s_thunk);
|
||||||
|
sexp_gc_preserve(ctx, thunk, s_thunk);
|
||||||
|
thunk = compile(ctx, obj);
|
||||||
if (sexp_exceptionp(thunk)) {
|
if (sexp_exceptionp(thunk)) {
|
||||||
sexp_print_exception(ctx, thunk,
|
sexp_print_exception(ctx, thunk,
|
||||||
env_global_ref(sexp_context_env(ctx),
|
env_global_ref(sexp_context_env(ctx),
|
||||||
the_cur_err_symbol,
|
the_cur_err_symbol,
|
||||||
SEXP_FALSE));
|
SEXP_FALSE));
|
||||||
return thunk;
|
res = thunk;
|
||||||
|
} else {
|
||||||
|
res = apply(ctx, thunk, SEXP_NULL);
|
||||||
}
|
}
|
||||||
return apply(ctx, thunk, SEXP_NULL);
|
sexp_gc_release(ctx, thunk, s_thunk);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp eval (sexp obj, sexp env) {
|
sexp eval (sexp obj, sexp env) {
|
||||||
|
|
32
gc.c
32
gc.c
|
@ -638,17 +638,42 @@ void validate_gc_vars (sexp ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int validate_freed_pointer (sexp x) {
|
int validate_freed_pointer (sexp ctx, sexp x) {
|
||||||
int freep = 1;
|
int freep = 1;
|
||||||
sexp *p;
|
sexp *p;
|
||||||
|
struct sexp_gc_var_t *saves, *prev=NULL;
|
||||||
|
char *v1, *v2;
|
||||||
|
|
||||||
for (p=&x; p<stack_base; p++) {
|
for (p=&x; p<stack_base; p++) {
|
||||||
if (*p == x) {
|
if (*p == x) {
|
||||||
|
v1 = v2 = NULL;
|
||||||
|
for (saves=sexp_context_saves(ctx); saves; saves=saves->next) {
|
||||||
|
if (saves->var && prev && prev->var
|
||||||
|
&& (((saves->var <= p) && (prev->var >= p))
|
||||||
|
|| ((saves->var >= p) && (prev->var <= p)))) {
|
||||||
|
v1 = saves->name;
|
||||||
|
v2 = prev->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = saves;
|
||||||
|
}
|
||||||
|
if (v1 && v2)
|
||||||
|
fprintf(stderr, "reference to freed var %p at %p between %s and %s: ",
|
||||||
|
x, p, v1, v2);
|
||||||
|
else if (sexp_context_saves(ctx) && (p <= sexp_context_saves(ctx)->var))
|
||||||
|
fprintf(stderr, "reference to freed var %p at %p after %s: ",
|
||||||
|
x, p, sexp_context_saves(ctx)->name);
|
||||||
|
else if (prev && (p >= prev->var))
|
||||||
|
fprintf(stderr, "reference to freed var %p at %p before %s: ",
|
||||||
|
x, p, prev->name);
|
||||||
|
else
|
||||||
fprintf(stderr, "reference to freed var %p at %p: ", x, p);
|
fprintf(stderr, "reference to freed var %p at %p: ", x, p);
|
||||||
simple_write(x, 1, stderr);
|
simple_write(x, 1, stderr);
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
freep = 0;
|
freep = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return freep;
|
return freep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,7 +694,7 @@ sexp sexp_sweep (sexp ctx) {
|
||||||
fprintf(stderr, "sweep: p: %p <= q: %p\n", p, q);
|
fprintf(stderr, "sweep: p: %p <= q: %p\n", p, q);
|
||||||
}
|
}
|
||||||
size = sexp_align(sexp_allocated_bytes(p), 4);
|
size = sexp_align(sexp_allocated_bytes(p), 4);
|
||||||
if ((! sexp_gc_mark(p)) && validate_freed_pointer(p)) {
|
if ((! sexp_gc_mark(p))/* && validate_freed_pointer(ctx, p) */) {
|
||||||
/* fprintf(stderr, "\x1B[31mfreeing %lu bytes @ %p (%x) ", size, p, sexp_pointer_tag(p)); */
|
/* fprintf(stderr, "\x1B[31mfreeing %lu bytes @ %p (%x) ", size, p, sexp_pointer_tag(p)); */
|
||||||
/* simple_write(p, 1, stderr); */
|
/* simple_write(p, 1, stderr); */
|
||||||
/* fprintf(stderr, "\x1B[0m\n"); */
|
/* fprintf(stderr, "\x1B[0m\n"); */
|
||||||
|
@ -870,6 +895,7 @@ void sexp_gc_init () {
|
||||||
sexp_car(next) = (sexp) (size - sexp_align(sexp_sizeof(pair), 4));
|
sexp_car(next) = (sexp) (size - sexp_align(sexp_sizeof(pair), 4));
|
||||||
sexp_cdr(next) = SEXP_NULL;
|
sexp_cdr(next) = SEXP_NULL;
|
||||||
stack_base = &next + 32;
|
stack_base = &next + 32;
|
||||||
fprintf(stderr, "heap: %p - %p, next: %p\n", sexp_heap, sexp_heap_end, next);
|
fprintf(stderr, "heap: %p - %p, next: %p, stack_base: %p\n",
|
||||||
|
sexp_heap, sexp_heap_end, next, stack_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
main.c
8
main.c
|
@ -2,7 +2,9 @@
|
||||||
#include "eval.c"
|
#include "eval.c"
|
||||||
|
|
||||||
void repl (sexp ctx) {
|
void repl (sexp ctx) {
|
||||||
sexp obj, tmp, res, env, in, out, err;
|
sexp tmp, res, env, in, out, err;
|
||||||
|
sexp_gc_var(ctx, obj, s_obj);
|
||||||
|
sexp_gc_preserve(ctx, obj, s_obj);
|
||||||
env = sexp_context_env(ctx);
|
env = sexp_context_env(ctx);
|
||||||
sexp_context_tracep(ctx) = 1;
|
sexp_context_tracep(ctx) = 1;
|
||||||
in = env_global_ref(env, the_cur_in_symbol, SEXP_FALSE);
|
in = env_global_ref(env, the_cur_in_symbol, SEXP_FALSE);
|
||||||
|
@ -29,6 +31,7 @@ void repl (sexp ctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sexp_gc_release(ctx, obj, s_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_main (int argc, char **argv) {
|
void run_main (int argc, char **argv) {
|
||||||
|
@ -36,12 +39,11 @@ void run_main (int argc, char **argv) {
|
||||||
sexp_uint_t i, quit=0, init_loaded=0;
|
sexp_uint_t i, quit=0, init_loaded=0;
|
||||||
|
|
||||||
ctx = sexp_make_context(NULL, NULL, NULL);
|
ctx = sexp_make_context(NULL, NULL, NULL);
|
||||||
env = sexp_make_standard_env(ctx, sexp_make_integer(5));
|
env = sexp_context_env(ctx);
|
||||||
env_define(ctx, env, the_interaction_env_symbol, env);
|
env_define(ctx, env, the_interaction_env_symbol, env);
|
||||||
out = env_global_ref(env, the_cur_out_symbol, SEXP_FALSE);
|
out = env_global_ref(env, the_cur_out_symbol, SEXP_FALSE);
|
||||||
err_cell = env_cell(env, the_cur_err_symbol);
|
err_cell = env_cell(env, the_cur_err_symbol);
|
||||||
perr_cell = env_cell(env, sexp_intern(ctx, "print-exception"));
|
perr_cell = env_cell(env, sexp_intern(ctx, "print-exception"));
|
||||||
sexp_context_env(ctx) = env;
|
|
||||||
sexp_context_tailp(ctx) = 0;
|
sexp_context_tailp(ctx) = 0;
|
||||||
if (err_cell && perr_cell && sexp_opcodep(sexp_cdr(perr_cell))) {
|
if (err_cell && perr_cell && sexp_opcodep(sexp_cdr(perr_cell))) {
|
||||||
emit(ctx, OP_GLOBAL_KNOWN_REF);
|
emit(ctx, OP_GLOBAL_KNOWN_REF);
|
||||||
|
|
9
sexp.c
9
sexp.c
|
@ -49,10 +49,7 @@ sexp sexp_symbol_table[SEXP_SYMBOL_TABLE_SIZE];
|
||||||
|
|
||||||
sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag) {
|
sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag) {
|
||||||
sexp res = (sexp) sexp_alloc(ctx, size);
|
sexp res = (sexp) sexp_alloc(ctx, size);
|
||||||
if (! res)
|
if (res) sexp_pointer_tag(res) = tag;
|
||||||
errx(EX_OSERR, "out of memory: couldn't allocate %ld bytes for %ld",
|
|
||||||
size ,tag);
|
|
||||||
sexp_pointer_tag(res) = tag;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +479,8 @@ sexp sexp_make_vector(sexp ctx, sexp len, sexp dflt) {
|
||||||
sexp v, *x;
|
sexp v, *x;
|
||||||
int i, clen = sexp_unbox_integer(len);
|
int i, clen = sexp_unbox_integer(len);
|
||||||
if (! clen) return the_empty_vector;
|
if (! clen) return the_empty_vector;
|
||||||
v = sexp_alloc(ctx, sexp_sizeof(vector) + clen*sizeof(sexp));
|
v = sexp_alloc_tagged(ctx, sexp_sizeof(vector) + clen*sizeof(sexp),
|
||||||
sexp_pointer_tag(v) = SEXP_VECTOR;
|
SEXP_VECTOR);
|
||||||
x = sexp_vector_data(v);
|
x = sexp_vector_data(v);
|
||||||
for (i=0; i<clen; i++)
|
for (i=0; i<clen; i++)
|
||||||
x[i] = dflt;
|
x[i] = dflt;
|
||||||
|
|
Loading…
Add table
Reference in a new issue