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 ed5f7518b6
commit 368baa0561
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 35 deletions

View File

@ -11,17 +11,17 @@ nasal_runtime runtime;
void help()
{
std::cout<<">> [\"file\"] input a file."<<std::endl;
std::cout<<">> [clear ] clear the screen."<<std::endl;
std::cout<<">> [del ] clear the input filename."<<std::endl;
std::cout<<">> [rs ] print source code."<<std::endl;
std::cout<<">> [lex ] use lexer to turn code into tokens."<<std::endl;
std::cout<<">> [ast ] do parsing and check the abstract syntax tree."<<std::endl;
std::cout<<">> [run ] run abstract syntax tree."<<std::endl;
std::cout<<">> [exec ] generate byte code."<<std::endl;
std::cout<<">> [erun ] run byte code."<<std::endl;
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
std::cout<<">> [\"file\"] input a file name.\n";
std::cout<<">> [clear ] clear the screen.\n";
std::cout<<">> [del ] clear the input filename.\n";
std::cout<<">> [rs ] print source code.\n";
std::cout<<">> [lex ] use lexer to turn code into tokens.\n";
std::cout<<">> [ast ] do parsing and check the abstract syntax tree.\n";
std::cout<<">> [run ] run abstract syntax tree.\n";
std::cout<<">> [exec ] generate byte code.\n";
std::cout<<">> [erun ] run byte code.\n";
std::cout<<">> [logo ] print logo of nasal .\n";
std::cout<<">> [exit ] quit nasal interpreter.\n";
return;
}

View File

@ -500,34 +500,46 @@ nasal_scalar::nasal_scalar()
}
nasal_scalar::~nasal_scalar()
{
switch(this->type)
{
case vm_nil: break;
case vm_number: delete (double*)(this->scalar_ptr); break;
case vm_string: delete (std::string*)(this->scalar_ptr); break;
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;
}
// must set type and scalar_ptr to default first
// this operation will avoid SIGTRAP caused by circular reference
// circular reference will cause using destructor repeatedly
int tmp_type=this->type;
void* tmp_ptr=this->scalar_ptr;
this->type=vm_nil;
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;
}
void nasal_scalar::clear()
{
switch(this->type)
{
case vm_nil: break;
case vm_number: delete (double*)(this->scalar_ptr); break;
case vm_string: delete (std::string*)(this->scalar_ptr); break;
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;
}
// must set type and scalar_ptr to default first
// this operation will avoid SIGTRAP caused by circular reference
// circular reference will cause using destructor repeatedly
int tmp_type=this->type;
void* tmp_ptr=this->scalar_ptr;
this->type=vm_nil;
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;
}
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;
}
for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
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];
}
for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[i];
while(!garbage_collector_free_space.empty())
@ -1438,12 +1451,13 @@ void nasal_virtual_machine::clear()
garbage_collector_memory[i][j].collected=true;
}
for(int i=0;i<gc_mem_size;++i)
{
for(int j=0;j<GC_BLK_SIZE;++j)
if(garbage_collector_memory[i][j].elem.get_type()!=vm_nil)
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];
}
for(int i=0;i<mm_mem_size;++i)
delete []memory_manager_memory[i];
while(!garbage_collector_free_space.empty())