diff --git a/version3.0/nasal_gc.h b/version3.0/nasal_gc.h index 6b50bcd..f19ec67 100644 --- a/version3.0/nasal_gc.h +++ b/version3.0/nasal_gc.h @@ -77,7 +77,7 @@ public: void add_new_value(std::string,int); int get_value_address(std::string); int get_mem_address(std::string); - void deepcopy(nasal_closure&); + void set_closure(nasal_closure&); }; class nasal_scalar @@ -123,7 +123,7 @@ class nasal_virtual_machine struct gc_unit { bool collected; - char ref_cnt; + int ref_cnt; nasal_scalar elem; gc_unit() { @@ -141,10 +141,12 @@ private: public: ~nasal_virtual_machine(); void clear(); + void debug(); int gc_alloc(); // garbage collector gives a new space nasal_scalar& gc_get(int); // get scalar that stored in gc - int add_reference(int); - int del_reference(int); + void add_reference(int); + void del_reference(int); + int get_refcnt(int); int mem_alloc(); // memory gives a new space int mem_free(int); // give space back to memory int mem_change(int,int); // change value in memory space @@ -190,6 +192,8 @@ int nasal_vector::del_elem(int index) return -1; int ret=elems[index]; nasal_vm.mem_free(ret); + for(int i=index;i=0) nasal_vm.del_reference(closure_addr); - closure_addr=value_address; + int new_closure=nasal_vm.gc_alloc(); + nasal_vm.gc_get(new_closure).set_type(vm_closure); + nasal_vm.gc_get(new_closure).get_closure().set_closure(nasal_vm.gc_get(value_address).get_closure()); + closure_addr=new_closure; return; } int nasal_function::get_closure_addr() @@ -415,39 +422,8 @@ void nasal_closure::del_scope() { if(this->elems.empty()) return; - // make closure here - // functions in different scope but the same closure will get different copies of closures - // functions in the same scope will get the same copy of closure,when running these functions,one closure will be changed,make sure you are using it correctly! - // please notice this,otherwise your programme may not work correctly - int closure=nasal_vm.gc_alloc(); - nasal_vm.gc_get(closure).set_type(vm_closure); - nasal_closure& new_closure=nasal_vm.gc_get(closure).get_closure(); - new_closure.deepcopy(*this); - - std::vector func_name; - for(std::map::iterator i=new_closure.elems.back().begin();i!=new_closure.elems.back().end();++i) - { - int value_addr=nasal_vm.mem_get(i->second); - if(nasal_vm.gc_get(value_addr).get_type()==vm_function) - { - func_name.push_back(i->first); - nasal_vm.mem_free(i->second); // mem_free will delete the reference of mem_get(i->second) - } - } - for(int i=0;i::iterator i=this->elems.back().begin();i!=this->elems.back().end();++i) - { - int value_addr=nasal_vm.mem_get(i->second); - if(nasal_vm.gc_get(value_addr).get_type()==vm_function) - { - nasal_vm.gc_get(value_addr).get_func().set_closure_addr(closure); - nasal_vm.add_reference(closure); - } + for(std::map::iterator i=elems.back().begin();i!=elems.back().end();++i) nasal_vm.mem_free(i->second); - } - nasal_vm.del_reference(closure); this->elems.pop_back(); return; } @@ -484,19 +460,22 @@ int nasal_closure::get_mem_address(std::string key) } return ret_address; } -void nasal_closure::deepcopy(nasal_closure& tmp) +void nasal_closure::set_closure(nasal_closure& tmp) { + for(std::list >::iterator i=elems.begin();i!=elems.end();++i) + for(std::map::iterator j=i->begin();j!=i->end();++j) + nasal_vm.mem_free(j->second); + elems.clear(); for(std::list >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i) { this->add_scope(); for(std::map::iterator j=i->begin();j!=i->end();++j) { int new_mem_addr=nasal_vm.mem_alloc(); - int new_value_addr=nasal_vm.gc_alloc(); - nasal_vm.mem_init(new_mem_addr,new_value_addr); - int tmp_value_addr=nasal_vm.mem_get(j->second); - nasal_vm.gc_get(new_value_addr).deepcopy(nasal_vm.gc_get(tmp_value_addr)); - this->elems.back()[j->first]=new_mem_addr; + int value_addr=nasal_vm.mem_get(j->second); + nasal_vm.mem_init(new_mem_addr,value_addr); + nasal_vm.add_reference(value_addr); + elems.back()[j->first]=new_mem_addr; } } return; @@ -521,12 +500,12 @@ nasal_scalar::~nasal_scalar() 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->scalar_ptr=NULL; return; } void nasal_scalar::clear() { - this->type=vm_nil; switch(this->type) { case vm_nil: break; @@ -537,6 +516,7 @@ void nasal_scalar::clear() 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->scalar_ptr=NULL; return; } @@ -630,7 +610,7 @@ void nasal_scalar::deepcopy(nasal_scalar& tmp) case vm_vector: this->scalar_ptr=(void*)(new nasal_vector);(*(nasal_vector*)this->scalar_ptr).deepcopy(tmp.get_vector());break; case vm_hash: this->scalar_ptr=(void*)(new nasal_hash);(*(nasal_hash*)this->scalar_ptr).deepcopy(tmp.get_hash());break; case vm_function: this->scalar_ptr=(void*)(new nasal_function);(*(nasal_function*)this->scalar_ptr).deepcopy(tmp.get_func());break; - case vm_closure: this->scalar_ptr=(void*)(new nasal_closure);(*(nasal_closure*)this->scalar_ptr).deepcopy(tmp.get_closure());break; + case vm_closure: this->scalar_ptr=(void*)(new nasal_closure);(*(nasal_closure*)this->scalar_ptr).set_closure(tmp.get_closure());break; } return; } @@ -1381,19 +1361,52 @@ nasal_virtual_machine::~nasal_virtual_machine() int gc_mem_size=garbage_collector_memory.size(); int mm_mem_size=memory_manager_memory.size(); for(int i=0;i> [debug] "<<((i<<8)+j)<<": "<>8); int blk_plc=(value_address&0xff); if(0<=value_address && value_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected) ++garbage_collector_memory[blk_num][blk_plc].ref_cnt; else - { std::cout<<">> [vm] gc_add_ref:unexpected memory \'"<>8); int blk_plc=(value_address&0xff); @@ -1454,7 +1464,7 @@ int nasal_virtual_machine::del_reference(int value_address) else { std::cout<<">> [vm] gc_del_ref:unexpected memory \'"<>8); + int blk_plc=(value_address&0xff); + if(0<=value_address && value_address<(garbage_collector_memory.size()<<8) && !garbage_collector_memory[blk_num][blk_plc].collected) + return garbage_collector_memory[blk_num][blk_plc].ref_cnt; + else + std::cout<<">> [vm] get_refcnt:unexpected memory \'"<error=0; + this->function_returned_address=-1; this->global_scope_address=nasal_vm.gc_alloc(); nasal_vm.gc_get(global_scope_address).set_type(vm_closure); @@ -168,7 +169,7 @@ int nasal_runtime::hash_generation(nasal_ast& node,int local_scope_addr) } return new_addr; } -int nasal_runtime::function_generation(nasal_ast& node) +int nasal_runtime::function_generation(nasal_ast& node,int local_scope_addr) { int new_addr=nasal_vm.gc_alloc(); nasal_vm.gc_get(new_addr).set_type(vm_function); @@ -177,9 +178,15 @@ int nasal_runtime::function_generation(nasal_ast& node) ref_of_this_function.set_arguments(node.get_children()[0]); ref_of_this_function.set_run_block(node.get_children()[1]); - int new_closure=nasal_vm.gc_alloc(); - nasal_vm.gc_get(new_closure).set_type(vm_closure); - ref_of_this_function.set_closure_addr(new_closure); + if(local_scope_addr>=0) + ref_of_this_function.set_closure_addr(local_scope_addr); + else + { + int new_closure=nasal_vm.gc_alloc(); + nasal_vm.gc_get(new_closure).set_type(vm_closure); + ref_of_this_function.set_closure_addr(new_closure); + nasal_vm.del_reference(new_closure); + } return new_addr; } int nasal_runtime::main_progress() @@ -353,12 +360,18 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow nasal_vm.gc_get(while_local_scope_addr).get_closure().add_scope(); } // check condition and begin loop - while(check_condition(calculation(condition_node,while_local_scope_addr))) + int condition_value_addr=calculation(condition_node,while_local_scope_addr); + bool result=check_condition(condition_value_addr); + nasal_vm.del_reference(condition_value_addr); + while(result) { // return expression will be checked in block_progress ret_state=block_progress(run_block_node,local_scope_addr,allow_return); if(ret_state==rt_break || ret_state==rt_error || ret_state==rt_return) break; + condition_value_addr=calculation(condition_node,while_local_scope_addr); + result=check_condition(condition_value_addr); + nasal_vm.del_reference(condition_value_addr); } nasal_vm.gc_get(while_local_scope_addr).get_closure().del_scope(); nasal_vm.del_reference(while_local_scope_addr); @@ -429,6 +442,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow if(ret_state==rt_break || ret_state==rt_return || ret_state==rt_error) break; } + nasal_vm.del_reference(vector_value_addr); nasal_vm.gc_get(forei_local_scope_addr).get_closure().del_scope(); nasal_vm.del_reference(forei_local_scope_addr); } @@ -453,9 +467,12 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow nasal_vm.gc_get(for_local_scope_addr).get_closure().add_scope(); } // for progress + int condition_value_addr=calculation(condition_node,for_local_scope_addr); + bool result=check_condition(condition_value_addr); + nasal_vm.del_reference(condition_value_addr); for( ret_state=before_for_loop(before_loop_node,for_local_scope_addr); - check_condition(calculation(condition_node,for_local_scope_addr)); + result; ret_state=after_each_for_loop(each_loop_do_node,for_local_scope_addr) ) { @@ -464,6 +481,9 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr,bool allow ret_state=block_progress(run_block_node,for_local_scope_addr,allow_return); if(ret_state==rt_error || ret_state==rt_return || ret_state==rt_break) break; + condition_value_addr=calculation(condition_node,for_local_scope_addr); + result=check_condition(condition_value_addr); + nasal_vm.del_reference(condition_value_addr); } nasal_vm.gc_get(for_local_scope_addr).get_closure().del_scope(); nasal_vm.del_reference(for_local_scope_addr); @@ -513,7 +533,9 @@ int nasal_runtime::conditional_progress(nasal_ast& node,int local_scope_addr,boo int condition_value_addr=calculation(tmp_node.get_children()[0],local_scope_addr); if(condition_value_addr<0) return rt_error; - if(check_condition(condition_value_addr)) + bool result=check_condition(condition_value_addr); + nasal_vm.del_reference(condition_value_addr); + if(result) { ret_state=block_progress(tmp_node.get_children()[1],local_scope_addr,allow_return); break; @@ -862,8 +884,8 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_ // set self if(func_name.length()) { - run_closure.add_new_value(func_name,base_value_addr); nasal_vm.add_reference(base_value_addr); + run_closure.add_new_value(func_name,base_value_addr); } // set hash.me if(last_call_hash_addr>=0) @@ -1041,6 +1063,8 @@ int nasal_runtime::call_function(nasal_ast& node,std::string func_name,int base_ } } int ret_state=block_progress(reference_of_func.get_run_block(),run_closure_addr,true); + run_closure.del_scope(); + if(ret_state==rt_break || ret_state==rt_continue) { std::cout<<">> [runtime] call_function: break and continue are not allowed to be used here."<=0) { ret_value_addr=function_returned_address; @@ -1243,7 +1266,7 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr) else if(calculation_type==ast_hash) ret_address=hash_generation(node,local_scope_addr); else if(calculation_type==ast_function) - ret_address=function_generation(node); + ret_address=function_generation(node,local_scope_addr); else if(calculation_type==ast_call) ret_address=call_scalar(node,local_scope_addr); else if(calculation_type==ast_add) @@ -1393,13 +1416,6 @@ int nasal_runtime::calculation(nasal_ast& node,int local_scope_addr) int new_scalar_gc_addr=calculation(node.get_children()[1],local_scope_addr); int type=nasal_vm.gc_get(new_scalar_gc_addr).get_type(); - if(type!=vm_hash && type!=vm_vector) - { - int tmp_value_addr=nasal_vm.gc_alloc(); - nasal_vm.gc_get(tmp_value_addr).deepcopy(nasal_vm.gc_get(new_scalar_gc_addr)); - nasal_vm.del_reference(new_scalar_gc_addr); - new_scalar_gc_addr=tmp_value_addr; - } nasal_vm.mem_change(scalar_mem_space,new_scalar_gc_addr);// this progress will delete the reference to old gc_addr in scalar_mem_space nasal_vm.add_reference(new_scalar_gc_addr);// this reference is reserved for ret_address ret_address=new_scalar_gc_addr;