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:
Valk Richard Li 2021-02-17 19:31:44 +08:00
parent 767711c93a
commit 02148f4766
2 changed files with 54 additions and 90 deletions

View File

@ -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;
}

View File

@ -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();