From 7c026b62b7b690ed8c1f47fcbdebe61570c5c028 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Tue, 15 Dec 2020 13:00:24 +0800 Subject: [PATCH] update --- nasal_bytecode_vm.h | 117 +++++++++++++++++++----------------- nasal_gc.h | 143 ++++++++++++-------------------------------- nasal_parse.h | 10 ++++ nasal_runtime.h | 134 +++++++++++++++++++++++++---------------- 4 files changed, 190 insertions(+), 214 deletions(-) diff --git a/nasal_bytecode_vm.h b/nasal_bytecode_vm.h index 35771a8..7f79af3 100644 --- a/nasal_bytecode_vm.h +++ b/nasal_bytecode_vm.h @@ -13,6 +13,8 @@ private: std::vector exec_code; // main calculation stack std::stack value_stack; + // stack for mem_call + std::stack pointer_stack; // local scope for function block std::stack local_scope_stack; // slice stack for vec[val,val,val:val] @@ -104,6 +106,7 @@ void nasal_bytecode_vm::clear() vm.clear(); global_scope_addr=-1; while(!value_stack.empty())value_stack.pop(); + while(!pointer_stack.empty())pointer_stack.pop(); while(!local_scope_stack.empty())local_scope_stack.pop(); local_scope_stack.push(-1); while(!slice_stack.empty())slice_stack.pop(); @@ -116,15 +119,7 @@ void nasal_bytecode_vm::clear() } void nasal_bytecode_vm::die(std::string str) { - std::string numinfo=""; - int num=ptr; - for(int i=0;i<8;++i) - { - int tmp=num&0x0f; - numinfo=(char)(tmp>9? 'a'+tmp-10:'0'+tmp)+numinfo; - num>>=4; - } - std::cout<<">> [vm] 0x"<> [vm] 0x%.8x: %s\n",ptr,str.data()); main_loop_break_mark=false; return; } @@ -450,11 +445,11 @@ void nasal_bytecode_vm::opr_lnk() } void nasal_bytecode_vm::opr_addeq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr2=value_stack.top(); value_stack.pop(); - int val_addr1=vm.mem_get(mem_addr); + int val_addr1=*mem_addr; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -474,17 +469,18 @@ void nasal_bytecode_vm::opr_addeq() vm.gc_get(new_value_address).set_number(a_num+b_num); vm.add_reference(new_value_address); value_stack.push(new_value_address); - vm.mem_change(mem_addr,new_value_address); + vm.del_reference(*mem_addr); + *mem_addr=new_value_address; vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_subeq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr2=value_stack.top(); value_stack.pop(); - int val_addr1=vm.mem_get(mem_addr); + int val_addr1=*mem_addr; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -504,17 +500,18 @@ void nasal_bytecode_vm::opr_subeq() vm.gc_get(new_value_address).set_number(a_num-b_num); vm.add_reference(new_value_address); value_stack.push(new_value_address); - vm.mem_change(mem_addr,new_value_address); + vm.del_reference(*mem_addr); + *mem_addr=new_value_address; vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_muleq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr2=value_stack.top(); value_stack.pop(); - int val_addr1=vm.mem_get(mem_addr); + int val_addr1=*mem_addr; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -534,17 +531,18 @@ void nasal_bytecode_vm::opr_muleq() vm.gc_get(new_value_address).set_number(a_num*b_num); vm.add_reference(new_value_address); value_stack.push(new_value_address); - vm.mem_change(mem_addr,new_value_address); + vm.del_reference(*mem_addr); + *mem_addr=new_value_address; vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_diveq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr2=value_stack.top(); value_stack.pop(); - int val_addr1=vm.mem_get(mem_addr); + int val_addr1=*mem_addr; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -564,17 +562,18 @@ void nasal_bytecode_vm::opr_diveq() vm.gc_get(new_value_address).set_number(a_num/b_num); vm.add_reference(new_value_address); value_stack.push(new_value_address); - vm.mem_change(mem_addr,new_value_address); + vm.del_reference(*mem_addr); + *mem_addr=new_value_address; vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_lnkeq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr2=value_stack.top(); value_stack.pop(); - int val_addr1=vm.mem_get(mem_addr); + int val_addr1=*mem_addr; nasal_scalar& a_ref=vm.gc_get(val_addr1); nasal_scalar& b_ref=vm.gc_get(val_addr2); int a_ref_type=a_ref.get_type(); @@ -590,17 +589,19 @@ void nasal_bytecode_vm::opr_lnkeq() vm.gc_get(new_value_address).set_string(a_str+b_str); vm.add_reference(new_value_address); value_stack.push(new_value_address); - vm.mem_change(mem_addr,new_value_address); + vm.del_reference(*mem_addr); + *mem_addr=new_value_address; vm.del_reference(val_addr2); return; } void nasal_bytecode_vm::opr_meq() { - int mem_addr=value_stack.top(); - value_stack.pop(); + int* mem_addr=pointer_stack.top(); + pointer_stack.pop(); int val_addr=value_stack.top(); vm.add_reference(val_addr); - vm.mem_change(mem_addr,val_addr); + vm.del_reference(*mem_addr); + *mem_addr=val_addr; return; } void nasal_bytecode_vm::opr_eq() @@ -1284,23 +1285,23 @@ void nasal_bytecode_vm::opr_slice2() } void nasal_bytecode_vm::opr_mcall() { - int mem_addr=-1; + int* mem_addr=NULL; if(local_scope_stack.top()>=0) mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(string_table[exec_code[ptr].index]); - if(mem_addr<0) + if(!mem_addr) mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(string_table[exec_code[ptr].index]); - if(mem_addr<0) + if(!mem_addr) die("mcall: cannot find symbol named \""+string_table[exec_code[ptr].index]+"\""); - value_stack.push(mem_addr); + pointer_stack.push(mem_addr); return; } void nasal_bytecode_vm::opr_mcallv() { int val_addr=value_stack.top(); value_stack.pop(); - int vec_addr=vm.mem_get(value_stack.top()); - value_stack.pop(); - int type=vm.gc_get(vec_addr).get_type(); + int* vec_addr=pointer_stack.top(); + pointer_stack.pop(); + int type=vm.gc_get(*vec_addr).get_type(); if(type==vm_string) { die("mcallv: cannot get memory space in a string"); @@ -1315,13 +1316,13 @@ void nasal_bytecode_vm::opr_mcallv() case vm_string:num=(int)trans_string_to_number(vm.gc_get(val_addr).get_string());break; default:die("mcallv: error value type");break; } - int res=vm.gc_get(vec_addr).get_vector().get_mem_address(num); - if(res<0) + int* res=vm.gc_get(*vec_addr).get_vector().get_mem_address(num); + if(!res) { die("mcallv: index out of range"); return; } - value_stack.push(res); + pointer_stack.push(res); } else if(type==vm_hash) { @@ -1330,34 +1331,38 @@ void nasal_bytecode_vm::opr_mcallv() die("mcallv: must use string as the key"); return; } - int res=vm.gc_get(vec_addr).get_hash().get_mem_address(vm.gc_get(val_addr).get_string()); - if(res<0) + nasal_hash& ref=vm.gc_get(*vec_addr).get_hash(); + std::string str=vm.gc_get(val_addr).get_string(); + int* res=ref.get_mem_address(str); + if(!res) { - die("mcallv: cannot find member \""+vm.gc_get(val_addr).get_string()+"\" of this hash"); - return; + ref.add_elem(str,vm.gc_alloc(vm_nil)); + res=ref.get_mem_address(str); } - value_stack.push(res); + pointer_stack.push(res); } vm.del_reference(val_addr); return; } void nasal_bytecode_vm::opr_mcallh() { - int mem_addr=-1; - int hash_addr=vm.mem_get(value_stack.top()); - value_stack.pop(); - if(vm.gc_get(hash_addr).get_type()!=vm_hash) + int* mem_addr=NULL; + int* hash_addr=pointer_stack.top(); + pointer_stack.pop(); + if(vm.gc_get(*hash_addr).get_type()!=vm_hash) { die("mcallh: must call a hash"); return; } - mem_addr=vm.gc_get(hash_addr).get_hash().get_mem_address(string_table[exec_code[ptr].index]); - if(mem_addr<0) + nasal_hash& ref=vm.gc_get(*hash_addr).get_hash(); + std::string str=string_table[exec_code[ptr].index]; + mem_addr=ref.get_mem_address(str); + if(!mem_addr) { - die("mcallh: cannot get memory space in this hash"); - return; + ref.add_elem(str,vm.gc_alloc(vm_nil)); + mem_addr=ref.get_mem_address(str); } - value_stack.push(mem_addr); + pointer_stack.push(mem_addr); return; } void nasal_bytecode_vm::opr_return() diff --git a/nasal_gc.h b/nasal_gc.h index a4de021..50c094f 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -35,7 +35,7 @@ public: int del_elem(); int size(); int get_value_address(int); - int get_mem_address(int); + int* get_mem_address(int); void print(); }; @@ -53,7 +53,7 @@ public: int size(); int get_special_para(std::string); int get_value_address(std::string); - int get_mem_address(std::string); + int* get_mem_address(std::string); bool check_contain(std::string); int get_keys(); void print(); @@ -62,7 +62,6 @@ public: class nasal_function { private: - // this int points to the space in nasal_vm::garbage_collector_memory nasal_virtual_machine& vm; int entry; int closure_addr; @@ -103,7 +102,7 @@ public: void del_scope(); void add_new_value(std::string,int); int get_value_address(std::string); - int get_mem_address(std::string); + int* get_mem_address(std::string); void set_closure(nasal_closure&); }; @@ -146,8 +145,6 @@ private: nasal_scalar error_returned_value; std::queue garbage_collector_free_space; std::vector garbage_collector_memory; - std::queue memory_manager_free_space; - std::vector memory_manager_memory; public: nasal_virtual_machine(); ~nasal_virtual_machine(); @@ -157,10 +154,6 @@ public: nasal_scalar& gc_get(int); // get scalar that stored in gc void add_reference(int); void del_reference(int); - int mem_alloc(int); // memory gives a new space - void mem_free(int); // give space back to memory - void mem_change(int,int); // change value in memory space - int mem_get(int); // get value in memory space }; /*functions of nasal_vector*/ @@ -172,14 +165,13 @@ nasal_vector::~nasal_vector() { int size=elems.size(); for(int i=0;i> [runtime] nasal_vector::get_value_address: index out of range: "<right_range) { std::cout<<">> [runtime] nasal_vector::get_mem_address: index out of range: "<::iterator iter=elems.begin();iter!=elems.end();++iter) - vm.mem_free(iter->second); + vm.del_reference(iter->second); elems.clear(); return; } void nasal_hash::add_elem(std::string key,int value_address) { if(elems.find(key)==elems.end()) - { - int memory_address=vm.mem_alloc(value_address); - elems[key]=memory_address; - } + elems[key]=value_address; return; } void nasal_hash::del_elem(std::string key) { if(elems.find(key)!=elems.end()) { - vm.mem_free(elems[key]); + vm.del_reference(elems[key]); elems.erase(key); } return; @@ -281,18 +268,17 @@ int nasal_hash::size() int nasal_hash::get_special_para(std::string key) { if(elems.find(key)!=elems.end()) - return vm.mem_get(elems[key]); + return elems[key]; return -1; } int nasal_hash::get_value_address(std::string key) { int ret_value_addr=-1; if(elems.find(key)!=elems.end()) - return vm.mem_get(elems[key]); + return elems[key]; else if(elems.find("parents")!=elems.end()) { - int mem_addr=elems["parents"]; - int val_addr=vm.mem_get(mem_addr); + int val_addr=elems["parents"]; if(vm.gc_get(val_addr).get_type()==vm_vector) { nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector(); @@ -309,15 +295,14 @@ int nasal_hash::get_value_address(std::string key) } return ret_value_addr; } -int nasal_hash::get_mem_address(std::string key) +int* nasal_hash::get_mem_address(std::string key) { - int ret_mem_addr=-1; + int* mem_addr=NULL; if(elems.find(key)!=elems.end()) - return elems[key]; + return &elems[key]; else if(elems.find("parents")!=elems.end()) { - int mem_addr=elems["parents"]; - int val_addr=vm.mem_get(mem_addr); + int val_addr=elems["parents"]; if(vm.gc_get(val_addr).get_type()==vm_vector) { nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector(); @@ -326,13 +311,13 @@ int nasal_hash::get_mem_address(std::string key) { int tmp_val_addr=vec_ref.get_value_address(i); if(vm.gc_get(tmp_val_addr).get_type()==vm_hash) - ret_mem_addr=vm.gc_get(tmp_val_addr).get_hash().get_mem_address(key); - if(ret_mem_addr>=0) + mem_addr=vm.gc_get(tmp_val_addr).get_hash().get_mem_address(key); + if(mem_addr>0) break; } } } - return ret_mem_addr; + return mem_addr; } bool nasal_hash::check_contain(std::string key) { @@ -341,8 +326,7 @@ bool nasal_hash::check_contain(std::string key) if(elems.find("parents")!=elems.end()) { bool result=false; - int mem_addr=elems["parents"]; - int val_addr=vm.mem_get(mem_addr); + int val_addr=elems["parents"]; if(vm.gc_get(val_addr).get_type()==vm_vector) { nasal_vector& vec_ref=vm.gc_get(val_addr).get_vector(); @@ -380,7 +364,7 @@ void nasal_hash::print() for(std::map::iterator i=elems.begin();i!=elems.end();++i) { std::cout<first<<":"; - nasal_scalar& tmp=vm.gc_get(vm.mem_get(i->second)); + nasal_scalar& tmp=vm.gc_get(i->second); switch(tmp.get_type()) { case vm_nil:std::cout<<"nil";break; @@ -491,7 +475,7 @@ nasal_closure::~nasal_closure() { for(std::list >::iterator i=elems.begin();i!=elems.end();++i) for(std::map::iterator j=i->begin();j!=i->end();++j) - vm.mem_free(j->second); + vm.del_reference(j->second); elems.clear(); return; } @@ -505,20 +489,19 @@ void nasal_closure::del_scope() { std::map& last_scope=elems.back(); for(std::map::iterator i=last_scope.begin();i!=last_scope.end();++i) - vm.mem_free(i->second); + vm.del_reference(i->second); elems.pop_back(); return; } void nasal_closure::add_new_value(std::string key,int value_address) { - int new_mem_address=vm.mem_alloc(value_address); if(elems.back().find(key)!=elems.back().end()) { // if this value already exists,delete the old value and update a new value - int old_mem_address=elems.back()[key]; - vm.mem_free(old_mem_address); + int old_val_address=elems.back()[key]; + vm.del_reference(old_val_address); } - elems.back()[key]=new_mem_address; + elems.back()[key]=value_address; return; } int nasal_closure::get_value_address(std::string key) @@ -526,22 +509,22 @@ int nasal_closure::get_value_address(std::string key) int ret_address=-1; for(std::list >::iterator i=elems.begin();i!=elems.end();++i) if(i->find(key)!=i->end()) - ret_address=vm.mem_get((*i)[key]); + ret_address=(*i)[key]; return ret_address; } -int nasal_closure::get_mem_address(std::string key) +int* nasal_closure::get_mem_address(std::string key) { - int ret_address=-1; + int* ret_address=NULL; for(std::list >::iterator i=elems.begin();i!=elems.end();++i) if(i->find(key)!=i->end()) - ret_address=(*i)[key]; + ret_address=&((*i)[key]); return ret_address; } 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) - vm.mem_free(j->second); + vm.del_reference(j->second); elems.clear(); for(std::list >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i) { @@ -549,10 +532,9 @@ void nasal_closure::set_closure(nasal_closure& tmp) elems.push_back(new_scope); for(std::map::iterator j=i->begin();j!=i->end();++j) { - int value_addr=vm.mem_get(j->second); - int new_mem_addr=vm.mem_alloc(value_addr); + int value_addr=j->second; vm.add_reference(value_addr); - elems.back()[j->first]=new_mem_addr; + elems.back()[j->first]=value_addr; } } return; @@ -687,10 +669,7 @@ nasal_virtual_machine::~nasal_virtual_machine() delete garbage_collector_memory[i]; while(!garbage_collector_free_space.empty()) garbage_collector_free_space.pop(); - while(!memory_manager_free_space.empty()) - memory_manager_free_space.pop(); garbage_collector_memory.clear(); - memory_manager_memory.clear(); return; } void nasal_virtual_machine::debug() @@ -728,10 +707,7 @@ void nasal_virtual_machine::clear() delete garbage_collector_memory[i]; while(!garbage_collector_free_space.empty()) garbage_collector_free_space.pop(); - while(!memory_manager_free_space.empty()) - memory_manager_free_space.pop(); garbage_collector_memory.clear(); - memory_manager_memory.clear(); return; } int nasal_virtual_machine::gc_alloc(int val_type) @@ -780,48 +756,5 @@ void nasal_virtual_machine::del_reference(int value_address) } return; } -int nasal_virtual_machine::mem_alloc(int value_address) -{ - if(memory_manager_free_space.empty()) - { - int mem_size=memory_manager_memory.size(); - memory_manager_memory.resize(mem_size+256); - for(int i=mem_size;idel_reference(memory_manager_memory[memory_address]); - memory_manager_free_space.push(memory_address); - } - return; -} -void nasal_virtual_machine::mem_change(int memory_address,int value_address) -{ - // this progress is used to change a memory space's value address - // be careful! this process doesn't check if this mem_space is in use. - if(0<=memory_address) - { - this->del_reference(memory_manager_memory[memory_address]); - memory_manager_memory[memory_address]=value_address; - } - return; -} -int nasal_virtual_machine::mem_get(int memory_address) -{ - // be careful! this process doesn't check if this mem_space is in use. - if(0<=memory_address) - return memory_manager_memory[memory_address]; - return -1; -} #endif \ No newline at end of file diff --git a/nasal_parse.h b/nasal_parse.h index ab1f376..60838d8 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -180,6 +180,15 @@ void nasal_parse::die(int line,std::string info) { ++error; std::cout<<">> [parse] line "<=tok_list_size || tok_list[ptr].type!=tok_colon) diff --git a/nasal_runtime.h b/nasal_runtime.h index 6e59daf..f694fd0 100644 --- a/nasal_runtime.h +++ b/nasal_runtime.h @@ -56,9 +56,9 @@ private: int call_function(nasal_ast&,int,int,int); int call_builtin_function(std::string,int); // get scalars' memory place in complex data structure like vector/hash/function/closure(scope) - int call_scalar_mem(nasal_ast&,int); - int call_vector_mem(nasal_ast&,int,int); - int call_hash_mem(nasal_ast&,int,int); + int* call_scalar_mem(nasal_ast&,int); + int* call_vector_mem(nasal_ast&,int*,int); + int* call_hash_mem(nasal_ast&,int*,int); // calculate scalars int nasal_scalar_add(int,int); int nasal_scalar_sub(int,int); @@ -337,7 +337,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr) return rt_error; } // begin loop progress - int mem_addr=-1; + int* mem_addr=NULL; if(iter_node.get_type()==ast_new_iter) { int new_value_addr=nasal_vm.gc_alloc(vm_nil); @@ -347,7 +347,7 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr) } else mem_addr=call_scalar_mem(iter_node,local_scope_addr); - if(mem_addr<0) + if(!mem_addr) { die(iter_node.get_line(),"get null iterator"); return rt_error; @@ -361,13 +361,15 @@ int nasal_runtime::loop_progress(nasal_ast& node,int local_scope_addr) { int new_iter_val_addr=nasal_vm.gc_alloc(vm_number); nasal_vm.gc_get(new_iter_val_addr).set_number((double)i); - nasal_vm.mem_change(mem_addr,new_iter_val_addr); + nasal_vm.del_reference(*mem_addr); + *mem_addr=new_iter_val_addr; } else { int value_addr=ref_vector.get_value_address(i); nasal_vm.add_reference(value_addr); - nasal_vm.mem_change(mem_addr,value_addr); + nasal_vm.del_reference(*mem_addr); + *mem_addr=value_addr; } ret_state=block_progress(run_block_node,local_scope_addr); if(ret_state==rt_break || ret_state==rt_return || error) @@ -923,37 +925,37 @@ int nasal_runtime::call_builtin_function(std::string val_name,int local_scope_ad } return ret_value_addr; } -int nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr) +int* nasal_runtime::call_scalar_mem(nasal_ast& node,int local_scope_addr) { - int mem_address=-1; + int* mem_address=NULL; if(node.get_type()==ast_identifier) { std::string id_name=node.get_str(); if(local_scope_addr>=0) mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name); - if(mem_address<0) + if(!mem_address) mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name); - if(mem_address<0) + if(!mem_address) { die(node.get_line(),"cannot find \""+id_name+"\""); - return -1; + return NULL; } return mem_address; } std::string id_name=node.get_children()[0].get_str(); if(local_scope_addr>=0) mem_address=nasal_vm.gc_get(local_scope_addr).get_closure().get_mem_address(id_name); - if(mem_address<0) + if(!mem_address) mem_address=nasal_vm.gc_get(global_scope_address).get_closure().get_mem_address(id_name); - if(mem_address<0) + if(!mem_address) { die(node.get_children()[0].get_line(),"cannot find \""+id_name+"\""); - return -1; + return NULL; } int call_expr_size=node.get_children().size(); for(int i=1;i mem_table; int id_size=multi_call_node.get_children().size(); - for(int i=0;i