delete slice_stack

This commit is contained in:
ValKmjolnir 2021-07-07 14:46:46 +08:00
parent 57d6bcdc52
commit 590c595522
3 changed files with 45 additions and 43 deletions

View File

@ -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<nasal_val*>& 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;
}

View File

@ -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<nasal_val*> num_addrs; // reserved address for const vm_num
std::vector<nasal_val*> str_addrs; // reserved address for const vm_str
std::vector<nasal_val*> slice_stack; // slice stack for vec[val,val,val:val]
std::vector<nasal_val*> memory; // gc memory
std::queue <nasal_val*> free_list[vm_type_size]; // gc free list
std::list<std::vector<nasal_val*>> 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<vm_type_size;++i)
while(!free_list[i].empty())
free_list[i].pop();
//global.clear();
local.clear();
slice_stack.clear();
delete nil_addr;
delete one_addr;

View File

@ -10,6 +10,7 @@ private:
uint32_t pc; // program counter
std::stack<int> ret; // ptr stack stores address for function to return
std::stack<int> counter; // iterator stack for forindex/foreach
std::vector<double> num_table;// numbers used in process(const calculation)
std::vector<std::string> str_table;// symbols used in process
std::vector<uint32_t> 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()<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_leqc()
{
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_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<nasal_val*>& ref=stack_top[0]->ptr.vec->elems;
std::vector<nasal_val*>& aim=gc.slice_stack.back()->ptr.vec->elems;
std::vector<nasal_val*>& ref=stack_top[-1]->ptr.vec->elems;
std::vector<nasal_val*>& 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<opcode>& 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<opcode>& 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);