add new gc type vm_upval

This commit is contained in:
ValKmjolnir 2022-02-13 22:40:54 +08:00
parent 9139e34c0b
commit 5fba784d05
4 changed files with 97 additions and 61 deletions

View File

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

View File

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

View File

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

View File

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