diff --git a/nasal_codegen.h b/nasal_codegen.h index ca58065..6056b4c 100644 --- a/nasal_codegen.h +++ b/nasal_codegen.h @@ -6,6 +6,7 @@ enum op_code op_nop, // do nothing and end the vm main loop op_intg, // global scope size op_intl, // local scope size + op_offset, // offset of local scope of function in closure op_loadg, // load global symbol value op_loadl, // load local symbol value op_pnum, // push constant number to the stack @@ -75,6 +76,7 @@ struct {op_nop, "nop "}, {op_intg, "intg "}, {op_intl, "intl "}, + {op_offset, "offset"}, {op_loadg, "loadg "}, {op_loadl, "loadl "}, {op_pnum, "pnum "}, @@ -373,6 +375,10 @@ void nasal_codegen::func_gen(nasal_ast& ast) // this symbol's index will be 0 if(local.size()==1) add_sym("me"); + + gen(op_offset,0); + for(auto i:local) + exec_code.back().num+=i.size(); // generate parameter list for(auto tmp:ast.get_children()[0].get_children()) { diff --git a/nasal_vm.h b/nasal_vm.h index e5f3be1..73114d3 100644 --- a/nasal_vm.h +++ b/nasal_vm.h @@ -21,6 +21,7 @@ private: void opr_nop(); void opr_intg(); void opr_intl(); + void opr_offset(); void opr_loadg(); void opr_loadl(); void opr_pnum(); @@ -146,15 +147,19 @@ void nasal_vm::opr_nop() } void nasal_vm::opr_intg() { - gc.global.resize(exec_code[pc].num); + gc.global.resize(exec_code[pc].num,gc.nil_addr); return; } 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 return; } +void nasal_vm::opr_offset() +{ + (*stack_top)->ptr.func->offset=exec_code[pc].num; +} void nasal_vm::opr_loadg() { gc.global[exec_code[pc].num]=*stack_top--; @@ -209,8 +214,7 @@ void nasal_vm::opr_newf() if(!gc.local.empty()) val->ptr.func->closure=gc.local.back(); else - val->ptr.func->closure.push_back(gc.nil_addr); - val->ptr.func->offset=val->ptr.func->closure.size(); + val->ptr.func->closure.push_back(gc.nil_addr);// me *(++stack_top)=val; return; } @@ -868,6 +872,7 @@ void nasal_vm::run() &nasal_vm::opr_nop, &nasal_vm::opr_intg, &nasal_vm::opr_intl, + &nasal_vm::opr_offset, &nasal_vm::opr_loadg, &nasal_vm::opr_loadl, &nasal_vm::opr_pnum,