diff --git a/nasal_gc.h b/nasal_gc.h index e9a920b..257b331 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -82,12 +82,10 @@ class nasal_scop { private: nasal_gc& gc; - std::list > elems; + std::map elems; public: nasal_scop(nasal_gc&); ~nasal_scop(); - void add_scope(); - void del_scope(); void set_closure(nasal_scop&); void add_new_value(int,nasal_val*); nasal_val* get_value_address(int); @@ -435,76 +433,44 @@ nasal_val* nasal_func::get_closure_addr() /*functions of nasal_scop*/ nasal_scop::nasal_scop(nasal_gc& ngc):gc(ngc) { - std::map new_scope; - elems.push_back(new_scope); return; } nasal_scop::~nasal_scop() { - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - for(std::map::iterator j=i->begin();j!=i->end();++j) - gc.del_reference(j->second); - elems.clear(); - return; -} -void nasal_scop::add_scope() -{ - std::map new_scope; - elems.push_front(new_scope); - return; -} -void nasal_scop::del_scope() -{ - std::map& last_scope=elems.front(); - for(std::map::iterator i=last_scope.begin();i!=last_scope.end();++i) + for(std::map::iterator i=elems.begin();i!=elems.end();++i) gc.del_reference(i->second); - elems.pop_front(); + elems.clear(); return; } void nasal_scop::add_new_value(int key,nasal_val* value_address) { - if(elems.front().find(key)!=elems.front().end()) + if(elems.find(key)!=elems.end()) { // if this value already exists,delete the old value and update a new value - nasal_val* old_val_address=elems.front()[key]; - gc.del_reference(old_val_address); + gc.del_reference(elems[key]); } - elems.front()[key]=value_address; + elems[key]=value_address; return; } nasal_val* nasal_scop::get_value_address(int key) { - nasal_val* ret_address=NULL; - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - if(i->find(key)!=i->end()) - return (*i)[key]; - return ret_address; + if(elems.find(key)!=elems.end()) + return elems[key]; + return NULL; } nasal_val** nasal_scop::get_mem_address(int key) { - nasal_val** ret_address=NULL; - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - if(i->find(key)!=i->end()) - return &((*i)[key]); - return ret_address; + if(elems.find(key)!=elems.end()) + return &(elems[key]); + return NULL; } void nasal_scop::set_closure(nasal_scop& tmp) { - for(std::list >::iterator i=elems.begin();i!=elems.end();++i) - for(std::map::iterator j=i->begin();j!=i->end();++j) - gc.del_reference(j->second); - elems.clear(); - for(std::list >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i) - { - std::map new_scope; - elems.push_back(new_scope); - for(std::map::iterator j=i->begin();j!=i->end();++j) - { - nasal_val* value_addr=j->second; - gc.add_reference(value_addr); - elems.back()[j->first]=value_addr; - } - } + for(std::map::iterator i=elems.begin();i!=elems.end();++i) + gc.del_reference(i->second); + elems=tmp.elems; + for(std::map::iterator i=elems.begin();i!=elems.end();++i) + gc.add_reference(i->second); return; } @@ -521,13 +487,13 @@ nasal_val::nasal_val(int nasal_val_type,nasal_gc& nvm) type=nasal_val_type; switch(nasal_val_type) { - case vm_nil: break; - case vm_num: ptr.num=0; break; - case vm_str: ptr.str=new std::string; break; - case vm_vec: ptr.vec=new nasal_vec(nvm); break; - case vm_hash: ptr.hash=new nasal_hash(nvm); break; - case vm_func: ptr.func=new nasal_func(nvm); break; - case vm_scop: ptr.cls=new nasal_scop(nvm); break; + case vm_nil: break; + case vm_num: ptr.num=0; break; + case vm_str: ptr.str=new std::string; break; + case vm_vec: ptr.vec=new nasal_vec(nvm); break; + case vm_hash: ptr.hash=new nasal_hash(nvm); break; + case vm_func: ptr.func=new nasal_func(nvm); break; + case vm_scop: ptr.cls=new nasal_scop(nvm); break; } return; } @@ -540,13 +506,13 @@ nasal_val::~nasal_val() type=vm_nil; switch(tmp_type) { - case vm_nil: break; - case vm_num: break; - case vm_str: delete ptr.str; break; - case vm_vec: delete ptr.vec; break; - case vm_hash: delete ptr.hash; break; + case vm_nil: break; + case vm_num: break; + case vm_str: delete ptr.str; break; + case vm_vec: delete ptr.vec; break; + case vm_hash: delete ptr.hash; break; case vm_func: delete ptr.func; break; - case vm_scop: delete ptr.cls; break; + case vm_scop: delete ptr.cls; break; } return; } @@ -559,13 +525,13 @@ void nasal_val::clear() type=vm_nil; switch(tmp_type) { - case vm_nil: break; - case vm_num: break; - case vm_str: delete ptr.str; break; - case vm_vec: delete ptr.vec; break; - case vm_hash: delete ptr.hash; break; + case vm_nil: break; + case vm_num: break; + case vm_str: delete ptr.str; break; + case vm_vec: delete ptr.vec; break; + case vm_hash: delete ptr.hash; break; case vm_func: delete ptr.func; break; - case vm_scop: delete ptr.cls; break; + case vm_scop: delete ptr.cls; break; } return; } @@ -574,13 +540,13 @@ void nasal_val::set_type(int nasal_val_type,nasal_gc& nvm) type=nasal_val_type; switch(nasal_val_type) { - case vm_nil: break; - case vm_num: ptr.num=0; break; - case vm_str: ptr.str=new std::string; break; - case vm_vec: ptr.vec=new nasal_vec(nvm); break; - case vm_hash: ptr.hash=new nasal_hash(nvm); break; - case vm_func: ptr.func=new nasal_func(nvm); break; - case vm_scop: ptr.cls=new nasal_scop(nvm); break; + case vm_nil: break; + case vm_num: ptr.num=0; break; + case vm_str: ptr.str=new std::string; break; + case vm_vec: ptr.vec=new nasal_vec(nvm); break; + case vm_hash: ptr.hash=new nasal_hash(nvm); break; + case vm_func: ptr.func=new nasal_func(nvm); break; + case vm_scop: ptr.cls=new nasal_scop(nvm); break; } return; } diff --git a/nasal_vm.h b/nasal_vm.h index cec9370..1d9f756 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -825,17 +825,16 @@ void nasal_vm::opr_callf() die("callf: called a value that is not a function"); return; } - nasal_func& ref=func_addr->get_func(); - nasal_val* closure=ref.get_closure_addr(); + nasal_func& ref_func=func_addr->get_func(); + nasal_val* closure=gc.gc_alloc(vm_scop); nasal_scop& ref_closure=closure->get_closure(); - ref_closure.add_scope(); + ref_closure.set_closure(ref_func.get_closure_addr()->get_closure()); local_scope_stack.push(closure); - gc.add_reference(closure); if(para_addr->get_type()==vm_vec) { nasal_vec& ref_vec=para_addr->get_vector(); - std::vector& ref_para=ref.get_para(); - std::vector& ref_default=ref.get_default(); + std::vector& ref_para=ref_func.get_para(); + std::vector& ref_default=ref_func.get_default(); int i=0; for(;i=0) + if(ref_func.get_dynamic_para()>=0) { nasal_val* vec_addr=gc.gc_alloc(vm_vec); for(;iget_vector().add_elem(tmp); gc.add_reference(tmp); } - ref_closure.add_new_value(ref.get_dynamic_para(),vec_addr); + ref_closure.add_new_value(ref_func.get_dynamic_para(),vec_addr); } } else { nasal_hash& ref_hash=para_addr->get_hash(); - std::vector& ref_para=ref.get_para(); - std::vector& ref_default=ref.get_default(); - if(ref.get_dynamic_para()>=0) + std::vector& ref_para=ref_func.get_para(); + std::vector& ref_default=ref_func.get_default(); + if(ref_func.get_dynamic_para()>=0) { die("callf: special call cannot use dynamic parameter"); return; @@ -894,7 +893,7 @@ void nasal_vm::opr_callf() } gc.del_reference(para_addr); call_stack.push(ptr); - ptr=ref.get_entry()-1; + ptr=ref_func.get_entry()-1; return; } void nasal_vm::opr_builtincall() @@ -1086,7 +1085,6 @@ void nasal_vm::opr_return() { nasal_val* closure_addr=local_scope_stack.top(); local_scope_stack.pop(); - closure_addr->get_closure().del_scope(); gc.del_reference(closure_addr); ptr=call_stack.top(); call_stack.pop();