bug fixed & more efficient function call
fixed a bug when different hash calling the same function,'me' will be set to the latest called hash's address. changed the way of pushing the scope to the stack by copying a new scope from the function's scope address. use map as the nasal_scop instead of list<map>,it'll be more efficient.
This commit is contained in:
parent
767711c93a
commit
02148f4766
120
nasal_gc.h
120
nasal_gc.h
|
@ -82,12 +82,10 @@ class nasal_scop
|
|||
{
|
||||
private:
|
||||
nasal_gc& gc;
|
||||
std::list<std::map<int,nasal_val*> > elems;
|
||||
std::map<int,nasal_val*> elems;
|
||||
public:
|
||||
nasal_scop(nasal_gc&);
|
||||
~nasal_scop();
|
||||
void add_scope();
|
||||
void del_scope();
|
||||
void set_closure(nasal_scop&);
|
||||
void add_new_value(int,nasal_val*);
|
||||
nasal_val* get_value_address(int);
|
||||
|
@ -435,76 +433,44 @@ nasal_val* nasal_func::get_closure_addr()
|
|||
/*functions of nasal_scop*/
|
||||
nasal_scop::nasal_scop(nasal_gc& ngc):gc(ngc)
|
||||
{
|
||||
std::map<int,nasal_val*> new_scope;
|
||||
elems.push_back(new_scope);
|
||||
return;
|
||||
}
|
||||
nasal_scop::~nasal_scop()
|
||||
{
|
||||
for(std::list<std::map<int,nasal_val*> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||
for(std::map<int,nasal_val*>::iterator j=i->begin();j!=i->end();++j)
|
||||
gc.del_reference(j->second);
|
||||
elems.clear();
|
||||
return;
|
||||
}
|
||||
void nasal_scop::add_scope()
|
||||
{
|
||||
std::map<int,nasal_val*> new_scope;
|
||||
elems.push_front(new_scope);
|
||||
return;
|
||||
}
|
||||
void nasal_scop::del_scope()
|
||||
{
|
||||
std::map<int,nasal_val*>& last_scope=elems.front();
|
||||
for(std::map<int,nasal_val*>::iterator i=last_scope.begin();i!=last_scope.end();++i)
|
||||
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i)
|
||||
gc.del_reference(i->second);
|
||||
elems.pop_front();
|
||||
elems.clear();
|
||||
return;
|
||||
}
|
||||
void nasal_scop::add_new_value(int key,nasal_val* value_address)
|
||||
{
|
||||
if(elems.front().find(key)!=elems.front().end())
|
||||
if(elems.find(key)!=elems.end())
|
||||
{
|
||||
// if this value already exists,delete the old value and update a new value
|
||||
nasal_val* old_val_address=elems.front()[key];
|
||||
gc.del_reference(old_val_address);
|
||||
gc.del_reference(elems[key]);
|
||||
}
|
||||
elems.front()[key]=value_address;
|
||||
elems[key]=value_address;
|
||||
return;
|
||||
}
|
||||
nasal_val* nasal_scop::get_value_address(int key)
|
||||
{
|
||||
nasal_val* ret_address=NULL;
|
||||
for(std::list<std::map<int,nasal_val*> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||
if(i->find(key)!=i->end())
|
||||
return (*i)[key];
|
||||
return ret_address;
|
||||
if(elems.find(key)!=elems.end())
|
||||
return elems[key];
|
||||
return NULL;
|
||||
}
|
||||
nasal_val** nasal_scop::get_mem_address(int key)
|
||||
{
|
||||
nasal_val** ret_address=NULL;
|
||||
for(std::list<std::map<int,nasal_val*> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||
if(i->find(key)!=i->end())
|
||||
return &((*i)[key]);
|
||||
return ret_address;
|
||||
if(elems.find(key)!=elems.end())
|
||||
return &(elems[key]);
|
||||
return NULL;
|
||||
}
|
||||
void nasal_scop::set_closure(nasal_scop& tmp)
|
||||
{
|
||||
for(std::list<std::map<int,nasal_val*> >::iterator i=elems.begin();i!=elems.end();++i)
|
||||
for(std::map<int,nasal_val*>::iterator j=i->begin();j!=i->end();++j)
|
||||
gc.del_reference(j->second);
|
||||
elems.clear();
|
||||
for(std::list<std::map<int,nasal_val*> >::iterator i=tmp.elems.begin();i!=tmp.elems.end();++i)
|
||||
{
|
||||
std::map<int,nasal_val*> new_scope;
|
||||
elems.push_back(new_scope);
|
||||
for(std::map<int,nasal_val*>::iterator j=i->begin();j!=i->end();++j)
|
||||
{
|
||||
nasal_val* value_addr=j->second;
|
||||
gc.add_reference(value_addr);
|
||||
elems.back()[j->first]=value_addr;
|
||||
}
|
||||
}
|
||||
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i)
|
||||
gc.del_reference(i->second);
|
||||
elems=tmp.elems;
|
||||
for(std::map<int,nasal_val*>::iterator i=elems.begin();i!=elems.end();++i)
|
||||
gc.add_reference(i->second);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -521,13 +487,13 @@ nasal_val::nasal_val(int nasal_val_type,nasal_gc& nvm)
|
|||
type=nasal_val_type;
|
||||
switch(nasal_val_type)
|
||||
{
|
||||
case vm_nil: break;
|
||||
case vm_num: ptr.num=0; break;
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec(nvm); break;
|
||||
case vm_hash: ptr.hash=new nasal_hash(nvm); break;
|
||||
case vm_func: ptr.func=new nasal_func(nvm); break;
|
||||
case vm_scop: ptr.cls=new nasal_scop(nvm); break;
|
||||
case vm_nil: break;
|
||||
case vm_num: ptr.num=0; break;
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec(nvm); break;
|
||||
case vm_hash: ptr.hash=new nasal_hash(nvm); break;
|
||||
case vm_func: ptr.func=new nasal_func(nvm); break;
|
||||
case vm_scop: ptr.cls=new nasal_scop(nvm); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -540,13 +506,13 @@ nasal_val::~nasal_val()
|
|||
type=vm_nil;
|
||||
switch(tmp_type)
|
||||
{
|
||||
case vm_nil: break;
|
||||
case vm_num: break;
|
||||
case vm_str: delete ptr.str; break;
|
||||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_nil: break;
|
||||
case vm_num: break;
|
||||
case vm_str: delete ptr.str; break;
|
||||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_scop: delete ptr.cls; break;
|
||||
case vm_scop: delete ptr.cls; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -559,13 +525,13 @@ void nasal_val::clear()
|
|||
type=vm_nil;
|
||||
switch(tmp_type)
|
||||
{
|
||||
case vm_nil: break;
|
||||
case vm_num: break;
|
||||
case vm_str: delete ptr.str; break;
|
||||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_nil: break;
|
||||
case vm_num: break;
|
||||
case vm_str: delete ptr.str; break;
|
||||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_scop: delete ptr.cls; break;
|
||||
case vm_scop: delete ptr.cls; break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -574,13 +540,13 @@ void nasal_val::set_type(int nasal_val_type,nasal_gc& nvm)
|
|||
type=nasal_val_type;
|
||||
switch(nasal_val_type)
|
||||
{
|
||||
case vm_nil: break;
|
||||
case vm_num: ptr.num=0; break;
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec(nvm); break;
|
||||
case vm_hash: ptr.hash=new nasal_hash(nvm); break;
|
||||
case vm_func: ptr.func=new nasal_func(nvm); break;
|
||||
case vm_scop: ptr.cls=new nasal_scop(nvm); break;
|
||||
case vm_nil: break;
|
||||
case vm_num: ptr.num=0; break;
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec(nvm); break;
|
||||
case vm_hash: ptr.hash=new nasal_hash(nvm); break;
|
||||
case vm_func: ptr.func=new nasal_func(nvm); break;
|
||||
case vm_scop: ptr.cls=new nasal_scop(nvm); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
24
nasal_vm.h
24
nasal_vm.h
|
@ -825,17 +825,16 @@ void nasal_vm::opr_callf()
|
|||
die("callf: called a value that is not a function");
|
||||
return;
|
||||
}
|
||||
nasal_func& ref=func_addr->get_func();
|
||||
nasal_val* closure=ref.get_closure_addr();
|
||||
nasal_func& ref_func=func_addr->get_func();
|
||||
nasal_val* closure=gc.gc_alloc(vm_scop);
|
||||
nasal_scop& ref_closure=closure->get_closure();
|
||||
ref_closure.add_scope();
|
||||
ref_closure.set_closure(ref_func.get_closure_addr()->get_closure());
|
||||
local_scope_stack.push(closure);
|
||||
gc.add_reference(closure);
|
||||
if(para_addr->get_type()==vm_vec)
|
||||
{
|
||||
nasal_vec& ref_vec=para_addr->get_vector();
|
||||
std::vector<int>& ref_para=ref.get_para();
|
||||
std::vector<nasal_val*>& ref_default=ref.get_default();
|
||||
std::vector<int>& ref_para=ref_func.get_para();
|
||||
std::vector<nasal_val*>& ref_default=ref_func.get_default();
|
||||
int i=0;
|
||||
for(;i<ref_para.size();++i)
|
||||
{
|
||||
|
@ -856,7 +855,7 @@ void nasal_vm::opr_callf()
|
|||
gc.add_reference(tmp);
|
||||
}
|
||||
}
|
||||
if(ref.get_dynamic_para()>=0)
|
||||
if(ref_func.get_dynamic_para()>=0)
|
||||
{
|
||||
nasal_val* vec_addr=gc.gc_alloc(vm_vec);
|
||||
for(;i<ref_vec.size();++i)
|
||||
|
@ -865,15 +864,15 @@ void nasal_vm::opr_callf()
|
|||
vec_addr->get_vector().add_elem(tmp);
|
||||
gc.add_reference(tmp);
|
||||
}
|
||||
ref_closure.add_new_value(ref.get_dynamic_para(),vec_addr);
|
||||
ref_closure.add_new_value(ref_func.get_dynamic_para(),vec_addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nasal_hash& ref_hash=para_addr->get_hash();
|
||||
std::vector<int>& ref_para=ref.get_para();
|
||||
std::vector<nasal_val*>& ref_default=ref.get_default();
|
||||
if(ref.get_dynamic_para()>=0)
|
||||
std::vector<int>& ref_para=ref_func.get_para();
|
||||
std::vector<nasal_val*>& ref_default=ref_func.get_default();
|
||||
if(ref_func.get_dynamic_para()>=0)
|
||||
{
|
||||
die("callf: special call cannot use dynamic parameter");
|
||||
return;
|
||||
|
@ -894,7 +893,7 @@ void nasal_vm::opr_callf()
|
|||
}
|
||||
gc.del_reference(para_addr);
|
||||
call_stack.push(ptr);
|
||||
ptr=ref.get_entry()-1;
|
||||
ptr=ref_func.get_entry()-1;
|
||||
return;
|
||||
}
|
||||
void nasal_vm::opr_builtincall()
|
||||
|
@ -1086,7 +1085,6 @@ void nasal_vm::opr_return()
|
|||
{
|
||||
nasal_val* closure_addr=local_scope_stack.top();
|
||||
local_scope_stack.pop();
|
||||
closure_addr->get_closure().del_scope();
|
||||
gc.del_reference(closure_addr);
|
||||
ptr=call_stack.top();
|
||||
call_stack.pop();
|
||||
|
|
Loading…
Reference in New Issue