diff --git a/nasal_builtin.h b/nasal_builtin.h index 0d02e80..1510f32 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -2,12 +2,11 @@ #define __NASAL_BUILTIN_H__ /* builtin functions must be called inside a outer function like this: - var print=func(elements...) + var print=func(elems...) { - __builtin_std_cout(elements); - return nil; + return __builtin_print(elems); } - builtin function __builtin_std_cout is wrapped up by print + builtin function __builtin_print is wrapped up by print */ // declaration of builtin functions @@ -690,12 +689,12 @@ nasal_val* builtin_type(std::vector& local_scope,nasal_gc& gc) nasal_val* ret_addr=gc.gc_alloc(vm_str); switch(val_addr->type) { - case vm_nil: *ret_addr->ptr.str="nil"; break; - case vm_num: *ret_addr->ptr.str="number"; break; - case vm_str: *ret_addr->ptr.str="string"; break; - case vm_vec: *ret_addr->ptr.str="vector"; break; - case vm_hash: *ret_addr->ptr.str="hash"; break; - case vm_func: *ret_addr->ptr.str="function"; break; + case vm_nil: *ret_addr->ptr.str="nil"; break; + case vm_num: *ret_addr->ptr.str="num"; break; + case vm_str: *ret_addr->ptr.str="str"; break; + case vm_vec: *ret_addr->ptr.str="vec"; break; + case vm_hash: *ret_addr->ptr.str="hash"; break; + case vm_func: *ret_addr->ptr.str="func"; break; } return ret_addr; } diff --git a/nasal_gc.h b/nasal_gc.h index 8370cc9..11a7617 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -18,10 +18,10 @@ const int increment[vm_type_size]= { 0, // vm_nil,in fact it is not in use 65536,// vm_num - 256, // vm_str - 16, // vm_func + 512, // vm_str + 64, // vm_func 2048, // vm_vec - 8 // vm_hash + 512 // vm_hash }; struct nasal_val;//declaration of nasal_val @@ -63,7 +63,7 @@ struct nasal_val// 16 bytes #define GC_COLLECTED 1 #define GC_FOUND 2 uint8_t mark; - uint16_t type; + uint8_t type; union { double num; @@ -234,7 +234,7 @@ std::string nasal_val::to_string() struct nasal_gc { -#define STACK_MAX_DEPTH (4096) +#define STACK_MAX_DEPTH (4080) nasal_val* zero_addr; // reserved address of nasal_val,type vm_num, 0 nasal_val* one_addr; // reserved address of nasal_val,type vm_num, 1 nasal_val* nil_addr; // reserved address of nasal_val,type vm_nil @@ -242,7 +242,6 @@ struct nasal_gc nasal_val** stack_top; // stack top std::vector num_addrs; // reserved address for const vm_num std::vector str_addrs; // reserved address for const vm_str - std::vector slice_stack; // slice stack for vec[val,val,val:val] std::vector memory; // gc memory std::queue free_list[vm_type_size]; // gc free list std::list> local; @@ -261,8 +260,6 @@ void nasal_gc::mark() for(auto& i:local) for(auto j:i) bfs.push(j); - for(auto i:slice_stack) - bfs.push(i); for(nasal_val** i=val_stack;i<=stack_top;++i) bfs.push(*i); while(!bfs.empty()) @@ -357,9 +354,7 @@ void nasal_gc::gc_clear() for(int i=0;i ret; // ptr stack stores address for function to return std::stack counter; // iterator stack for forindex/foreach + std::vector num_table;// numbers used in process(const calculation) std::vector str_table;// symbols used in process std::vector imm; // immediate number nasal_val** mem_addr; // used for mem_call @@ -107,6 +108,7 @@ void nasal_vm::init( { gc.gc_init(nums,strs); gc.val_stack[STACK_MAX_DEPTH-1]=nullptr; + num_table=nums; // get constant numbers str_table=strs; // get constant strings & symbols return; } @@ -117,6 +119,7 @@ void nasal_vm::clear() ret.pop(); while(!counter.empty()) counter.pop(); + num_table.clear(); str_table.clear(); imm.clear(); return; @@ -315,28 +318,28 @@ inline void nasal_vm::opr_lnk() inline void nasal_vm::opr_addc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=stack_top[0]->to_number()+gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=stack_top[0]->to_number()+num_table[imm[pc]]; stack_top[0]=new_val; return; } inline void nasal_vm::opr_subc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=stack_top[0]->to_number()-gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=stack_top[0]->to_number()-num_table[imm[pc]]; stack_top[0]=new_val; return; } inline void nasal_vm::opr_mulc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=stack_top[0]->to_number()*gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=stack_top[0]->to_number()*num_table[imm[pc]]; stack_top[0]=new_val; return; } inline void nasal_vm::opr_divc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=stack_top[0]->to_number()/gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=stack_top[0]->to_number()/num_table[imm[pc]]; stack_top[0]=new_val; return; } @@ -385,28 +388,28 @@ inline void nasal_vm::opr_lnkeq() inline void nasal_vm::opr_addeqc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=mem_addr[0]->to_number()+gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=mem_addr[0]->to_number()+num_table[imm[pc]]; stack_top[0]=mem_addr[0]=new_val; return; } inline void nasal_vm::opr_subeqc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=mem_addr[0]->to_number()-gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=mem_addr[0]->to_number()-num_table[imm[pc]]; stack_top[0]=mem_addr[0]=new_val; return; } inline void nasal_vm::opr_muleqc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=mem_addr[0]->to_number()*gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=mem_addr[0]->to_number()*num_table[imm[pc]]; stack_top[0]=mem_addr[0]=new_val; return; } inline void nasal_vm::opr_diveqc() { nasal_val* new_val=gc.gc_alloc(vm_num); - new_val->ptr.num=mem_addr[0]->to_number()/gc.num_addrs[imm[pc]]->ptr.num; + new_val->ptr.num=mem_addr[0]->to_number()/num_table[imm[pc]]; stack_top[0]=mem_addr[0]=new_val; return; } @@ -480,22 +483,22 @@ inline void nasal_vm::opr_geq() } inline void nasal_vm::opr_lessc() { - stack_top[0]=(stack_top[0]->to_number()ptr.num)?gc.one_addr:gc.zero_addr; + stack_top[0]=(stack_top[0]->to_number()to_number()<=gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + stack_top[0]=(stack_top[0]->to_number()<=num_table[imm[pc]])?gc.one_addr:gc.zero_addr; return; } inline void nasal_vm::opr_grtc() { - stack_top[0]=(stack_top[0]->to_number()>gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + stack_top[0]=(stack_top[0]->to_number()>num_table[imm[pc]])?gc.one_addr:gc.zero_addr; return; } inline void nasal_vm::opr_geqc() { - stack_top[0]=(stack_top[0]->to_number()>=gc.num_addrs[imm[pc]]->ptr.num)?gc.one_addr:gc.zero_addr; + stack_top[0]=(stack_top[0]->to_number()>=num_table[imm[pc]])?gc.one_addr:gc.zero_addr; return; } inline void nasal_vm::opr_pop() @@ -734,32 +737,36 @@ inline void nasal_vm::opr_callb() } inline void nasal_vm::opr_slcbegin() { - gc.slice_stack.push_back(gc.gc_alloc(vm_vec)); - if(stack_top[0]->type!=vm_vec) + // | slice_vector | <-- stack_top[0] + // ---------------- + // | resource_vec | <-- stack_top[-1] + // ---------------- + (++stack_top)[0]=gc.gc_alloc(vm_vec); + if(stack_top[-1]->type!=vm_vec) die("slcbegin: must slice a vector"); return; } inline void nasal_vm::opr_slcend() { - stack_top[0]=gc.slice_stack.back(); - gc.slice_stack.pop_back(); + stack_top[-1]=stack_top[0]; + --stack_top; return; } inline void nasal_vm::opr_slc() { nasal_val* val=(stack_top--)[0]; - nasal_val* res=stack_top[0]->ptr.vec->get_val(val->to_number()); + nasal_val* res=stack_top[-1]->ptr.vec->get_val(val->to_number()); if(!res) die("slc: index out of range:"+num2str(val->to_number())); - gc.slice_stack.back()->ptr.vec->elems.push_back(res); + stack_top[0]->ptr.vec->elems.push_back(res); return; } inline void nasal_vm::opr_slc2() { nasal_val* val2=(stack_top--)[0]; nasal_val* val1=(stack_top--)[0]; - std::vector& ref=stack_top[0]->ptr.vec->elems; - std::vector& aim=gc.slice_stack.back()->ptr.vec->elems; + std::vector& ref=stack_top[-1]->ptr.vec->elems; + std::vector& aim=stack_top[0]->ptr.vec->elems; int type1=val1->type,type2=val2->type; int num1=val1->to_number(); @@ -865,7 +872,7 @@ inline void nasal_vm::opr_ret() } void nasal_vm::run(std::vector& exec) { - // int count[op_ret]={0}; + // int count[op_ret+1]={0}; void* opr_table[]= { &&nop, &&intg, &&intl, &&offset, @@ -895,12 +902,13 @@ void nasal_vm::run(std::vector& exec) imm.push_back(i.num); } + nasal_val** canary=gc.val_stack+STACK_MAX_DEPTH-1; clock_t begin=clock(); pc=0; goto *code[pc]; nop: - if(gc.val_stack[STACK_MAX_DEPTH-1]&&gc.val_stack[STACK_MAX_DEPTH-1]!=(nasal_val*)0xffff) + if(canary[0] && canary[0]!=(nasal_val*)0xffff) std::cout<<">> [vm] stack overflow.\n"; std::cout<<">> [vm] process exited after "<<((double)(clock()-begin))/CLOCKS_PER_SEC<<"s.\n"; // debug @@ -917,7 +925,7 @@ nop: // count[index]=0; // } return; -#define exec_operand(op,num) {op();/*++count[num];*/if(!gc.val_stack[STACK_MAX_DEPTH-1])goto *code[++pc];goto nop;} +#define exec_operand(op,num) {op();/*++count[num];*/if(!canary[0])goto *code[++pc];goto nop;} intg: exec_operand(opr_intg ,1); intl: exec_operand(opr_intl ,2); offset: exec_operand(opr_offset ,3);