From fed1e20085a86d7462a0faeb9d96e0a1f52659f5 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Sat, 19 Dec 2020 21:02:02 +0800 Subject: [PATCH] update --- nasal_bytecode_vm.h | 112 ++++++++++++++++++++++++++------------------ nasal_gc.h | 48 +++++++------------ nasal_parse.h | 5 +- 3 files changed, 83 insertions(+), 82 deletions(-) diff --git a/nasal_bytecode_vm.h b/nasal_bytecode_vm.h index fdd4f45..ca6b339 100644 --- a/nasal_bytecode_vm.h +++ b/nasal_bytecode_vm.h @@ -95,7 +95,6 @@ public: ~nasal_bytecode_vm(); void clear(); void run(std::vector&,std::vector&,std::vector&); - void nas_switch_threading(std::vector&,std::vector&,std::vector&); }; nasal_bytecode_vm::nasal_bytecode_vm() @@ -729,17 +728,24 @@ void nasal_bytecode_vm::opr_call() { int val_addr=-1; int name_index=exec_code[ptr].index; - if(local_scope_stack.top()>=0) - val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(name_index); - if(val_addr<0) - val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(name_index); - if(val_addr<0) + int local_scope_top=local_scope_stack.top(); + if(local_scope_top>=0) + val_addr=vm.gc_get(local_scope_top).get_closure().get_value_address(name_index); + if(val_addr>=0) { - die("call: cannot find symbol named \""+string_table[name_index]+"\""); + vm.add_reference(val_addr); + *(++value_stack_top)=val_addr; return; } - vm.add_reference(val_addr); - *(++value_stack_top)=val_addr; + else + val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(name_index); + if(val_addr>=0) + { + vm.add_reference(val_addr); + *(++value_stack_top)=val_addr; + return; + } + die("call: cannot find symbol named \""+string_table[name_index]+"\""); return; } void nasal_bytecode_vm::opr_callv() @@ -751,27 +757,16 @@ void nasal_bytecode_vm::opr_callv() { int num=vm.gc_get(val_addr).to_number(); int res=vm.gc_get(vec_addr).get_vector().get_value_address(num); - if(res<0) + if(res>=0) + { + vm.add_reference(res); + *(++value_stack_top)=res; + } + else { die("callv: index out of range"); return; } - vm.add_reference(res); - *(++value_stack_top)=res; - } - else if(type==vm_string) - { - std::string str=vm.gc_get(vec_addr).get_string(); - int num=vm.gc_get(val_addr).to_number(); - int str_size=str.length(); - if(num<-str_size || num>=str_size) - { - die("callv: index out of range"); - return; - } - int res=vm.gc_alloc(vm_number); - vm.gc_get(res).set_number((double)str[(num+str_size)%str_size]); - *(++value_stack_top)=res; } else if(type==vm_hash) { @@ -794,6 +789,20 @@ void nasal_bytecode_vm::opr_callv() vm.add_reference(res); *(++value_stack_top)=res; } + else if(type==vm_string) + { + std::string str=vm.gc_get(vec_addr).get_string(); + int num=vm.gc_get(val_addr).to_number(); + int str_size=str.length(); + if(num<-str_size || num>=str_size) + { + die("callv: index out of range"); + return; + } + int res=vm.gc_alloc(vm_number); + vm.gc_get(res).set_number((double)str[num>=0? num:num+str_size]); + *(++value_stack_top)=res; + } vm.del_reference(val_addr); vm.del_reference(vec_addr); return; @@ -825,12 +834,13 @@ void nasal_bytecode_vm::opr_callh() return; } int res=vm.gc_get(val_addr).get_hash().get_value_address(string_table[exec_code[ptr].index]); - if(res<0) + if(res>=0) + vm.add_reference(res); + else { die("callh: hash member \""+string_table[exec_code[ptr].index]+"\" does not exist"); return; } - vm.add_reference(res); if(vm.gc_get(res).get_type()==vm_function) vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value(me_index,val_addr); else @@ -931,8 +941,9 @@ void nasal_bytecode_vm::opr_builtincall() void nasal_bytecode_vm::opr_slicebegin() { slice_stack.push(vm.gc_alloc(vm_vector)); - if(vm.gc_get(*value_stack_top).get_type()!=vm_vector) - die("slcbegin: must slice a vector"); + if(vm.gc_get(*value_stack_top).get_type()==vm_vector) + return; + die("slcbegin: must slice a vector"); return; } void nasal_bytecode_vm::opr_sliceend() @@ -954,14 +965,14 @@ void nasal_bytecode_vm::opr_slice() default:die("slc: error value type");break; } int res=vm.gc_get(*value_stack_top).get_vector().get_value_address((int)num); - if(res<0) + if(res>=0) { - die("slc: index out of range"); + vm.add_reference(res); + vm.gc_get(slice_stack.top()).get_vector().add_elem(res); + vm.del_reference(val_addr); return; } - vm.add_reference(res); - vm.gc_get(slice_stack.top()).get_vector().add_elem(res); - vm.del_reference(val_addr); + die("slc: index out of range"); return; } void nasal_bytecode_vm::opr_slice2() @@ -1023,13 +1034,22 @@ void nasal_bytecode_vm::opr_mcall() { int* mem_addr=NULL; int name_index=exec_code[ptr].index; - if(local_scope_stack.top()>=0) - mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(name_index); - if(!mem_addr) + int local_scope_top=local_scope_stack.top(); + if(local_scope_top>=0) + mem_addr=vm.gc_get(local_scope_top).get_closure().get_mem_address(name_index); + if(mem_addr) + { + pointer_stack.push(mem_addr); + return; + } + else mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(name_index); - if(!mem_addr) - die("mcall: cannot find symbol named \""+string_table[name_index]+"\""); - pointer_stack.push(mem_addr); + if(mem_addr) + { + pointer_stack.push(mem_addr); + return; + } + die("mcall: cannot find symbol named \""+string_table[name_index]+"\""); return; } void nasal_bytecode_vm::opr_mcallv() @@ -1038,11 +1058,6 @@ void nasal_bytecode_vm::opr_mcallv() 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"); - return; - } if(type==vm_vector) { int num; @@ -1077,6 +1092,11 @@ void nasal_bytecode_vm::opr_mcallv() } pointer_stack.push(res); } + else + { + die("mcallv: cannot get memory space in a string"); + return; + } vm.del_reference(val_addr); return; } diff --git a/nasal_gc.h b/nasal_gc.h index b0435a9..ca5688a 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -114,8 +114,8 @@ protected: nasal_function* func; nasal_closure* cls; }ptr; - public: + int ref_cnt; nasal_scalar(); ~nasal_scalar(); void clear(); @@ -135,20 +135,10 @@ public: class nasal_virtual_machine { - struct gc_unit - { - int ref_cnt; - nasal_scalar elem; - gc_unit() - { - ref_cnt=0; - return; - } - }; private: nasal_scalar error_returned_value; std::queue garbage_collector_free_space; - std::vector garbage_collector_memory; + std::vector garbage_collector_memory; public: ~nasal_virtual_machine(); void clear(); @@ -646,10 +636,7 @@ nasal_virtual_machine::~nasal_virtual_machine() int gc_mem_size=garbage_collector_memory.size(); for(int i=0;iref_cnt) - { - garbage_collector_memory[i]->ref_cnt=0; - garbage_collector_memory[i]->elem.clear(); - } + garbage_collector_memory[i]->clear(); for(int i=0;iref_cnt) { std::cout<<">> [debug] "<ref_cnt<<" "; - switch(garbage_collector_memory[i]->elem.get_type()) + switch(garbage_collector_memory[i]->get_type()) { case vm_nil:std::cout<<"nil";break; - case vm_number:std::cout<<"number "<elem.get_number();break; - case vm_string:std::cout<<"string "<elem.get_string();break; + case vm_number:std::cout<<"number "<get_number();break; + case vm_string:std::cout<<"string "<get_string();break; case vm_vector:std::cout<<"vector";break; case vm_hash:std::cout<<"hash";break; case vm_function:std::cout<<"function";break; @@ -683,10 +670,7 @@ void nasal_virtual_machine::clear() int gc_mem_size=garbage_collector_memory.size(); for(int i=0;iref_cnt) - { - garbage_collector_memory[i]->ref_cnt=0; - garbage_collector_memory[i]->elem.clear(); - } + garbage_collector_memory[i]->clear(); for(int i=0;iref_cnt=1; - new_unit->elem.set_type(val_type,*this); + new_unit->set_type(val_type,*this); return ret; } int ret=garbage_collector_free_space.front(); - gc_unit& unit_ref=*garbage_collector_memory[ret]; + nasal_scalar& unit_ref=*garbage_collector_memory[ret]; unit_ref.ref_cnt=1; - unit_ref.elem.set_type(val_type,*this); + unit_ref.set_type(val_type,*this); garbage_collector_free_space.pop(); return ret; } nasal_scalar& nasal_virtual_machine::gc_get(int value_address) { - if(0<=value_address) - return garbage_collector_memory[value_address]->elem; + if(value_address>=0) + return *garbage_collector_memory[value_address]; return error_returned_value; } void nasal_virtual_machine::add_reference(int value_address) { - if(0<=value_address) + if(value_address>=0) ++garbage_collector_memory[value_address]->ref_cnt; return; } void nasal_virtual_machine::del_reference(int value_address) { - if(0<=value_address) + if(value_address>=0) --garbage_collector_memory[value_address]->ref_cnt; else return; if(!garbage_collector_memory[value_address]->ref_cnt) { - garbage_collector_memory[value_address]->elem.clear(); + garbage_collector_memory[value_address]->clear(); garbage_collector_free_space.push(value_address); } return; diff --git a/nasal_parse.h b/nasal_parse.h index 60838d8..95a5e74 100644 --- a/nasal_parse.h +++ b/nasal_parse.h @@ -1061,10 +1061,7 @@ nasal_ast nasal_parse::unary() if(node.get_children()[0].get_type()==ast_number) { double num=node.get_children()[0].get_num(); - if(node.get_type()==ast_unary_not) - num=(!num); - else - num=-num; + num=(node.get_type()==ast_unary_not?(!num):-num); node.set_type(ast_number); node.set_num(num); node.get_children().clear();