From 5899c6e3785b578ade77a50d764460529fd56684 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sun, 12 Apr 2020 01:58:30 -0700 Subject: [PATCH] update --- version2.0/main.cpp | 1 - version2.0/nasal_gc.h | 511 +++++++++++++++++++------------------ version2.0/nasal_runtime.h | 22 +- 3 files changed, 284 insertions(+), 250 deletions(-) diff --git a/version2.0/main.cpp b/version2.0/main.cpp index a6a9626..f8f1889 100644 --- a/version2.0/main.cpp +++ b/version2.0/main.cpp @@ -49,7 +49,6 @@ int main() std::cin>>command; if(command=="help") { - std::cout<<">> Be careful that this program does not support unicode(unicode will be set to \'?\')"<> [\'file\'] input a file."<> [cls ] clear the screen."<> [del ] clear the resource code."< > local_scope; - abstract_syntax_tree parameter_list; - abstract_syntax_tree function_root; - // parent_hash_addr is used to store the address of the hash which has this nasal_function - // because nasal_function needs this address to adjust the identifier called 'me' in local_scope - // 'me' is the identifier which points to the hash which has this nasal_function - public: - void set_clear(); - void set_local_scope(std::list >&); - void set_paramemter_list(abstract_syntax_tree&); - void set_statement_block(abstract_syntax_tree&); - std::list >& get_local_scope(); - abstract_syntax_tree& get_parameter_list(); - abstract_syntax_tree& get_statement_block(); - void deep_copy(nasal_function&); +private: + // closure_updated flag is used to mark if this function's closure is updated. + // to avoid some unexpected errors,closure of each function must be updated before blocks popping back the last scope + bool closure_updated; + std::list > local_scope; + abstract_syntax_tree parameter_list; + abstract_syntax_tree function_root; +public: + void set_clear(); + void set_local_scope(std::list >&); + bool get_closure_update_state(); + void set_closure_update_state(bool); + void set_paramemter_list(abstract_syntax_tree&); + void set_statement_block(abstract_syntax_tree&); + std::list >& get_local_scope(); + abstract_syntax_tree& get_parameter_list(); + abstract_syntax_tree& get_statement_block(); + void deep_copy(nasal_function&); }; class nasal_number { - private: - double nas_number; - public: - void set_clear(); - void set_number(double); - double get_number(); - void deep_copy(nasal_number&); +private: + double nas_number; +public: + void set_clear(); + void set_number(double); + double get_number(); + void deep_copy(nasal_number&); }; class nasal_string { - private: - std::string nas_string; - public: - void set_clear(); - void set_string(std::string); - std::string get_string(); - void deep_copy(nasal_string&); +private: + std::string nas_string; +public: + void set_clear(); + void set_string(std::string); + std::string get_string(); + void deep_copy(nasal_string&); }; class nasal_vector { - private: - std::vector nas_array; - public: - void set_clear(); - void vec_push(int); - int* get_elem_addr(int); - int get_elem(int); - int vec_pop(); - int get_size(); - int* get_parent_hash_member_addr(std::string); - int get_parent_hash_member(std::string); - void generate_new_hash(); - void deep_copy(nasal_vector&); +private: + std::vector nas_array; +public: + void set_clear(); + void vec_push(int); + int* get_elem_addr(int); + int get_elem(int); + int vec_pop(); + int get_size(); + int* get_parent_hash_member_addr(std::string); + int get_parent_hash_member(std::string); + void generate_new_hash(); + void deep_copy(nasal_vector&); }; class nasal_hash { - private: - std::map nas_hash; - public: - void set_clear(); - int* get_hash_member_addr(std::string); - int get_hash_member(std::string); - void hash_push(std::string,int); - void hash_pop(std::string); - void deep_copy(nasal_hash&); +private: + std::map nas_hash; +public: + void set_clear(); + int* get_hash_member_addr(std::string); + int get_hash_member(std::string); + void hash_push(std::string,int); + void hash_pop(std::string); + void deep_copy(nasal_hash&); }; class nasal_scalar { - private: - int type; - nasal_string var_string; - nasal_number var_number; - nasal_vector var_vector; - nasal_hash var_hash; - nasal_function var_func; - public: - nasal_scalar(); - void set_type(int); - int get_type(); - nasal_number& get_number(); - nasal_string& get_string(); - nasal_vector& get_vector(); - nasal_hash& get_hash(); - nasal_function& get_function(); +private: + int type; + nasal_string var_string; + nasal_number var_number; + nasal_vector var_vector; + nasal_hash var_hash; + nasal_function var_func; +public: + nasal_scalar(); + void set_type(int); + int get_type(); + nasal_number& get_number(); + nasal_string& get_string(); + nasal_vector& get_vector(); + nasal_hash& get_hash(); + nasal_function& get_function(); }; struct gc_unit @@ -126,208 +128,208 @@ struct memory_block class memory_block_list { - private: - memory_block* head; - int mem_size; - int blk_size; - public: - memory_block_list() +private: + memory_block* head; + int mem_size; + int blk_size; +public: + memory_block_list() + { + mem_size=0; + blk_size=1; + head=new memory_block; + head->next=NULL; + return; + } + ~memory_block_list() + { + mem_size=0; + blk_size=0; + memory_block* ptr=head; + while(ptr) { - mem_size=0; - blk_size=1; - head=new memory_block; - head->next=NULL; - return; + memory_block* tmp_ptr=ptr; + ptr=ptr->next; + delete tmp_ptr; } - ~memory_block_list() + return; + } + void clear() + { + memory_block* ptr=head; + while(ptr) { - mem_size=0; - blk_size=0; - memory_block* ptr=head; - while(ptr) - { - memory_block* tmp_ptr=ptr; - ptr=ptr->next; - delete tmp_ptr; - } - return; + memory_block* tmp_ptr=ptr; + ptr=ptr->next; + delete tmp_ptr; } - void clear() + mem_size=0; + blk_size=1; + head=new memory_block; + head->next=NULL; + return; + } + gc_unit& operator[](int address) + { + int block_num=address/NAS_POOL_SIZE; + int block_plc=address%NAS_POOL_SIZE; + memory_block* ptr=head; + for(int i=0;inext; + return ptr->space[block_plc]; + } + void push_back() + { + ++mem_size; + if(mem_size>blk_size*NAS_POOL_SIZE) { memory_block* ptr=head; - while(ptr) - { - memory_block* tmp_ptr=ptr; + while(ptr->next) ptr=ptr->next; - delete tmp_ptr; - } - mem_size=0; - blk_size=1; - head=new memory_block; - head->next=NULL; - return; - } - gc_unit& operator[](int address) - { - int block_num=address/NAS_POOL_SIZE; - int block_plc=address%NAS_POOL_SIZE; - memory_block* ptr=head; - for(int i=0;inext; - return ptr->space[block_plc]; - } - void push_back() - { - ++mem_size; - if(mem_size>blk_size*NAS_POOL_SIZE) - { - memory_block* ptr=head; - while(ptr->next) - ptr=ptr->next; - ptr->next=new memory_block; - ptr->next->next=NULL; - ++blk_size; - } - return; - } - int size() - { - return mem_size; - } - int capacity() - { - return NAS_POOL_SIZE*blk_size; + ptr->next=new memory_block; + ptr->next->next=NULL; + ++blk_size; } + return; + } + int size() + { + return mem_size; + } + int capacity() + { + return NAS_POOL_SIZE*blk_size; + } }; #endif class gc_manager { - private: - // free_space list is used to store space that is not in use. - std::list free_space; - /* - cannot use std::vector to simulate memory - because if vector memory is not enough,vector will use another larger memory as it's main memory - then all the things will be moved to a new space, - at this time if you reference a member in it,this will cause segmentation error. - */ - memory_block_list memory; - bool error_occurred; - public: - void gc_init() +private: + // free_space list is used to store space that is not in use. + std::list free_space; + /* + cannot use std::vector to simulate memory + because if vector memory is not enough,vector will use another larger memory as it's main memory + then all the things will be moved to a new space, + at this time if you reference a member in it,this will cause segmentation error. + */ + memory_block_list memory; + bool error_occurred; +public: + void gc_init() + { + // this function must be called in class nasal_runtime before running any codes + memory.clear(); + free_space.clear(); + error_occurred=false; + return; + } + int gc_alloc() + { + // add a new space for a new value + // if list free_space is not empty,it will get the address at the front and give it to the new value + // if list free_space is empty,it will add new space in memory vector and give it to the new value + // by this way it can manage memory efficiently. + if(free_space.empty()) { - // this function must be called in class nasal_runtime before running any codes - memory.clear(); - free_space.clear(); - error_occurred=false; - return; + memory.push_back(); + free_space.push_back(memory.size()-1); } - int gc_alloc() + int alloc_plc=free_space.front(); + free_space.pop_front(); + memory[alloc_plc].collected=false; + memory[alloc_plc].refcnt=1; + return alloc_plc; + } + int get_reference(int addr) + { + // get the reference counts of the scalar + return memory[addr].refcnt; + } + nasal_scalar& get_scalar(int addr) + { + // get the reference of the scalar + return memory[addr].elem; + } + bool place_check(const int addr) + { + // check if this place is in memory + // and this place is uncollected + // this function is often used when an identifier is calling a space in memory + return (0<=addr) && (addr> [Gc] fatal error: reference unexpected memory place "; + prt_hex(addr); + std::cout<<" ."<> [Gc] fatal error: reference unexpected memory place "; - prt_hex(addr); - std::cout<<" ."<> [Gc] collected ";prt_hex(addr);std::cout<> [Gc] collected ";prt_hex(addr);std::cout<> [Gc] fatal error: delete unexpected memory address: "; + prt_hex(addr); + std::cout<<" ."<> [Gc] memory size:"<> [Gc] memory capacity:"<> [Gc] memory usage: "<> [Gc] fatal error: delete unexpected memory address: "; - prt_hex(addr); - std::cout<<" ."<> [Gc] memory size:"<> [Gc] memory capacity:"<> [Gc] memory usage: "< >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) for(std::map::iterator i=iter->begin();i!=iter->end();++i) nasal_gc.reference_delete(i->second); + closure_updated=false; local_scope.clear(); function_root.set_clear(); return; } void nasal_function::set_local_scope(std::list >& tmp_scope) { + for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) + for(std::map::iterator i=iter->begin();i!=iter->end();++i) + nasal_gc.reference_delete(i->second); local_scope=tmp_scope; for(std::list >::iterator iter=local_scope.begin();iter!=local_scope.end();++iter) for(std::map::iterator i=iter->begin();i!=iter->end();++i) nasal_gc.reference_add(i->second); return; } +bool nasal_function::get_closure_update_state() +{ + return closure_updated; +} +void nasal_function::set_closure_update_state(bool _state) +{ + closure_updated=_state; + return; +} void nasal_function::set_paramemter_list(abstract_syntax_tree& para_list) { parameter_list=para_list; diff --git a/version2.0/nasal_runtime.h b/version2.0/nasal_runtime.h index 730d735..6861a09 100644 --- a/version2.0/nasal_runtime.h +++ b/version2.0/nasal_runtime.h @@ -100,6 +100,7 @@ class nasal_runtime int vector_generation (std::list >&,abstract_syntax_tree&);//checked int hash_generation (std::list >&,abstract_syntax_tree&);// checked int function_generation(std::list >&,abstract_syntax_tree&);// checked + void update_closure (std::list >&); bool check_condition (std::list >&,abstract_syntax_tree&);// checked int calculation (std::list >&,abstract_syntax_tree&);// checked int assignment (std::list >&,abstract_syntax_tree&,int); @@ -1463,6 +1464,7 @@ int nasal_runtime::function_generation(std::list >& lo int addr=nasal_gc.gc_alloc(); nasal_gc.get_scalar(addr).set_type(scalar_function); nasal_gc.get_scalar(addr).get_function().set_local_scope(local_scope); + nasal_gc.get_scalar(addr).get_function().set_closure_update_state(false); std::list::iterator i=node.get_children().begin(); nasal_gc.get_scalar(addr).get_function().set_paramemter_list(*i); @@ -2054,6 +2056,20 @@ int nasal_runtime::function_generation(std::list >& lo } return addr; } +void nasal_runtime::update_closure(std::list >& local_scope) +{ + // update_closure + if(!local_scope.size()) + return; + for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) + if(nasal_gc.get_scalar(i->second).get_type()==scalar_function && + !nasal_gc.get_scalar(i->second).get_function().get_closure_update_state()) + { + nasal_gc.get_scalar(i->second).get_function().set_local_scope(local_scope); + nasal_gc.get_scalar(i->second).get_function().set_closure_update_state(true); + } + return; +} bool nasal_runtime::check_condition(std::list >& local_scope,abstract_syntax_tree& node) { bool ret=false; @@ -4403,11 +4419,13 @@ int nasal_runtime::block_proc(std::list >& local_scope if(state==__state_break || state==__state_continue || state==__state_return || state==__state_error) break; } + // update_closure + update_closure(local_scope); return state; } int nasal_runtime::func_proc( std::list >& parameters_assist_scope,// scope that used to generate parameters - std::list > local_scope,// running scope,often gets the scope that calls it + std::list > local_scope, // running scope,often gets the scope that calls it abstract_syntax_tree& parameter_list, // parameter list format of nasal function abstract_syntax_tree& func_root, // main runnning block of nasal function abstract_syntax_tree& input_parameters, // input parameters when calling this nasal function @@ -4596,6 +4614,8 @@ int nasal_runtime::func_proc( function_returned_addr=nasal_gc.gc_alloc(); nasal_gc.get_scalar(function_returned_addr).set_type(scalar_nil); } + // update closure + update_closure(local_scope); for(std::map::iterator i=local_scope.back().begin();i!=local_scope.back().end();++i) nasal_gc.reference_delete(i->second); local_scope.pop_back();