Sorting out what looked like a premature freeing bug.
It wasn't, but in investigating I tightened up allocation and deallocation in frames.
This commit is contained in:
parent
98120d045b
commit
2c001a5f98
|
@ -54,7 +54,7 @@ void inc_ref( struct cons_pointer pointer ) {
|
||||||
void dec_ref( struct cons_pointer pointer ) {
|
void dec_ref( struct cons_pointer pointer ) {
|
||||||
struct cons_space_object *cell = &pointer2cell( pointer );
|
struct cons_space_object *cell = &pointer2cell( pointer );
|
||||||
|
|
||||||
if ( cell->count <= MAXREFERENCE ) {
|
if ( cell->count > 0 ) {
|
||||||
cell->count--;
|
cell->count--;
|
||||||
|
|
||||||
if ( cell->count == 0 ) {
|
if ( cell->count == 0 ) {
|
||||||
|
|
|
@ -80,8 +80,8 @@ bool equal( struct cons_pointer a, struct cons_pointer b ) {
|
||||||
&& ( equal( cell_a->payload.string.cdr,
|
&& ( equal( cell_a->payload.string.cdr,
|
||||||
cell_b->payload.string.cdr )
|
cell_b->payload.string.cdr )
|
||||||
|| ( end_of_string( cell_a->payload.string.cdr )
|
|| ( end_of_string( cell_a->payload.string.cdr )
|
||||||
&& end_of_string( cell_b->payload.string.
|
&& end_of_string( cell_b->payload.
|
||||||
cdr ) ) );
|
string.cdr ) ) );
|
||||||
break;
|
break;
|
||||||
case INTEGERTV:
|
case INTEGERTV:
|
||||||
result =
|
result =
|
||||||
|
|
|
@ -88,8 +88,7 @@ struct cons_pointer eval_form( struct stack_frame *parent,
|
||||||
|
|
||||||
struct cons_pointer result = NIL;
|
struct cons_pointer result = NIL;
|
||||||
struct stack_frame *next = make_empty_frame( parent, env );
|
struct stack_frame *next = make_empty_frame( parent, env );
|
||||||
next->arg[0] = form;
|
set_reg( next, 0, form );
|
||||||
inc_ref( next->arg[0] );
|
|
||||||
result = lisp_eval( next, env );
|
result = lisp_eval( next, env );
|
||||||
|
|
||||||
if ( !exceptionp( result ) ) {
|
if ( !exceptionp( result ) ) {
|
||||||
|
@ -242,8 +241,7 @@ struct cons_pointer
|
||||||
c_apply( struct stack_frame *frame, struct cons_pointer env ) {
|
c_apply( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
struct cons_pointer result = NIL;
|
struct cons_pointer result = NIL;
|
||||||
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
struct stack_frame *fn_frame = make_empty_frame( frame, env );
|
||||||
fn_frame->arg[0] = c_car( frame->arg[0] );
|
set_reg( fn_frame, 0, c_car( frame->arg[0] ) );
|
||||||
inc_ref( fn_frame->arg[0] );
|
|
||||||
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
struct cons_pointer fn_pointer = lisp_eval( fn_frame, env );
|
||||||
|
|
||||||
if ( !exceptionp( result ) ) {
|
if ( !exceptionp( result ) ) {
|
||||||
|
@ -438,9 +436,8 @@ lisp_apply( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
fputws( L"Apply: ", stderr );
|
fputws( L"Apply: ", stderr );
|
||||||
dump_frame( stderr, frame );
|
dump_frame( stderr, frame );
|
||||||
|
|
||||||
frame->arg[0] = make_cons( frame->arg[0], frame->arg[1] );
|
set_reg( frame, 0, make_cons( frame->arg[0], frame->arg[1] ) );
|
||||||
inc_ref( frame->arg[0] );
|
set_reg( frame, 1, NIL );
|
||||||
frame->arg[1] = NIL;
|
|
||||||
|
|
||||||
struct cons_pointer result = c_apply( frame, env );
|
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
|
struct cons_pointer
|
||||||
lisp_print( struct stack_frame *frame, struct cons_pointer env ) {
|
lisp_print( struct stack_frame *frame, struct cons_pointer env ) {
|
||||||
|
struct cons_pointer result = NIL;
|
||||||
FILE *output = stdout;
|
FILE *output = stdout;
|
||||||
|
|
||||||
if ( writep( frame->arg[1] ) ) {
|
if ( writep( frame->arg[1] ) ) {
|
||||||
output = pointer2cell( frame->arg[1] ).payload.stream.stream;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
12
src/print.c
12
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
|
* Print the cons-space object indicated by `pointer` to the stream indicated
|
||||||
* by `output`.
|
* 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 );
|
struct cons_space_object cell = pointer2cell( pointer );
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
|
@ -132,8 +132,8 @@ void print( FILE * output, struct cons_pointer pointer ) {
|
||||||
case LAMBDATV:
|
case LAMBDATV:
|
||||||
print( output, make_cons( c_string_to_lisp_symbol( "lambda" ),
|
print( output, make_cons( c_string_to_lisp_symbol( "lambda" ),
|
||||||
make_cons( cell.payload.lambda.args,
|
make_cons( cell.payload.lambda.args,
|
||||||
cell.payload.
|
cell.payload.lambda.
|
||||||
lambda.body ) ) );
|
body ) ) );
|
||||||
break;
|
break;
|
||||||
case NILTV:
|
case NILTV:
|
||||||
fwprintf( output, L"nil" );
|
fwprintf( output, L"nil" );
|
||||||
|
@ -141,8 +141,8 @@ void print( FILE * output, struct cons_pointer pointer ) {
|
||||||
case NLAMBDATV:
|
case NLAMBDATV:
|
||||||
print( output, make_cons( c_string_to_lisp_symbol( "nlambda" ),
|
print( output, make_cons( c_string_to_lisp_symbol( "nlambda" ),
|
||||||
make_cons( cell.payload.lambda.args,
|
make_cons( cell.payload.lambda.args,
|
||||||
cell.payload.
|
cell.payload.lambda.
|
||||||
lambda.body ) ) );
|
body ) ) );
|
||||||
break;
|
break;
|
||||||
case READTV:
|
case READTV:
|
||||||
fwprintf( output, L"(Input stream)" );
|
fwprintf( output, L"(Input stream)" );
|
||||||
|
@ -196,4 +196,6 @@ void print( FILE * output, struct cons_pointer pointer ) {
|
||||||
if ( print_use_colours ) {
|
if ( print_use_colours ) {
|
||||||
fputws( L"\x1B[39m", output );
|
fputws( L"\x1B[39m", output );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pointer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef __print_h
|
#ifndef __print_h
|
||||||
#define __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;
|
extern int print_use_colours;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
28
src/repl.c
28
src/repl.c
|
@ -33,7 +33,7 @@
|
||||||
struct cons_pointer repl_read( struct cons_pointer stream_pointer ) {
|
struct cons_pointer repl_read( struct cons_pointer stream_pointer ) {
|
||||||
struct stack_frame *frame = make_empty_frame( NULL, oblist );
|
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 );
|
struct cons_pointer result = lisp_read( frame, oblist );
|
||||||
free_stack_frame( frame );
|
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 cons_pointer repl_eval( struct cons_pointer input ) {
|
||||||
struct stack_frame *frame = make_empty_frame( NULL, oblist );
|
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 );
|
struct cons_pointer result = lisp_eval( frame, oblist );
|
||||||
|
|
||||||
if ( !exceptionp( result ) ) {
|
if ( !exceptionp( result ) ) {
|
||||||
|
@ -63,8 +63,8 @@ struct cons_pointer repl_print( struct cons_pointer stream_pointer,
|
||||||
struct cons_pointer value ) {
|
struct cons_pointer value ) {
|
||||||
struct stack_frame *frame = make_empty_frame( NULL, oblist );
|
struct stack_frame *frame = make_empty_frame( NULL, oblist );
|
||||||
|
|
||||||
frame->arg[0] = value;
|
set_reg( frame, 0, value );
|
||||||
frame->arg[1] = NIL /* stream_pointer */ ;
|
set_reg( frame, 1, stream_pointer );
|
||||||
struct cons_pointer result = lisp_print( frame, oblist );
|
struct cons_pointer result = lisp_print( frame, oblist );
|
||||||
free_stack_frame( frame );
|
free_stack_frame( frame );
|
||||||
|
|
||||||
|
@ -82,7 +82,10 @@ void
|
||||||
repl( FILE * in_stream, FILE * out_stream, FILE * error_stream,
|
repl( FILE * in_stream, FILE * out_stream, FILE * error_stream,
|
||||||
bool show_prompt ) {
|
bool show_prompt ) {
|
||||||
struct cons_pointer input_stream = make_read_stream( in_stream );
|
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 );
|
struct cons_pointer output_stream = make_write_stream( out_stream );
|
||||||
|
pointer2cell( output_stream ).count = MAXREFERENCE;
|
||||||
|
|
||||||
while ( !feof( pointer2cell( input_stream ).payload.stream.stream ) ) {
|
while ( !feof( pointer2cell( input_stream ).payload.stream.stream ) ) {
|
||||||
if ( show_prompt ) {
|
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 );
|
struct cons_pointer input = repl_read( input_stream );
|
||||||
|
inc_ref( input );
|
||||||
|
|
||||||
if ( exceptionp( input ) ) {
|
if ( exceptionp( input ) ) {
|
||||||
|
if ( !feof( pointer2cell( input_stream ).payload.stream.stream ) ) {
|
||||||
|
repl_print( output_stream, input );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
repl_print( output_stream, repl_eval( input ) );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dec_ref( input );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/stack.c
11
src/stack.c
|
@ -49,7 +49,7 @@ struct stack_frame *make_empty_frame( struct stack_frame *previous,
|
||||||
result->function = NIL;
|
result->function = NIL;
|
||||||
|
|
||||||
for ( int i = 0; i < args_in_frame; i++ ) {
|
for ( int i = 0; i < args_in_frame; i++ ) {
|
||||||
result->arg[i] = NIL;
|
set_reg( result, i, NIL );
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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
|
* https://github.com/simon-brooke/post-scarcity/wiki/parallelism
|
||||||
*/
|
*/
|
||||||
struct stack_frame *arg_frame = make_empty_frame( result, env );
|
struct stack_frame *arg_frame = make_empty_frame( result, env );
|
||||||
arg_frame->arg[0] = cell.payload.cons.car;
|
set_reg( arg_frame, 0, cell.payload.cons.car );
|
||||||
inc_ref( arg_frame->arg[0] );
|
|
||||||
|
|
||||||
struct cons_pointer val = lisp_eval( arg_frame, env );
|
struct cons_pointer val = lisp_eval( arg_frame, env );
|
||||||
if ( exceptionp( val ) ) {
|
if ( exceptionp( val ) ) {
|
||||||
exception = &val;
|
exception = &val;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
result->arg[i] = val;
|
set_reg( result, i, val );
|
||||||
}
|
}
|
||||||
inc_ref( val );
|
|
||||||
|
|
||||||
free_stack_frame( arg_frame );
|
free_stack_frame( arg_frame );
|
||||||
|
|
||||||
|
@ -129,8 +127,7 @@ struct stack_frame *make_special_frame( struct stack_frame *previous,
|
||||||
* stash them on more */
|
* stash them on more */
|
||||||
struct cons_space_object cell = pointer2cell( args );
|
struct cons_space_object cell = pointer2cell( args );
|
||||||
|
|
||||||
result->arg[i] = cell.payload.cons.car;
|
set_reg( result, i, cell.payload.cons.car );
|
||||||
inc_ref( result->arg[i] );
|
|
||||||
|
|
||||||
args = cell.payload.cons.cdr;
|
args = cell.payload.cons.cdr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,13 @@
|
||||||
#ifndef __stack_h
|
#ifndef __stack_h
|
||||||
#define __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.
|
* Make an empty stack frame, and return it.
|
||||||
* @param previous the current top-of-stack;
|
* @param previous the current top-of-stack;
|
||||||
|
|
Loading…
Reference in a new issue