diff --git a/maple_engine/src/invoke_method.cpp b/maple_engine/src/invoke_method.cpp index 7bfd034e3c5dbd0528a6019ae51c86405f239b7b..946f5270547a6f1b70602a2d482a60361715c5cd 100644 --- a/maple_engine/src/invoke_method.cpp +++ b/maple_engine/src/invoke_method.cpp @@ -138,6 +138,7 @@ void collect_stack_refs(void* bp, std::set& refs); #endif // !MPLPRE_C extern "C" void MCC_DecRef_NaiveRCFast(void* obj); +extern "C" void MCC_IncRef_NaiveRCFast(void* obj); MValue maple_invoke_method(const method_header_t* const mir_header, const MFunction *caller) { // Array of labels for threaded interpretion @@ -244,7 +245,7 @@ label_OP_addrof: res.x.a64 = (uint8_t*)&arg.x; } else { MValue &local = MLOCALS(-idx); - local.ptyp = (PrimType)func.header->primtype_table[func.header->formals_num - idx]; + local.ptyp = (PrimType)func.header->primtype_table[(func.header->formals_num - idx)*2]; // both formals and locals are 2B each res.x.a64 = (uint8_t*)&local.x; } MPUSH(res); @@ -1229,9 +1230,17 @@ label_exception_handler: } } - { // Exception not handled; do reference counting cleanup for localrefvars - uint8_t* locals_table = (uint8_t*)&func.header->primtype_table + func.header->formals_num; // find start of table for locals; skip formals, which are 1B each + { // Exception not handled; do reference counting cleanup for formals and localrefvars + uint8_t* formals_table = (uint8_t*)&func.header->primtype_table; + for(int i=0; iformals_num; i++) { + if(formals_table[2*i+1] == 1) { // 2B for each formal; clean up if the 2nd byte is 1. + MValue &arg = MARGS(i+1); // with MARGS(), formals index starts with 1 + void* ref = (void*)arg.x.a64; + MCC_DecRef_NaiveRCFast(ref); + } + } + uint8_t* locals_table = (uint8_t*)&func.header->primtype_table + func.header->formals_num*2; // find start of table for locals; skip formals, which are 2B each for(int i=0; ilocals_num; i++) { if(locals_table[2*i+1] == 2 || locals_table[2*i+1] == 3) { // 2B for each local var; clean up if the 2nd byte is 2 or 3. if(func.operand_stack[i].ptyp != PTY_a64) @@ -1240,6 +1249,13 @@ label_exception_handler: if(ref && ref != thrownval) { MCC_DecRef_NaiveRCFast(ref); } + } else if(locals_table[2*i+1] == 4 || locals_table[2*i+1] == 5) { + if(func.operand_stack[i].ptyp != PTY_a64) + continue; + void* ref = (void*)func.operand_stack[i].x.a64; + if(ref) { + MCC_IncRef_NaiveRCFast(ref); + } } } } diff --git a/maple_engine/src/mfunction.cpp b/maple_engine/src/mfunction.cpp index 637c3f1a6be48bcd7798c29b4f683e63e2164cb5..a79f3cfdcdf57ab6d4f65baf424bd57a53c5bc49 100644 --- a/maple_engine/src/mfunction.cpp +++ b/maple_engine/src/mfunction.cpp @@ -73,7 +73,7 @@ namespace maple { sp = header->locals_num; // for all locals, return value, throw value and evaluation stack operand_stack.resize(sp + header->eval_depth + 1, {.x.i64 = 0, PTY_void}); - var_names = (char*)(&header->primtype_table) + header->formals_num + header->locals_num*2; // locals_num*2 because each entry has 2 bytes + var_names = (char*)(&header->primtype_table) + header->formals_num*2 + header->locals_num*2; // *2 because formals and locals each have 2 bytes if(var_names >= (char*)pc) var_names = nullptr; } diff --git a/maple_engine/src/shimfunction.cpp b/maple_engine/src/shimfunction.cpp index 523d41f6c76eeaa2a678e37a1cd7b0ff421f8c83..b45474718cd564072b201f088937158b5cc88ac5 100644 --- a/maple_engine/src/shimfunction.cpp +++ b/maple_engine/src/shimfunction.cpp @@ -57,7 +57,7 @@ extern "C" int64_t __engine_shim(int64_t first_arg, ...) { uint16_t arg_idx = 0; while(arg_idx < arg_num) { // Process all other argements - val.ptyp = (PrimType)(header->primtype_table[arg_idx]); + val.ptyp = (PrimType)(header->primtype_table[arg_idx*2]); // each argument has 2B switch(val.ptyp) { case PTY_i8: val.x.i8 = va_arg(args, int);