update
This commit is contained in:
parent
9f30440286
commit
fed1e20085
|
@ -95,7 +95,6 @@ public:
|
||||||
~nasal_bytecode_vm();
|
~nasal_bytecode_vm();
|
||||||
void clear();
|
void clear();
|
||||||
void run(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
void run(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
||||||
void nas_switch_threading(std::vector<std::string>&,std::vector<double>&,std::vector<opcode>&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nasal_bytecode_vm::nasal_bytecode_vm()
|
nasal_bytecode_vm::nasal_bytecode_vm()
|
||||||
|
@ -729,17 +728,24 @@ void nasal_bytecode_vm::opr_call()
|
||||||
{
|
{
|
||||||
int val_addr=-1;
|
int val_addr=-1;
|
||||||
int name_index=exec_code[ptr].index;
|
int name_index=exec_code[ptr].index;
|
||||||
if(local_scope_stack.top()>=0)
|
int local_scope_top=local_scope_stack.top();
|
||||||
val_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_value_address(name_index);
|
if(local_scope_top>=0)
|
||||||
if(val_addr<0)
|
val_addr=vm.gc_get(local_scope_top).get_closure().get_value_address(name_index);
|
||||||
val_addr=vm.gc_get(global_scope_addr).get_closure().get_value_address(name_index);
|
if(val_addr>=0)
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
vm.add_reference(val_addr);
|
else
|
||||||
*(++value_stack_top)=val_addr;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_callv()
|
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 num=vm.gc_get(val_addr).to_number();
|
||||||
int res=vm.gc_get(vec_addr).get_vector().get_value_address(num);
|
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");
|
die("callv: index out of range");
|
||||||
return;
|
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)
|
else if(type==vm_hash)
|
||||||
{
|
{
|
||||||
|
@ -794,6 +789,20 @@ void nasal_bytecode_vm::opr_callv()
|
||||||
vm.add_reference(res);
|
vm.add_reference(res);
|
||||||
*(++value_stack_top)=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(val_addr);
|
||||||
vm.del_reference(vec_addr);
|
vm.del_reference(vec_addr);
|
||||||
return;
|
return;
|
||||||
|
@ -825,12 +834,13 @@ void nasal_bytecode_vm::opr_callh()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int res=vm.gc_get(val_addr).get_hash().get_value_address(string_table[exec_code[ptr].index]);
|
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");
|
die("callh: hash member \""+string_table[exec_code[ptr].index]+"\" does not exist");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vm.add_reference(res);
|
|
||||||
if(vm.gc_get(res).get_type()==vm_function)
|
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);
|
vm.gc_get(vm.gc_get(res).get_func().get_closure_addr()).get_closure().add_new_value(me_index,val_addr);
|
||||||
else
|
else
|
||||||
|
@ -931,8 +941,9 @@ void nasal_bytecode_vm::opr_builtincall()
|
||||||
void nasal_bytecode_vm::opr_slicebegin()
|
void nasal_bytecode_vm::opr_slicebegin()
|
||||||
{
|
{
|
||||||
slice_stack.push(vm.gc_alloc(vm_vector));
|
slice_stack.push(vm.gc_alloc(vm_vector));
|
||||||
if(vm.gc_get(*value_stack_top).get_type()!=vm_vector)
|
if(vm.gc_get(*value_stack_top).get_type()==vm_vector)
|
||||||
die("slcbegin: must slice a vector");
|
return;
|
||||||
|
die("slcbegin: must slice a vector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_sliceend()
|
void nasal_bytecode_vm::opr_sliceend()
|
||||||
|
@ -954,14 +965,14 @@ void nasal_bytecode_vm::opr_slice()
|
||||||
default:die("slc: error value type");break;
|
default:die("slc: error value type");break;
|
||||||
}
|
}
|
||||||
int res=vm.gc_get(*value_stack_top).get_vector().get_value_address((int)num);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
vm.add_reference(res);
|
die("slc: index out of range");
|
||||||
vm.gc_get(slice_stack.top()).get_vector().add_elem(res);
|
|
||||||
vm.del_reference(val_addr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_slice2()
|
void nasal_bytecode_vm::opr_slice2()
|
||||||
|
@ -1023,13 +1034,22 @@ void nasal_bytecode_vm::opr_mcall()
|
||||||
{
|
{
|
||||||
int* mem_addr=NULL;
|
int* mem_addr=NULL;
|
||||||
int name_index=exec_code[ptr].index;
|
int name_index=exec_code[ptr].index;
|
||||||
if(local_scope_stack.top()>=0)
|
int local_scope_top=local_scope_stack.top();
|
||||||
mem_addr=vm.gc_get(local_scope_stack.top()).get_closure().get_mem_address(name_index);
|
if(local_scope_top>=0)
|
||||||
if(!mem_addr)
|
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);
|
mem_addr=vm.gc_get(global_scope_addr).get_closure().get_mem_address(name_index);
|
||||||
if(!mem_addr)
|
if(mem_addr)
|
||||||
die("mcall: cannot find symbol named \""+string_table[name_index]+"\"");
|
{
|
||||||
pointer_stack.push(mem_addr);
|
pointer_stack.push(mem_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
die("mcall: cannot find symbol named \""+string_table[name_index]+"\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_bytecode_vm::opr_mcallv()
|
void nasal_bytecode_vm::opr_mcallv()
|
||||||
|
@ -1038,11 +1058,6 @@ void nasal_bytecode_vm::opr_mcallv()
|
||||||
int* vec_addr=pointer_stack.top();
|
int* vec_addr=pointer_stack.top();
|
||||||
pointer_stack.pop();
|
pointer_stack.pop();
|
||||||
int type=vm.gc_get(*vec_addr).get_type();
|
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)
|
if(type==vm_vector)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
|
@ -1077,6 +1092,11 @@ void nasal_bytecode_vm::opr_mcallv()
|
||||||
}
|
}
|
||||||
pointer_stack.push(res);
|
pointer_stack.push(res);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
die("mcallv: cannot get memory space in a string");
|
||||||
|
return;
|
||||||
|
}
|
||||||
vm.del_reference(val_addr);
|
vm.del_reference(val_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
48
nasal_gc.h
48
nasal_gc.h
|
@ -114,8 +114,8 @@ protected:
|
||||||
nasal_function* func;
|
nasal_function* func;
|
||||||
nasal_closure* cls;
|
nasal_closure* cls;
|
||||||
}ptr;
|
}ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int ref_cnt;
|
||||||
nasal_scalar();
|
nasal_scalar();
|
||||||
~nasal_scalar();
|
~nasal_scalar();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -135,20 +135,10 @@ public:
|
||||||
|
|
||||||
class nasal_virtual_machine
|
class nasal_virtual_machine
|
||||||
{
|
{
|
||||||
struct gc_unit
|
|
||||||
{
|
|
||||||
int ref_cnt;
|
|
||||||
nasal_scalar elem;
|
|
||||||
gc_unit()
|
|
||||||
{
|
|
||||||
ref_cnt=0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private:
|
private:
|
||||||
nasal_scalar error_returned_value;
|
nasal_scalar error_returned_value;
|
||||||
std::queue<int> garbage_collector_free_space;
|
std::queue<int> garbage_collector_free_space;
|
||||||
std::vector<gc_unit*> garbage_collector_memory;
|
std::vector<nasal_scalar*> garbage_collector_memory;
|
||||||
public:
|
public:
|
||||||
~nasal_virtual_machine();
|
~nasal_virtual_machine();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -646,10 +636,7 @@ nasal_virtual_machine::~nasal_virtual_machine()
|
||||||
int gc_mem_size=garbage_collector_memory.size();
|
int gc_mem_size=garbage_collector_memory.size();
|
||||||
for(int i=0;i<gc_mem_size;++i)
|
for(int i=0;i<gc_mem_size;++i)
|
||||||
if(garbage_collector_memory[i]->ref_cnt)
|
if(garbage_collector_memory[i]->ref_cnt)
|
||||||
{
|
garbage_collector_memory[i]->clear();
|
||||||
garbage_collector_memory[i]->ref_cnt=0;
|
|
||||||
garbage_collector_memory[i]->elem.clear();
|
|
||||||
}
|
|
||||||
for(int i=0;i<gc_mem_size;++i)
|
for(int i=0;i<gc_mem_size;++i)
|
||||||
delete garbage_collector_memory[i];
|
delete garbage_collector_memory[i];
|
||||||
while(!garbage_collector_free_space.empty())
|
while(!garbage_collector_free_space.empty())
|
||||||
|
@ -664,11 +651,11 @@ void nasal_virtual_machine::debug()
|
||||||
if(garbage_collector_memory[i]->ref_cnt)
|
if(garbage_collector_memory[i]->ref_cnt)
|
||||||
{
|
{
|
||||||
std::cout<<">> [debug] "<<i<<": "<<garbage_collector_memory[i]->ref_cnt<<" ";
|
std::cout<<">> [debug] "<<i<<": "<<garbage_collector_memory[i]->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_nil:std::cout<<"nil";break;
|
||||||
case vm_number:std::cout<<"number "<<garbage_collector_memory[i]->elem.get_number();break;
|
case vm_number:std::cout<<"number "<<garbage_collector_memory[i]->get_number();break;
|
||||||
case vm_string:std::cout<<"string "<<garbage_collector_memory[i]->elem.get_string();break;
|
case vm_string:std::cout<<"string "<<garbage_collector_memory[i]->get_string();break;
|
||||||
case vm_vector:std::cout<<"vector";break;
|
case vm_vector:std::cout<<"vector";break;
|
||||||
case vm_hash:std::cout<<"hash";break;
|
case vm_hash:std::cout<<"hash";break;
|
||||||
case vm_function:std::cout<<"function";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();
|
int gc_mem_size=garbage_collector_memory.size();
|
||||||
for(int i=0;i<gc_mem_size;++i)
|
for(int i=0;i<gc_mem_size;++i)
|
||||||
if(garbage_collector_memory[i]->ref_cnt)
|
if(garbage_collector_memory[i]->ref_cnt)
|
||||||
{
|
garbage_collector_memory[i]->clear();
|
||||||
garbage_collector_memory[i]->ref_cnt=0;
|
|
||||||
garbage_collector_memory[i]->elem.clear();
|
|
||||||
}
|
|
||||||
for(int i=0;i<gc_mem_size;++i)
|
for(int i=0;i<gc_mem_size;++i)
|
||||||
delete garbage_collector_memory[i];
|
delete garbage_collector_memory[i];
|
||||||
while(!garbage_collector_free_space.empty())
|
while(!garbage_collector_free_space.empty())
|
||||||
|
@ -699,41 +683,41 @@ int nasal_virtual_machine::gc_alloc(int val_type)
|
||||||
if(garbage_collector_free_space.empty())
|
if(garbage_collector_free_space.empty())
|
||||||
{
|
{
|
||||||
int mem_size=garbage_collector_memory.size();
|
int mem_size=garbage_collector_memory.size();
|
||||||
gc_unit* new_unit=new gc_unit;
|
nasal_scalar* new_unit=new nasal_scalar;
|
||||||
garbage_collector_memory.push_back(new_unit);
|
garbage_collector_memory.push_back(new_unit);
|
||||||
int ret=mem_size;
|
int ret=mem_size;
|
||||||
new_unit->ref_cnt=1;
|
new_unit->ref_cnt=1;
|
||||||
new_unit->elem.set_type(val_type,*this);
|
new_unit->set_type(val_type,*this);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int ret=garbage_collector_free_space.front();
|
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.ref_cnt=1;
|
||||||
unit_ref.elem.set_type(val_type,*this);
|
unit_ref.set_type(val_type,*this);
|
||||||
garbage_collector_free_space.pop();
|
garbage_collector_free_space.pop();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
|
nasal_scalar& nasal_virtual_machine::gc_get(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address)
|
if(value_address>=0)
|
||||||
return garbage_collector_memory[value_address]->elem;
|
return *garbage_collector_memory[value_address];
|
||||||
return error_returned_value;
|
return error_returned_value;
|
||||||
}
|
}
|
||||||
void nasal_virtual_machine::add_reference(int value_address)
|
void nasal_virtual_machine::add_reference(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address)
|
if(value_address>=0)
|
||||||
++garbage_collector_memory[value_address]->ref_cnt;
|
++garbage_collector_memory[value_address]->ref_cnt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void nasal_virtual_machine::del_reference(int value_address)
|
void nasal_virtual_machine::del_reference(int value_address)
|
||||||
{
|
{
|
||||||
if(0<=value_address)
|
if(value_address>=0)
|
||||||
--garbage_collector_memory[value_address]->ref_cnt;
|
--garbage_collector_memory[value_address]->ref_cnt;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
if(!garbage_collector_memory[value_address]->ref_cnt)
|
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);
|
garbage_collector_free_space.push(value_address);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1061,10 +1061,7 @@ nasal_ast nasal_parse::unary()
|
||||||
if(node.get_children()[0].get_type()==ast_number)
|
if(node.get_children()[0].get_type()==ast_number)
|
||||||
{
|
{
|
||||||
double num=node.get_children()[0].get_num();
|
double num=node.get_children()[0].get_num();
|
||||||
if(node.get_type()==ast_unary_not)
|
num=(node.get_type()==ast_unary_not?(!num):-num);
|
||||||
num=(!num);
|
|
||||||
else
|
|
||||||
num=-num;
|
|
||||||
node.set_type(ast_number);
|
node.set_type(ast_number);
|
||||||
node.set_num(num);
|
node.set_num(num);
|
||||||
node.get_children().clear();
|
node.get_children().clear();
|
||||||
|
|
Loading…
Reference in New Issue