bug fixed

add operand op_offset to make sure arguments are loaded at correct places,before this commit,arguments are not loaded from a correct offset,which will cause SIGSEGV when calling a function that has complex closure
This commit is contained in:
Valk Richard Li 2021-05-17 21:15:57 +08:00
parent a463af53b7
commit aae9395d66
2 changed files with 15 additions and 4 deletions

View File

@ -6,6 +6,7 @@ enum op_code
op_nop, // do nothing and end the vm main loop op_nop, // do nothing and end the vm main loop
op_intg, // global scope size op_intg, // global scope size
op_intl, // local scope size op_intl, // local scope size
op_offset, // offset of local scope of function in closure
op_loadg, // load global symbol value op_loadg, // load global symbol value
op_loadl, // load local symbol value op_loadl, // load local symbol value
op_pnum, // push constant number to the stack op_pnum, // push constant number to the stack
@ -75,6 +76,7 @@ struct
{op_nop, "nop "}, {op_nop, "nop "},
{op_intg, "intg "}, {op_intg, "intg "},
{op_intl, "intl "}, {op_intl, "intl "},
{op_offset, "offset"},
{op_loadg, "loadg "}, {op_loadg, "loadg "},
{op_loadl, "loadl "}, {op_loadl, "loadl "},
{op_pnum, "pnum "}, {op_pnum, "pnum "},
@ -373,6 +375,10 @@ void nasal_codegen::func_gen(nasal_ast& ast)
// this symbol's index will be 0 // this symbol's index will be 0
if(local.size()==1) if(local.size()==1)
add_sym("me"); add_sym("me");
gen(op_offset,0);
for(auto i:local)
exec_code.back().num+=i.size();
// generate parameter list // generate parameter list
for(auto tmp:ast.get_children()[0].get_children()) for(auto tmp:ast.get_children()[0].get_children())
{ {

View File

@ -21,6 +21,7 @@ private:
void opr_nop(); void opr_nop();
void opr_intg(); void opr_intg();
void opr_intl(); void opr_intl();
void opr_offset();
void opr_loadg(); void opr_loadg();
void opr_loadl(); void opr_loadl();
void opr_pnum(); void opr_pnum();
@ -146,15 +147,19 @@ void nasal_vm::opr_nop()
} }
void nasal_vm::opr_intg() void nasal_vm::opr_intg()
{ {
gc.global.resize(exec_code[pc].num); gc.global.resize(exec_code[pc].num,gc.nil_addr);
return; return;
} }
void nasal_vm::opr_intl() void nasal_vm::opr_intl()
{ {
(*stack_top)->ptr.func->closure.resize(exec_code[pc].num); (*stack_top)->ptr.func->closure.resize(exec_code[pc].num,gc.nil_addr);
(*stack_top)->ptr.func->closure[0]=gc.nil_addr;// me (*stack_top)->ptr.func->closure[0]=gc.nil_addr;// me
return; return;
} }
void nasal_vm::opr_offset()
{
(*stack_top)->ptr.func->offset=exec_code[pc].num;
}
void nasal_vm::opr_loadg() void nasal_vm::opr_loadg()
{ {
gc.global[exec_code[pc].num]=*stack_top--; gc.global[exec_code[pc].num]=*stack_top--;
@ -209,8 +214,7 @@ void nasal_vm::opr_newf()
if(!gc.local.empty()) if(!gc.local.empty())
val->ptr.func->closure=gc.local.back(); val->ptr.func->closure=gc.local.back();
else else
val->ptr.func->closure.push_back(gc.nil_addr); val->ptr.func->closure.push_back(gc.nil_addr);// me
val->ptr.func->offset=val->ptr.func->closure.size();
*(++stack_top)=val; *(++stack_top)=val;
return; return;
} }
@ -868,6 +872,7 @@ void nasal_vm::run()
&nasal_vm::opr_nop, &nasal_vm::opr_nop,
&nasal_vm::opr_intg, &nasal_vm::opr_intg,
&nasal_vm::opr_intl, &nasal_vm::opr_intl,
&nasal_vm::opr_offset,
&nasal_vm::opr_loadg, &nasal_vm::opr_loadg,
&nasal_vm::opr_loadl, &nasal_vm::opr_loadl,
&nasal_vm::opr_pnum, &nasal_vm::opr_pnum,