⚡ optimize codes
This commit is contained in:
parent
99dca532f6
commit
ebfacd9197
|
@ -142,7 +142,7 @@ Use these commands to get version of interpreter:
|
|||
/ \/ / _` / __|/ _` | |
|
||||
/ /\ / (_| \__ \ (_| | |
|
||||
\_\ \/ \__,_|___/\__,_|_|
|
||||
nasal ver : 9.0
|
||||
nasal ver : 10.0
|
||||
c++ std : 201103
|
||||
thanks to : https://github.com/andyross/nasal
|
||||
code repo : https://github.com/ValKmjolnir/Nasal-Interpreter
|
||||
|
@ -156,6 +156,9 @@ Use these commands to get help(see more debug commands in help):
|
|||
> ./nasal -h | --help
|
||||
|
||||
```bash
|
||||
,--#-,
|
||||
<3 / \____\ <3
|
||||
|_|__A_|
|
||||
nasal <option>
|
||||
option:
|
||||
-h, --help | get help.
|
||||
|
@ -633,7 +636,7 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
|||
if(hash.type!=vm_hash)
|
||||
return builtin_err("keys","\"hash\" must be hash");
|
||||
// push vector into local scope to avoid being sweeped
|
||||
if(gc.top+1>=gc.stack+nasal_gc::stack_depth-1)
|
||||
if(gc.top+1>=gc.canary)
|
||||
return builtin_err("keys","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
|
|
3
main.cpp
3
main.cpp
|
@ -13,6 +13,9 @@ const uint32_t VM_OPTIMIZE =0x100;
|
|||
void help()
|
||||
{
|
||||
std::cout
|
||||
<<" ,--#-,\n"
|
||||
<<"<3 / \\____\\ <3\n"
|
||||
<<" |_|__A_|\n"
|
||||
#ifdef _WIN32
|
||||
<<"use command <chcp 65001> if want to use unicode.\n"
|
||||
#endif
|
||||
|
|
2
nasal.h
2
nasal.h
|
@ -45,6 +45,8 @@
|
|||
#define PRTINT64 "%lld"
|
||||
#endif
|
||||
|
||||
const uint32_t STACK_DEPTH=8192;
|
||||
|
||||
inline double hex_to_double(const char* str)
|
||||
{
|
||||
double ret=0;
|
||||
|
|
|
@ -306,7 +306,7 @@ nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
|||
size_t source_len=source.length();
|
||||
|
||||
// push it to local scope to avoid being sweeped
|
||||
if(gc.top+1>=gc.stack+nasal_gc::stack_depth-1)
|
||||
if(gc.top+1>=gc.canary)
|
||||
return builtin_err("split","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
|
||||
|
@ -611,7 +611,7 @@ nasal_ref builtin_keys(nasal_ref* local,nasal_gc& gc)
|
|||
if(hash.type!=vm_hash)
|
||||
return builtin_err("keys","\"hash\" must be hash");
|
||||
// push vector into local scope to avoid being sweeped
|
||||
if(gc.top+1>=gc.stack+nasal_gc::stack_depth-1)
|
||||
if(gc.top+1>=gc.canary)
|
||||
return builtin_err("keys","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
|
@ -1115,7 +1115,7 @@ nasal_ref builtin_chdir(nasal_ref* local,nasal_gc& gc)
|
|||
nasal_ref builtin_environ(nasal_ref* local,nasal_gc& gc)
|
||||
{
|
||||
char** env=environ;
|
||||
if(gc.top+1>=gc.stack+nasal_gc::stack_depth-1)
|
||||
if(gc.top+1>=gc.canary)
|
||||
return builtin_err("environ","expand temporary space error:stackoverflow");
|
||||
(++gc.top)[0]=gc.alloc(vm_vec);
|
||||
auto& vec=gc.top[0].vec().elems;
|
||||
|
|
|
@ -430,7 +430,7 @@ void nasal_codegen::func_gen(const nasal_ast& ast)
|
|||
block_gen(block);
|
||||
in_iterloop.pop();
|
||||
code[local_label].num=local.back().size();
|
||||
if(local.back().size()>=nasal_gc::stack_depth)
|
||||
if(local.back().size()>=STACK_DEPTH)
|
||||
die("too many local variants: "+std::to_string(local.back().size())+".",block.line());
|
||||
local.pop_back();
|
||||
|
||||
|
@ -1232,7 +1232,7 @@ void nasal_codegen::compile(const nasal_parse& parse,const nasal_import& import)
|
|||
gen(op_intg,global.size(),0);
|
||||
block_gen(parse.ast()); // generate main block
|
||||
gen(op_exit,0,0);
|
||||
if(global.size()>=nasal_gc::stack_depth)
|
||||
if(global.size()>=STACK_DEPTH)
|
||||
die("too many global variants: "+std::to_string(global.size())+".",0);
|
||||
nerr.chkerr();
|
||||
}
|
||||
|
|
60
nasal_gc.h
60
nasal_gc.h
|
@ -175,7 +175,7 @@ struct nasal_obj
|
|||
enum obj_type
|
||||
{
|
||||
null,
|
||||
file=1,
|
||||
file,
|
||||
dir,
|
||||
dylib,
|
||||
faddr
|
||||
|
@ -209,8 +209,7 @@ struct nasal_co
|
|||
running,
|
||||
dead
|
||||
};
|
||||
static const uint32_t depth=1024;
|
||||
nasal_ref stack[depth];
|
||||
nasal_ref stack[STACK_DEPTH];
|
||||
|
||||
uint32_t pc;
|
||||
nasal_ref* top;
|
||||
|
@ -224,19 +223,19 @@ struct nasal_co
|
|||
nasal_co():
|
||||
pc(0),
|
||||
top(stack),
|
||||
canary(stack+depth-1),
|
||||
canary(stack+STACK_DEPTH-1),
|
||||
localr(nullptr),
|
||||
memr(nullptr),
|
||||
funcr({vm_nil,(double)0}),
|
||||
upvalr({vm_nil,(double)0}),
|
||||
status(nasal_co::suspended)
|
||||
{
|
||||
for(uint32_t i=0;i<depth;++i)
|
||||
for(uint32_t i=0;i<STACK_DEPTH;++i)
|
||||
stack[i]={vm_nil,(double)0};
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
for(uint32_t i=0;i<depth;++i)
|
||||
for(uint32_t i=0;i<STACK_DEPTH;++i)
|
||||
stack[i]={vm_nil,(double)0};
|
||||
pc=0;
|
||||
localr=nullptr;
|
||||
|
@ -451,10 +450,8 @@ const nasal_ref nil ={vm_nil,(double)0};
|
|||
|
||||
struct nasal_gc
|
||||
{
|
||||
static const uint32_t stack_depth=8192; // depth of value stack
|
||||
struct
|
||||
{
|
||||
nasal_ref stack[stack_depth];
|
||||
uint32_t pc;
|
||||
nasal_ref* top;
|
||||
nasal_ref* localr;
|
||||
|
@ -462,16 +459,17 @@ struct nasal_gc
|
|||
nasal_ref funcr;
|
||||
nasal_ref upvalr;
|
||||
nasal_ref* canary;
|
||||
nasal_ref* stack;
|
||||
} main_ctx;
|
||||
|
||||
/* runtime context */
|
||||
uint32_t pc; // program counter
|
||||
nasal_ref* top; // stack top
|
||||
nasal_ref* localr; // local scope register
|
||||
nasal_ref* memr; // used for mem_call
|
||||
nasal_ref funcr; // function register
|
||||
nasal_ref upvalr; // upvalue register
|
||||
nasal_ref* canary; // avoid stackoverflow
|
||||
uint32_t& pc; // program counter
|
||||
nasal_ref*& localr; // local scope register
|
||||
nasal_ref*& memr; // used for mem_call
|
||||
nasal_ref& funcr; // function register
|
||||
nasal_ref& upvalr; // upvalue register
|
||||
nasal_ref*& canary; // avoid stackoverflow
|
||||
nasal_ref*& top; // stack top
|
||||
nasal_ref* stack; // stack pointer
|
||||
nasal_co* coroutine; // running coroutine
|
||||
|
||||
|
@ -483,6 +481,23 @@ struct nasal_gc
|
|||
/* values for analysis */
|
||||
uint64_t size[vm_type_size];
|
||||
uint64_t count[vm_type_size];
|
||||
nasal_gc(
|
||||
uint32_t& _pc,
|
||||
nasal_ref*& _localr,
|
||||
nasal_ref*& _memr,
|
||||
nasal_ref& _funcr,
|
||||
nasal_ref& _upvalr,
|
||||
nasal_ref*& _canary,
|
||||
nasal_ref*& _top,
|
||||
nasal_ref* _stk):
|
||||
pc(_pc),
|
||||
localr(_localr),
|
||||
memr(_memr),
|
||||
funcr(_funcr),
|
||||
upvalr(_upvalr),
|
||||
canary(_canary),
|
||||
top(_top),
|
||||
stack(_stk){}
|
||||
void mark();
|
||||
void sweep();
|
||||
void init(const std::vector<std::string>&);
|
||||
|
@ -499,6 +514,7 @@ void nasal_gc::mark()
|
|||
{
|
||||
std::queue<nasal_ref> bfs;
|
||||
|
||||
// this make sure values on main stack can be scanned
|
||||
if(!coroutine)
|
||||
{
|
||||
for(nasal_ref* i=stack;i<=top;++i)
|
||||
|
@ -586,8 +602,6 @@ void nasal_gc::init(const std::vector<std::string>& s)
|
|||
memory.push_back(tmp);
|
||||
free_list[i].push(tmp);
|
||||
}
|
||||
stack=main_ctx.stack;
|
||||
top=main_ctx.stack;
|
||||
coroutine=nullptr;
|
||||
// init constant strings
|
||||
strs.resize(s.size());
|
||||
|
@ -679,6 +693,7 @@ void nasal_gc::ctxchg(nasal_co& context)
|
|||
main_ctx.funcr=funcr;
|
||||
main_ctx.upvalr=upvalr;
|
||||
main_ctx.canary=canary;
|
||||
main_ctx.stack=stack;
|
||||
|
||||
pc=context.pc;
|
||||
top=context.top;
|
||||
|
@ -694,24 +709,23 @@ void nasal_gc::ctxchg(nasal_co& context)
|
|||
}
|
||||
void nasal_gc::ctxreserve()
|
||||
{
|
||||
if(coroutine->status!=nasal_co::dead)
|
||||
coroutine->status=nasal_co::suspended;
|
||||
// pc=0 means this coroutine is finished, so we use entry to reset it
|
||||
coroutine->pc=pc==0?coroutine->funcr.func().entry:pc;
|
||||
coroutine->top=top;
|
||||
// pc=0 means this coroutine is finished
|
||||
coroutine->status=pc?nasal_co::suspended:nasal_co::dead;
|
||||
coroutine->pc=pc;
|
||||
coroutine->localr=localr;
|
||||
coroutine->memr=memr;
|
||||
coroutine->funcr=funcr;
|
||||
coroutine->upvalr=upvalr;
|
||||
coroutine->canary=canary;
|
||||
coroutine->top=top;
|
||||
|
||||
pc=main_ctx.pc;
|
||||
top=main_ctx.top;
|
||||
localr=main_ctx.localr;
|
||||
memr=main_ctx.memr;
|
||||
funcr=main_ctx.funcr;
|
||||
upvalr=main_ctx.upvalr;
|
||||
canary=main_ctx.canary;
|
||||
top=main_ctx.top;
|
||||
stack=main_ctx.stack;
|
||||
coroutine=nullptr;
|
||||
}
|
||||
|
|
77
nasal_vm.h
77
nasal_vm.h
|
@ -5,20 +5,24 @@ class nasal_vm
|
|||
{
|
||||
protected:
|
||||
/* values of nasal_vm */
|
||||
uint32_t& pc; // program counter
|
||||
nasal_ref stack[STACK_DEPTH];
|
||||
uint32_t pc; // program counter
|
||||
nasal_ref* global; // global scope register
|
||||
nasal_ref*& localr; // local scope register
|
||||
nasal_ref*& memr; // used for mem_call
|
||||
nasal_ref& funcr; // function register
|
||||
nasal_ref& upvalr; // upvalue register
|
||||
nasal_ref*& canary; // avoid stackoverflow
|
||||
nasal_ref*& top; // stack top
|
||||
nasal_ref* localr; // local scope register
|
||||
nasal_ref* memr; // used for mem_call
|
||||
nasal_ref funcr; // function register
|
||||
nasal_ref upvalr; // upvalue register
|
||||
nasal_ref* canary; // avoid stackoverflow
|
||||
nasal_ref* top; // stack top
|
||||
|
||||
/* constant */
|
||||
const double* num_table;// const numbers, ref from nasal_codegen
|
||||
const std::string* str_table;// const symbols, ref from nasal_codegen
|
||||
std::vector<uint32_t> imm; // immediate number
|
||||
|
||||
/* garbage collector */
|
||||
nasal_gc gc;
|
||||
|
||||
/* values used for debug */
|
||||
size_t files_size;
|
||||
const std::string* files; // ref from nasal_import
|
||||
|
@ -121,14 +125,8 @@ protected:
|
|||
void opr_ret();
|
||||
public:
|
||||
nasal_vm():
|
||||
pc(gc.pc),
|
||||
global(gc.main_ctx.stack),
|
||||
localr(gc.localr),
|
||||
memr(gc.memr),
|
||||
funcr(gc.funcr),
|
||||
upvalr(gc.upvalr),
|
||||
canary(gc.canary),
|
||||
top(gc.top){}
|
||||
global(stack),
|
||||
gc(pc,localr,memr,funcr,upvalr,canary,top,stack){}
|
||||
void run(
|
||||
const nasal_codegen&,
|
||||
const nasal_import&,
|
||||
|
@ -148,13 +146,16 @@ void nasal_vm::init(
|
|||
bytecode=code.data();
|
||||
files=filenames.data();
|
||||
files_size=filenames.size();
|
||||
|
||||
/* set canary and program counter */
|
||||
canary=gc.stack+nasal_gc::stack_depth-1; // gc.stack[nasal_gc::stack_depth-1]
|
||||
pc=0;
|
||||
global=stack;
|
||||
localr=nullptr;
|
||||
memr=nullptr;
|
||||
funcr=nil;
|
||||
upvalr=nil;
|
||||
canary=stack+STACK_DEPTH-1; // stack[STACK_DEPTH-1]
|
||||
top=stack;
|
||||
}
|
||||
void nasal_vm::valinfo(nasal_ref& val)
|
||||
{
|
||||
|
@ -239,7 +240,7 @@ void nasal_vm::traceback()
|
|||
{
|
||||
uint32_t global_size=bytecode[0].num; // bytecode[0] is op_intg
|
||||
nasal_ref* t=top;
|
||||
nasal_ref* bottom=gc.stack+global_size;
|
||||
nasal_ref* bottom=stack+global_size;
|
||||
std::stack<uint32_t> ret;
|
||||
for(nasal_ref* i=bottom;i<=t;++i)
|
||||
if(i->type==vm_ret)
|
||||
|
@ -266,7 +267,7 @@ void nasal_vm::traceback()
|
|||
void nasal_vm::stackinfo(const uint32_t limit=10)
|
||||
{
|
||||
/* bytecode[0] is op_intg, the .num is the global size */
|
||||
uint32_t gsize=gc.stack==gc.main_ctx.stack?bytecode[0].num:0;
|
||||
uint32_t gsize=gc.stack==stack?bytecode[0].num:0;
|
||||
nasal_ref* t=top;
|
||||
nasal_ref* bottom=gc.stack+gsize;
|
||||
printf("vm stack(0x" PRTHEX64 "<sp+%u>, limit %u, total ",(uint64_t)bottom,gsize,limit);
|
||||
|
@ -285,7 +286,7 @@ void nasal_vm::stackinfo(const uint32_t limit=10)
|
|||
void nasal_vm::register_info()
|
||||
{
|
||||
printf("registers(%s):\n",gc.coroutine?"coroutine":"main");
|
||||
printf(" [ pc ] | pc | 0x%.x\n",pc);
|
||||
printf(" [ pc ] | pc | 0x%x\n",pc);
|
||||
printf(" [ global ] | addr | 0x" PRTHEX64 "\n",(uint64_t)global);
|
||||
printf(" [ localr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)localr);
|
||||
printf(" [ memr ] | addr | 0x" PRTHEX64 "\n",(uint64_t)memr);
|
||||
|
@ -306,7 +307,7 @@ void nasal_vm::register_info()
|
|||
}
|
||||
void nasal_vm::global_state()
|
||||
{
|
||||
if(!bytecode[0].num || gc.stack[0].type==vm_none) // bytecode[0].op is op_intg
|
||||
if(!bytecode[0].num || stack[0].type==vm_none) // bytecode[0].op is op_intg
|
||||
return;
|
||||
printf("global(0x" PRTHEX64 "<sp+0>):\n",(uint64_t)global);
|
||||
for(uint32_t i=0;i<bytecode[0].num;++i)
|
||||
|
@ -955,20 +956,21 @@ inline void nasal_vm::opr_mcallh()
|
|||
}
|
||||
inline void nasal_vm::opr_ret()
|
||||
{
|
||||
// +-----------------+
|
||||
// | return value | <- top[0]
|
||||
// +-----------------+
|
||||
// | old pc | <- top[-1]
|
||||
// +-----------------+
|
||||
// | old localr | <- top[-2]
|
||||
// +-----------------+
|
||||
// | old upvalr | <- top[-3]
|
||||
// +-----------------+
|
||||
// | local scope |
|
||||
// | ... |
|
||||
// +-----------------+ <- local pointer stored in localr
|
||||
// | old funcr | <- old function stored in funcr
|
||||
// +-----------------+
|
||||
/* +-----------------+
|
||||
* | return value | <- top[0]
|
||||
* +-----------------+
|
||||
* | old pc | <- top[-1]
|
||||
* +-----------------+
|
||||
* | old localr | <- top[-2]
|
||||
* +-----------------+
|
||||
* | old upvalr | <- top[-3]
|
||||
* +-----------------+
|
||||
* | local scope |
|
||||
* | ... |
|
||||
* +-----------------+ <- local pointer stored in localr
|
||||
* | old funcr | <- old function stored in funcr
|
||||
* +-----------------+
|
||||
*/
|
||||
nasal_ref ret =top[0];
|
||||
nasal_ref* local=localr;
|
||||
nasal_ref func =funcr;
|
||||
|
@ -992,12 +994,11 @@ inline void nasal_vm::opr_ret()
|
|||
for(uint32_t i=0;i<size;++i)
|
||||
upval.elems.push_back(local[i]);
|
||||
}
|
||||
if(!pc) // cannot use gc.coroutine to judge, because there maybe another function call inside
|
||||
{
|
||||
gc.coroutine->status=nasal_co::dead;
|
||||
// cannot use gc.coroutine to judge,
|
||||
// because there maybe another function call inside
|
||||
if(!pc)
|
||||
gc.ctxreserve();
|
||||
}
|
||||
}
|
||||
void nasal_vm::run(
|
||||
const nasal_codegen& gen,
|
||||
const nasal_import& linker,
|
||||
|
|
Loading…
Reference in New Issue