fix a bug of circular reference

This commit is contained in:
Valk Richard Li
2020-10-18 02:45:52 -07:00
committed by GitHub
parent 55183fdd7f
commit 3f5a15f1e3
2 changed files with 49 additions and 35 deletions
+11 -11
View File
@@ -11,17 +11,17 @@ nasal_runtime runtime;
void help() void help()
{ {
std::cout<<">> [\"file\"] input a file."<<std::endl; std::cout<<">> [\"file\"] input a file name.\n";
std::cout<<">> [clear ] clear the screen."<<std::endl; std::cout<<">> [clear ] clear the screen.\n";
std::cout<<">> [del ] clear the input filename."<<std::endl; std::cout<<">> [del ] clear the input filename.\n";
std::cout<<">> [rs ] print source code."<<std::endl; std::cout<<">> [rs ] print source code.\n";
std::cout<<">> [lex ] use lexer to turn code into tokens."<<std::endl; std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
std::cout<<">> [ast ] do parsing and check the abstract syntax tree."<<std::endl; std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
std::cout<<">> [run ] run abstract syntax tree."<<std::endl; std::cout<<">> [run ] run abstract syntax tree.\n";
std::cout<<">> [exec ] generate byte code."<<std::endl; std::cout<<">> [exec ] generate byte code.\n";
std::cout<<">> [erun ] run byte code."<<std::endl; std::cout<<">> [erun ] run byte code.\n";
std::cout<<">> [logo ] print logo of nasal ."<<std::endl; std::cout<<">> [logo ] print logo of nasal .\n";
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl; std::cout<<">> [exit ] quit nasal interpreter.\n";
return; return;
} }
+38 -24
View File
@@ -500,34 +500,46 @@ nasal_scalar::nasal_scalar()
} }
nasal_scalar::~nasal_scalar() nasal_scalar::~nasal_scalar()
{ {
switch(this->type) // must set type and scalar_ptr to default first
{ // this operation will avoid SIGTRAP caused by circular reference
case vm_nil: break; // circular reference will cause using destructor repeatedly
case vm_number: delete (double*)(this->scalar_ptr); break; int tmp_type=this->type;
case vm_string: delete (std::string*)(this->scalar_ptr); break; void* tmp_ptr=this->scalar_ptr;
case vm_vector: delete (nasal_vector*)(this->scalar_ptr); break;
case vm_hash: delete (nasal_hash*)(this->scalar_ptr); break;
case vm_function: delete (nasal_function*)(this->scalar_ptr); break;
case vm_closure: delete (nasal_closure*)(this->scalar_ptr); break;
}
this->type=vm_nil; this->type=vm_nil;
this->scalar_ptr=NULL; this->scalar_ptr=NULL;
switch(tmp_type)
{
case vm_nil: break;
case vm_number: delete (double*)(tmp_ptr); break;
case vm_string: delete (std::string*)(tmp_ptr); break;
case vm_vector: delete (nasal_vector*)(tmp_ptr); break;
case vm_hash: delete (nasal_hash*)(tmp_ptr); break;
case vm_function: delete (nasal_function*)(tmp_ptr); break;
case vm_closure: delete (nasal_closure*)(tmp_ptr); break;
}
return; return;
} }
void nasal_scalar::clear() void nasal_scalar::clear()
{ {
switch(this->type) // must set type and scalar_ptr to default first
{ // this operation will avoid SIGTRAP caused by circular reference
case vm_nil: break; // circular reference will cause using destructor repeatedly
case vm_number: delete (double*)(this->scalar_ptr); break; int tmp_type=this->type;
case vm_string: delete (std::string*)(this->scalar_ptr); break; void* tmp_ptr=this->scalar_ptr;
case vm_vector: delete (nasal_vector*)(this->scalar_ptr); break;
case vm_hash: delete (nasal_hash*)(this->scalar_ptr); break;
case vm_function: delete (nasal_function*)(this->scalar_ptr); break;
case vm_closure: delete (nasal_closure*)(this->scalar_ptr); break;
}
this->type=vm_nil; this->type=vm_nil;
this->scalar_ptr=NULL; this->scalar_ptr=NULL;
switch(tmp_type)
{
case vm_nil: break;
case vm_number: delete (double*)(tmp_ptr); break;
case vm_string: delete (std::string*)(tmp_ptr); break;
case vm_vector: delete (nasal_vector*)(tmp_ptr); break;
case vm_hash: delete (nasal_hash*)(tmp_ptr); break;
case vm_function: delete (nasal_function*)(tmp_ptr); break;
case vm_closure: delete (nasal_closure*)(tmp_ptr); break;
}
return; return;
} }
bool nasal_scalar::set_type(int nasal_scalar_type) bool nasal_scalar::set_type(int nasal_scalar_type)
@@ -1385,12 +1397,13 @@ nasal_virtual_machine::~nasal_virtual_machine()
garbage_collector_memory[i][j].collected=true; garbage_collector_memory[i][j].collected=true;
} }
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j) for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil) if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
garbage_collector_memory[i][j].elem.clear(); garbage_collector_memory[i][j].elem.clear();
// must delete gc_memory after destructing all elements
// or it may cause SIGTRAP because some elements may have pointers point to space that has been deleted(free)
for(int i=0;i<gc_mem_size;++i)
delete []garbage_collector_memory[i]; delete []garbage_collector_memory[i];
}
for(int i=0;i<mm_mem_size;++i) for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[i]; delete []memory_manager_memory[i];
while(!garbage_collector_free_space.empty()) while(!garbage_collector_free_space.empty())
@@ -1438,12 +1451,13 @@ void nasal_virtual_machine::clear()
garbage_collector_memory[i][j].collected=true; garbage_collector_memory[i][j].collected=true;
} }
for(int i=0;i<gc_mem_size;++i) for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j) for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil) if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
garbage_collector_memory[i][j].elem.clear(); garbage_collector_memory[i][j].elem.clear();
// must delete gc_memory after destructing all elements
// or it may cause SIGTRAP because some elements may have pointers point to space that has been deleted(free)
for(int i=0;i<gc_mem_size;++i)
delete []garbage_collector_memory[i]; delete []garbage_collector_memory[i];
}
for(int i=0;i<mm_mem_size;++i) for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[i]; delete []memory_manager_memory[i];
while(!garbage_collector_free_space.empty()) while(!garbage_collector_free_space.empty())