From 2c001a5f98c9588b549d4331815a231f714cb2e7 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sun, 23 Dec 2018 15:16:53 +0000 Subject: [PATCH] Sorting out what looked like a premature freeing bug. It wasn't, but in investigating I tightened up allocation and deallocation in frames. --- src/consspaceobject.c | 2 +- src/equal.c | 4 ++-- src/lispops.c | 20 +++++++++++--------- src/print.c | 12 +++++++----- src/print.h | 2 +- src/repl.c | 28 +++++++++++++--------------- src/stack.c | 11 ++++------- src/stack.h | 7 +++++++ 8 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/consspaceobject.c b/src/consspaceobject.c index 0fe28e3..ef96c1f 100644 --- a/src/consspaceobject.c +++ b/src/consspaceobject.c @@ -54,7 +54,7 @@ void inc_ref( struct cons_pointer pointer ) { void dec_ref( struct cons_pointer pointer ) { struct cons_space_object *cell = &pointer2cell( pointer ); - if ( cell->count <= MAXREFERENCE ) { + if ( cell->count > 0 ) { cell->count--; if ( cell->count == 0 ) { diff --git a/src/equal.c b/src/equal.c index ebb085e..0f0597c 100644 --- a/src/equal.c +++ b/src/equal.c @@ -80,8 +80,8 @@ bool equal( struct cons_pointer a, struct cons_pointer b ) { && ( equal( cell_a->payload.string.cdr, cell_b->payload.string.cdr ) || ( end_of_string( cell_a->payload.string.cdr ) - && end_of_string( cell_b->payload.string. - cdr ) ) ); + && end_of_string( cell_b->payload. + string.cdr ) ) ); break; case INTEGERTV: result = diff --git a/src/lispops.c b/src/lispops.c index 62338b1..f29c658 100644 --- a/src/lispops.c +++ b/src/lispops.c @@ -88,8 +88,7 @@ struct cons_pointer eval_form( struct stack_frame *parent, struct cons_pointer result = NIL; struct stack_frame *next = make_empty_frame( parent, env ); - next->arg[0] = form; - inc_ref( next->arg[0] ); + set_reg( next, 0, form ); result = lisp_eval( next, env ); if ( !exceptionp( result ) ) { @@ -242,8 +241,7 @@ struct cons_pointer c_apply( struct stack_frame *frame, struct cons_pointer env ) { struct cons_pointer result = NIL; struct stack_frame *fn_frame = make_empty_frame( frame, env ); - fn_frame->arg[0] = c_car( frame->arg[0] ); - inc_ref( fn_frame->arg[0] ); + set_reg( fn_frame, 0, c_car( frame->arg[0] ) ); struct cons_pointer fn_pointer = lisp_eval( fn_frame, env ); if ( !exceptionp( result ) ) { @@ -438,9 +436,8 @@ lisp_apply( struct stack_frame *frame, struct cons_pointer env ) { fputws( L"Apply: ", stderr ); dump_frame( stderr, frame ); - frame->arg[0] = make_cons( frame->arg[0], frame->arg[1] ); - inc_ref( frame->arg[0] ); - frame->arg[1] = NIL; + set_reg( frame, 0, make_cons( frame->arg[0], frame->arg[1] ) ); + set_reg( frame, 1, NIL ); struct cons_pointer result = c_apply( frame, env ); @@ -653,15 +650,20 @@ lisp_read( struct stack_frame *frame, struct cons_pointer env ) { */ struct cons_pointer lisp_print( struct stack_frame *frame, struct cons_pointer env ) { + struct cons_pointer result = NIL; FILE *output = stdout; if ( writep( frame->arg[1] ) ) { output = pointer2cell( frame->arg[1] ).payload.stream.stream; } - print( output, frame->arg[0] ); + result = print( output, frame->arg[0] ); - return NIL; + fputws( L"Print returning ", stderr); + print(stderr, result); + fputws( L"\n", stderr); + + return result; } diff --git a/src/print.c b/src/print.c index 42bf8b4..0ab42b2 100644 --- a/src/print.c +++ b/src/print.c @@ -103,7 +103,7 @@ void print_list( FILE * output, struct cons_pointer pointer ) { * Print the cons-space object indicated by `pointer` to the stream indicated * by `output`. */ -void print( FILE * output, struct cons_pointer pointer ) { +struct cons_pointer print( FILE * output, struct cons_pointer pointer ) { struct cons_space_object cell = pointer2cell( pointer ); char *buffer; @@ -132,8 +132,8 @@ void print( FILE * output, struct cons_pointer pointer ) { case LAMBDATV: print( output, make_cons( c_string_to_lisp_symbol( "lambda" ), make_cons( cell.payload.lambda.args, - cell.payload. - lambda.body ) ) ); + cell.payload.lambda. + body ) ) ); break; case NILTV: fwprintf( output, L"nil" ); @@ -141,8 +141,8 @@ void print( FILE * output, struct cons_pointer pointer ) { case NLAMBDATV: print( output, make_cons( c_string_to_lisp_symbol( "nlambda" ), make_cons( cell.payload.lambda.args, - cell.payload. - lambda.body ) ) ); + cell.payload.lambda. + body ) ) ); break; case READTV: fwprintf( output, L"(Input stream)" ); @@ -196,4 +196,6 @@ void print( FILE * output, struct cons_pointer pointer ) { if ( print_use_colours ) { fputws( L"\x1B[39m", output ); } + + return pointer; } diff --git a/src/print.h b/src/print.h index 7ee9c80..1399db4 100644 --- a/src/print.h +++ b/src/print.h @@ -14,7 +14,7 @@ #ifndef __print_h #define __print_h -void print( FILE * output, struct cons_pointer pointer ); +struct cons_pointer print( FILE * output, struct cons_pointer pointer ); extern int print_use_colours; #endif diff --git a/src/repl.c b/src/repl.c index 40f6300..2ebf79d 100644 --- a/src/repl.c +++ b/src/repl.c @@ -33,7 +33,7 @@ struct cons_pointer repl_read( struct cons_pointer stream_pointer ) { struct stack_frame *frame = make_empty_frame( NULL, oblist ); - frame->arg[0] = stream_pointer; + set_reg( frame, 0, stream_pointer ); struct cons_pointer result = lisp_read( frame, oblist ); free_stack_frame( frame ); @@ -46,7 +46,7 @@ struct cons_pointer repl_read( struct cons_pointer stream_pointer ) { struct cons_pointer repl_eval( struct cons_pointer input ) { struct stack_frame *frame = make_empty_frame( NULL, oblist ); - frame->arg[0] = input; + set_reg( frame, 0, input ); struct cons_pointer result = lisp_eval( frame, oblist ); if ( !exceptionp( result ) ) { @@ -63,8 +63,8 @@ struct cons_pointer repl_print( struct cons_pointer stream_pointer, struct cons_pointer value ) { struct stack_frame *frame = make_empty_frame( NULL, oblist ); - frame->arg[0] = value; - frame->arg[1] = NIL /* stream_pointer */ ; + set_reg( frame, 0, value ); + set_reg( frame, 1, stream_pointer ); struct cons_pointer result = lisp_print( frame, oblist ); free_stack_frame( frame ); @@ -82,7 +82,10 @@ void repl( FILE * in_stream, FILE * out_stream, FILE * error_stream, bool show_prompt ) { struct cons_pointer input_stream = make_read_stream( in_stream ); + pointer2cell( input_stream ).count = MAXREFERENCE; + struct cons_pointer output_stream = make_write_stream( out_stream ); + pointer2cell( output_stream ).count = MAXREFERENCE; while ( !feof( pointer2cell( input_stream ).payload.stream.stream ) ) { if ( show_prompt ) { @@ -90,21 +93,16 @@ repl( FILE * in_stream, FILE * out_stream, FILE * error_stream, } struct cons_pointer input = repl_read( input_stream ); + inc_ref( input ); if ( exceptionp( input ) ) { + if ( !feof( pointer2cell( input_stream ).payload.stream.stream ) ) { + repl_print( output_stream, input ); + } break; } else { - - struct cons_pointer val = repl_eval( input ); - - if ( feof( pointer2cell( input_stream ).payload.stream.stream ) ) { - /* suppress the 'end of stream' exception */ - if ( !exceptionp( val ) ) { - repl_print( output_stream, val ); - } - } else { - repl_print( output_stream, val ); - } + repl_print( output_stream, repl_eval( input ) ); } + dec_ref( input ); } } diff --git a/src/stack.c b/src/stack.c index 3554f22..1bb8b1b 100644 --- a/src/stack.c +++ b/src/stack.c @@ -49,7 +49,7 @@ struct stack_frame *make_empty_frame( struct stack_frame *previous, result->function = NIL; for ( int i = 0; i < args_in_frame; i++ ) { - result->arg[i] = NIL; + set_reg( result, i, NIL ); } return result; @@ -83,17 +83,15 @@ struct stack_frame *make_stack_frame( struct stack_frame *previous, * https://github.com/simon-brooke/post-scarcity/wiki/parallelism */ struct stack_frame *arg_frame = make_empty_frame( result, env ); - arg_frame->arg[0] = cell.payload.cons.car; - inc_ref( arg_frame->arg[0] ); + set_reg( arg_frame, 0, cell.payload.cons.car ); struct cons_pointer val = lisp_eval( arg_frame, env ); if ( exceptionp( val ) ) { exception = &val; break; } else { - result->arg[i] = val; + set_reg( result, i, val ); } - inc_ref( val ); free_stack_frame( arg_frame ); @@ -129,8 +127,7 @@ struct stack_frame *make_special_frame( struct stack_frame *previous, * stash them on more */ struct cons_space_object cell = pointer2cell( args ); - result->arg[i] = cell.payload.cons.car; - inc_ref( result->arg[i] ); + set_reg( result, i, cell.payload.cons.car ); args = cell.payload.cons.cdr; } diff --git a/src/stack.h b/src/stack.h index ebb1aa1..d708b39 100644 --- a/src/stack.h +++ b/src/stack.h @@ -24,6 +24,13 @@ #ifndef __stack_h #define __stack_h +/** + * set a register in a stack frame. Alwaye use this macro to do so, + • because that way we can be sure the inc_ref happens! + */ +#define set_reg(frame,register,value)frame->arg[register]=value; inc_ref(value) + + /** * Make an empty stack frame, and return it. * @param previous the current top-of-stack;