add new gc type vm_upval
This commit is contained in:
parent
9139e34c0b
commit
5fba784d05
32
README.md
32
README.md
|
@ -1,10 +1,10 @@
|
|||
# __Nasal Scripting Language__
|
||||
|
||||
```C++
|
||||
__ _
|
||||
/\ \ \__ _ ___ __ _| |
|
||||
/ \/ / _` / __|/ _` | |
|
||||
/ /\ / (_| \__ \ (_| | |
|
||||
__ _
|
||||
/\ \ \__ _ ___ __ _| |
|
||||
/ \/ / _` / __|/ _` | |
|
||||
/ /\ / (_| \__ \ (_| | |
|
||||
\_\ \/ \__,_|___/\__,_|_|
|
||||
```
|
||||
|
||||
|
@ -127,15 +127,15 @@ Use these commands to get version of interpreter:
|
|||
> ./nasal -v | --version
|
||||
|
||||
```bash
|
||||
__ _
|
||||
/\ \ \__ _ ___ __ _| |
|
||||
/ \/ / _` / __|/ _` | |
|
||||
/ /\ / (_| \__ \ (_| | |
|
||||
__ _
|
||||
/\ \ \__ _ ___ __ _| |
|
||||
/ \/ / _` / __|/ _` | |
|
||||
/ /\ / (_| \__ \ (_| | |
|
||||
\_\ \/ \__,_|___/\__,_|_|
|
||||
nasal interpreter ver 9.0
|
||||
thanks to : https://github.com/andyross/nasal
|
||||
code repo : https://github.com/ValKmjolnir/Nasal-Interpreter
|
||||
code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter
|
||||
code repo : https://github.com/ValKmjolnir/Nasal-Interpreter
|
||||
code repo : https://gitee.com/valkmjolnir/Nasal-Interpreter
|
||||
lang info : http://wiki.flightgear.org/Nasal_scripting_language
|
||||
input <nasal -h> to get help .
|
||||
```
|
||||
|
@ -148,7 +148,7 @@ Use these commands to get help(see more debug commands in help):
|
|||
nasal <option>
|
||||
option:
|
||||
-h, --help | get help.
|
||||
-v, --version | get version of nasal interpreter.
|
||||
-v, --version | get version of nasal interpreter.
|
||||
|
||||
nasal <file>
|
||||
file:
|
||||
|
@ -157,7 +157,7 @@ file:
|
|||
nasal [options...] <file>
|
||||
option:
|
||||
-l, --lex | view token info.
|
||||
-a, --ast | view abstract syntax tree.
|
||||
-a, --ast | view abstract syntax tree.
|
||||
-c, --code | view bytecode.
|
||||
-e, --exec | execute.
|
||||
-t, --time | execute and get the running time.
|
||||
|
@ -175,8 +175,6 @@ If your system is __`Windows`__ and you want to output unicode,please use this c
|
|||
|
||||
> chcp 65001
|
||||
|
||||
The interpreter's interactive mode will do this automatically,so you don't need to run this command if you use the interactive interpreter.
|
||||
|
||||
## __Release Notes__
|
||||
|
||||
### __version 8.0 release__
|
||||
|
@ -735,7 +733,7 @@ running time:
|
|||
|:----|:----|:----|
|
||||
|bf.nas|1100.19s||
|
||||
|mandel.nas|28.98s||
|
||||
|life.nas|0.857s(windows) 0.56(ubuntu WSL)||
|
||||
|life.nas|0.56s|0.857s(windows)|
|
||||
|ycombinator.nas|0.64s||
|
||||
|fib.nas|0.28s||
|
||||
|bfs.nas|0.156s|random result|
|
||||
|
@ -754,8 +752,8 @@ running time:
|
|||
|:----|:----|:----|
|
||||
|bf.nas|276.55s|great improvement|
|
||||
|mandel.nas|28.16s||
|
||||
|ycombinator.nas|0.578s||
|
||||
|life.nas|0.649s(windows) 0.2(ubuntu WSL)||
|
||||
|ycombinator.nas|0.59s||
|
||||
|life.nas|0.2s|0.649s(windows)|
|
||||
|fib.nas|0.234s|little improvement|
|
||||
|bfs.nas|0.14s|random result|
|
||||
|pi.nas|0.0625s||
|
||||
|
|
|
@ -180,7 +180,7 @@ void nasal_dbg::run(
|
|||
const nasal_import& linker)
|
||||
{
|
||||
detail_info=true;
|
||||
init(gen.get_strs(),gen.get_nums(),linker.get_file());
|
||||
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file());
|
||||
const void* opr_table[]=
|
||||
{
|
||||
&&nop, &&intg, &&intl, &&loadg,
|
||||
|
@ -203,7 +203,6 @@ void nasal_dbg::run(
|
|||
&&slc2, &&mcallg, &&mcalll, &&mupval,
|
||||
&&mcallv, &&mcallh, &&ret, &&vmexit
|
||||
};
|
||||
bytecode=gen.get_code().data();
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:gen.get_code())
|
||||
{
|
||||
|
|
89
nasal_gc.h
89
nasal_gc.h
|
@ -14,6 +14,7 @@ enum nasal_type
|
|||
vm_func,
|
||||
vm_vec,
|
||||
vm_hash,
|
||||
vm_upval,
|
||||
vm_obj,
|
||||
vm_type_size
|
||||
};
|
||||
|
@ -29,18 +30,20 @@ const uint32_t increment[vm_type_size]=
|
|||
0, // vm_nil
|
||||
0, // vm_num
|
||||
/* gc object */
|
||||
256, // vm_str
|
||||
128, // vm_str
|
||||
512, // vm_func
|
||||
512, // vm_vec
|
||||
128, // vm_hash
|
||||
128, // vm_vec
|
||||
64, // vm_hash
|
||||
512, // vm_upval
|
||||
16 // vm_obj
|
||||
};
|
||||
|
||||
struct nasal_vec; // vector
|
||||
struct nasal_hash;// hashmap(dict)
|
||||
struct nasal_func;// function(lambda)
|
||||
struct nasal_obj; // special objects
|
||||
struct nasal_val; // nasal_val includes gc-managed types
|
||||
struct nasal_vec; // vector
|
||||
struct nasal_hash; // hashmap(dict)
|
||||
struct nasal_func; // function(lambda)
|
||||
struct nasal_upval;// upvalue
|
||||
struct nasal_obj; // special objects
|
||||
struct nasal_val; // nasal_val includes gc-managed types
|
||||
|
||||
struct nasal_ref
|
||||
{
|
||||
|
@ -78,6 +81,7 @@ struct nasal_ref
|
|||
inline nasal_vec* vec ();
|
||||
inline nasal_hash* hash();
|
||||
inline nasal_func* func();
|
||||
inline nasal_upval& upval();
|
||||
inline nasal_obj* obj ();
|
||||
};
|
||||
|
||||
|
@ -113,6 +117,17 @@ struct nasal_func
|
|||
void clear();
|
||||
};
|
||||
|
||||
struct nasal_upval
|
||||
{
|
||||
bool onstk;
|
||||
nasal_ref* stk;
|
||||
std::vector<nasal_ref> elems;
|
||||
|
||||
nasal_upval(){onstk=true;stk=nullptr;}
|
||||
nasal_ref& operator[](const int);
|
||||
void clear(){onstk=true;elems.clear();}
|
||||
};
|
||||
|
||||
struct nasal_obj
|
||||
{
|
||||
uint32_t type;
|
||||
|
@ -135,6 +150,7 @@ struct nasal_val
|
|||
nasal_vec* vec;
|
||||
nasal_hash* hash;
|
||||
nasal_func* func;
|
||||
nasal_upval* upval;
|
||||
nasal_obj* obj;
|
||||
}ptr;
|
||||
|
||||
|
@ -241,6 +257,13 @@ void nasal_func::clear()
|
|||
keys.clear();
|
||||
}
|
||||
|
||||
nasal_ref& nasal_upval::operator[](const int index)
|
||||
{
|
||||
if(onstk)
|
||||
return stk[index];
|
||||
return elems[index];
|
||||
}
|
||||
|
||||
nasal_val::nasal_val(uint8_t val_type)
|
||||
{
|
||||
mark=GC_COLLECTED;
|
||||
|
@ -248,11 +271,12 @@ nasal_val::nasal_val(uint8_t val_type)
|
|||
unmut=0;
|
||||
switch(val_type)
|
||||
{
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec; break;
|
||||
case vm_hash: ptr.hash=new nasal_hash; break;
|
||||
case vm_func: ptr.func=new nasal_func; break;
|
||||
case vm_obj: ptr.obj=new nasal_obj; break;
|
||||
case vm_str: ptr.str=new std::string; break;
|
||||
case vm_vec: ptr.vec=new nasal_vec; break;
|
||||
case vm_hash: ptr.hash=new nasal_hash; break;
|
||||
case vm_func: ptr.func=new nasal_func; break;
|
||||
case vm_upval:ptr.upval=new nasal_upval;break;
|
||||
case vm_obj: ptr.obj=new nasal_obj; break;
|
||||
}
|
||||
}
|
||||
nasal_val::~nasal_val()
|
||||
|
@ -263,6 +287,7 @@ nasal_val::~nasal_val()
|
|||
case vm_vec: delete ptr.vec; break;
|
||||
case vm_hash: delete ptr.hash; break;
|
||||
case vm_func: delete ptr.func; break;
|
||||
case vm_upval:delete ptr.upval;break;
|
||||
case vm_obj: delete ptr.obj; break;
|
||||
}
|
||||
type=vm_nil;
|
||||
|
@ -293,14 +318,15 @@ void nasal_ref::print()
|
|||
case vm_obj: std::cout<<"<object>"; break;
|
||||
}
|
||||
}
|
||||
inline uint32_t nasal_ref::ret (){return value.ret; }
|
||||
inline int64_t& nasal_ref::cnt (){return value.cnt; }
|
||||
inline double& nasal_ref::num (){return value.num; }
|
||||
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
|
||||
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }
|
||||
inline nasal_hash* nasal_ref::hash(){return value.gcobj->ptr.hash;}
|
||||
inline nasal_func* nasal_ref::func(){return value.gcobj->ptr.func;}
|
||||
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
||||
inline uint32_t nasal_ref::ret (){return value.ret; }
|
||||
inline int64_t& nasal_ref::cnt (){return value.cnt; }
|
||||
inline double& nasal_ref::num (){return value.num; }
|
||||
inline std::string* nasal_ref::str (){return value.gcobj->ptr.str; }
|
||||
inline nasal_vec* nasal_ref::vec (){return value.gcobj->ptr.vec; }
|
||||
inline nasal_hash* nasal_ref::hash (){return value.gcobj->ptr.hash; }
|
||||
inline nasal_func* nasal_ref::func (){return value.gcobj->ptr.func; }
|
||||
inline nasal_upval& nasal_ref::upval(){return *value.gcobj->ptr.upval;}
|
||||
inline nasal_obj* nasal_ref::obj (){return value.gcobj->ptr.obj; }
|
||||
|
||||
const uint32_t STACK_MAX_DEPTH=8191;
|
||||
const nasal_ref zero={vm_num,(double)0};
|
||||
|
@ -355,6 +381,9 @@ void nasal_gc::mark()
|
|||
for(auto& i:tmp.func()->upvalue)
|
||||
bfs.push(i);
|
||||
break;
|
||||
case vm_upval:
|
||||
for(auto& i:tmp.upval().elems)
|
||||
bfs.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,11 +395,12 @@ void nasal_gc::sweep()
|
|||
{
|
||||
switch(i->type)
|
||||
{
|
||||
case vm_str: i->ptr.str->clear(); break;
|
||||
case vm_vec: i->ptr.vec->elems.clear(); break;
|
||||
case vm_hash:i->ptr.hash->elems.clear();break;
|
||||
case vm_func:i->ptr.func->clear(); break;
|
||||
case vm_obj: i->ptr.obj->clear(); break;
|
||||
case vm_str: i->ptr.str->clear(); break;
|
||||
case vm_vec: i->ptr.vec->elems.clear(); break;
|
||||
case vm_hash: i->ptr.hash->elems.clear();break;
|
||||
case vm_func: i->ptr.func->clear(); break;
|
||||
case vm_upval:i->ptr.upval->clear(); break;
|
||||
case vm_obj: i->ptr.obj->clear(); break;
|
||||
}
|
||||
free_list[i->type].push(i);
|
||||
i->mark=GC_COLLECTED;
|
||||
|
@ -416,9 +446,10 @@ void nasal_gc::clear()
|
|||
void nasal_gc::info()
|
||||
{
|
||||
const char* name[]={
|
||||
"null","cnt ","ret ",
|
||||
"nil ","num ","str ",
|
||||
"func","vec ","hash","obj "
|
||||
"null ","cnt ","ret ",
|
||||
"nil ","num ","str ",
|
||||
"func ","vec ","hash ",
|
||||
"upval","obj "
|
||||
};
|
||||
std::cout<<"\ngarbage collector info:\n";
|
||||
for(uint8_t i=vm_str;i<vm_type_size;++i)
|
||||
|
|
34
nasal_vm.h
34
nasal_vm.h
|
@ -24,6 +24,7 @@ protected:
|
|||
void init(
|
||||
const std::vector<std::string>&,
|
||||
const std::vector<double>&,
|
||||
const std::vector<opcode>&,
|
||||
const std::vector<std::string>&);
|
||||
/* debug functions */
|
||||
bool detail_info;
|
||||
|
@ -126,11 +127,13 @@ public:
|
|||
void nasal_vm::init(
|
||||
const std::vector<std::string>& strs,
|
||||
const std::vector<double>& nums,
|
||||
const std::vector<opcode>& code,
|
||||
const std::vector<std::string>& filenames)
|
||||
{
|
||||
gc.init(strs);
|
||||
num_table=nums.data();
|
||||
str_table=strs.data();
|
||||
bytecode=code.data();
|
||||
files=filenames.data();
|
||||
files_size=filenames.size();
|
||||
/* set canary and program counter */
|
||||
|
@ -339,11 +342,10 @@ inline void nasal_vm::opr_loadg()
|
|||
inline void nasal_vm::opr_loadl()
|
||||
{
|
||||
lstk.top()[imm[pc]]=(gc.top--)[0];
|
||||
//gc.local.back().vec()->elems[imm[pc]]=(gc.top--)[0];
|
||||
}
|
||||
inline void nasal_vm::opr_loadu()
|
||||
{
|
||||
fstk.top()->upvalue[(imm[pc]>>16)&0xffff].vec()->elems[imm[pc]&0xffff]=(gc.top--)[0];
|
||||
fstk.top()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]=(gc.top--)[0];
|
||||
}
|
||||
inline void nasal_vm::opr_pnum()
|
||||
{
|
||||
|
@ -383,12 +385,10 @@ inline void nasal_vm::opr_newf()
|
|||
if(!lstk.empty())
|
||||
{
|
||||
func->upvalue=fstk.top()->upvalue;
|
||||
nasal_ref upval=(gc.upvalue.back().type==vm_nil)?gc.alloc(vm_vec):gc.upvalue.back();
|
||||
nasal_ref upval=(gc.upvalue.back().type==vm_nil)?gc.alloc(vm_upval):gc.upvalue.back();
|
||||
upval.upval().stk=lstk.top();
|
||||
func->upvalue.push_back(upval);
|
||||
gc.upvalue.back()=upval;
|
||||
auto& vec=upval.vec()->elems;
|
||||
for(uint32_t i=0;i<fstk.top()->lsize;++i)
|
||||
vec.push_back(lstk.top()[i]);
|
||||
}
|
||||
}
|
||||
inline void nasal_vm::opr_happ()
|
||||
|
@ -601,7 +601,7 @@ inline void nasal_vm::opr_calll()
|
|||
}
|
||||
inline void nasal_vm::opr_upval()
|
||||
{
|
||||
(++gc.top)[0]=fstk.top()->upvalue[(imm[pc]>>16)&0xffff].vec()->elems[imm[pc]&0xffff];
|
||||
(++gc.top)[0]=fstk.top()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff];
|
||||
}
|
||||
inline void nasal_vm::opr_callv()
|
||||
{
|
||||
|
@ -801,7 +801,7 @@ inline void nasal_vm::opr_mcalll()
|
|||
}
|
||||
inline void nasal_vm::opr_mupval()
|
||||
{
|
||||
mem_addr=&fstk.top()->upvalue[(imm[pc]>>16)&0xffff].vec()->elems[imm[pc]&0xffff];
|
||||
mem_addr=&(fstk.top()->upvalue[(imm[pc]>>16)&0xffff].upval()[imm[pc]&0xffff]);
|
||||
(++gc.top)[0]=mem_addr[0];
|
||||
}
|
||||
inline void nasal_vm::opr_mcallv()
|
||||
|
@ -852,17 +852,26 @@ inline void nasal_vm::opr_ret()
|
|||
// +-----------------+
|
||||
// | local scope |
|
||||
// +-----------------+ <- local pointer stored in lstk
|
||||
// | called function | <- funct is set on stack because gc may mark it
|
||||
// | called function | <- func is stored on stack because gc may mark it
|
||||
// +-----------------+
|
||||
nasal_ref ret=gc.top[0];
|
||||
pc=gc.top[-1].ret();
|
||||
|
||||
gc.top=lstk.top()-1;
|
||||
lstk.pop();
|
||||
|
||||
gc.top[0].func()->local[0]={vm_nil,nullptr}; // get func and set 'me' to nil
|
||||
gc.top[0]=ret; // rewrite func with returned value
|
||||
|
||||
if(gc.upvalue.back().type==vm_upval) // synchronize upvalue
|
||||
{
|
||||
auto& upval=gc.upvalue.back().upval();
|
||||
auto local=lstk.top();
|
||||
auto size=fstk.top()->lsize;
|
||||
upval.onstk=false;
|
||||
for(uint32_t i=0;i<size;++i)
|
||||
upval.elems.push_back(local[i]);
|
||||
}
|
||||
lstk.pop();
|
||||
fstk.pop();
|
||||
gc.upvalue.pop_back();
|
||||
}
|
||||
|
@ -873,7 +882,7 @@ void nasal_vm::run(
|
|||
const bool detail)
|
||||
{
|
||||
detail_info=detail;
|
||||
init(gen.get_strs(),gen.get_nums(),linker.get_file());
|
||||
init(gen.get_strs(),gen.get_nums(),gen.get_code(),linker.get_file());
|
||||
uint64_t count[op_exit+1]={0};
|
||||
const void* opr_table[]=
|
||||
{
|
||||
|
@ -897,7 +906,6 @@ void nasal_vm::run(
|
|||
&&slc2, &&mcallg, &&mcalll, &&mupval,
|
||||
&&mcallv, &&mcallh, &&ret, &&vmexit
|
||||
};
|
||||
bytecode=gen.get_code().data();
|
||||
std::vector<const void*> code;
|
||||
for(auto& i:gen.get_code())
|
||||
{
|
||||
|
@ -985,7 +993,7 @@ callv: exec_opnodie(opr_callv ,op_callv ); // -0
|
|||
callvi: exec_opnodie(opr_callvi ,op_callvi ); // -0
|
||||
callh: exec_opnodie(opr_callh ,op_callh ); // -0
|
||||
callfv: exec_opnodie(opr_callfv ,op_callfv ); // check in the function
|
||||
callfh: exec_opnodie(opr_callfh ,op_callfh ); // -0 call this will push one hash
|
||||
callfh: exec_opnodie(opr_callfh ,op_callfh ); // check in the function
|
||||
callb: exec_opnodie(opr_callb ,op_callb ); // -0
|
||||
slcbegin:exec_operand(opr_slcbegin,op_slcbegin); // +1
|
||||
slcend: exec_opnodie(opr_slcend ,op_slcend ); // -1
|
||||
|
|
Loading…
Reference in New Issue