diff --git a/source/mach.c b/source/mach.c index 2336cf30..f180843f 100644 --- a/source/mach.c +++ b/source/mach.c @@ -608,6 +608,11 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { int ki = mach_cpool_add_str(cs, prop_name); + /* If ki overflows 8-bit C field, load key into R(base+1) register */ + if (ki >= 0xFF) { + mach_emit(cs, MACH_ABx(MACH_LOADK, base + 1, ki)); + } + /* Compile args into R(base+2)..R(base+1+nargs) */ for (int i = 0; i < nargs; i++) { int arg_reg = mach_reserve_reg(cs); @@ -617,7 +622,7 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { mach_emit(cs, MACH_ABC(MACH_MOVE, arg_reg, r, 0)); } - mach_emit(cs, MACH_ABC(MACH_CALLMETHOD, base, nargs, ki)); + mach_emit(cs, MACH_ABC(MACH_CALLMETHOD, base, nargs, ki >= 0xFF ? 0xFF : ki)); mach_free_reg_to(cs, save_freereg); if (dest >= 0 && dest != base) mach_emit(cs, MACH_ABC(MACH_MOVE, dest, base, 0)); @@ -887,13 +892,25 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { if (cs->freereg <= obj_r) cs->freereg = obj_r + 1; int ki = mach_cpool_add_str(cs, prop_name); int val_r = mach_reserve_reg(cs); - mach_emit(cs, MACH_ABC(MACH_GETFIELD, val_r, obj_r, ki)); + if (ki < 256) { + mach_emit(cs, MACH_ABC(MACH_GETFIELD, val_r, obj_r, ki)); + } else { + int kr = mach_reserve_reg(cs); + mach_emit(cs, MACH_ABx(MACH_LOADK, kr, ki)); + mach_emit(cs, MACH_ABC(MACH_GETINDEX, val_r, obj_r, kr)); + } if (is_postfix) mach_emit(cs, MACH_ABC(MACH_MOVE, dest, val_r, 0)); mach_emit(cs, MACH_ABC(inc_op, val_r, val_r, 0)); if (!is_postfix) mach_emit(cs, MACH_ABC(MACH_MOVE, dest, val_r, 0)); - mach_emit(cs, MACH_ABC(MACH_SETFIELD, obj_r, ki, val_r)); + if (ki < 256) { + mach_emit(cs, MACH_ABC(MACH_SETFIELD, obj_r, ki, val_r)); + } else { + int kr = mach_reserve_reg(cs); + mach_emit(cs, MACH_ABx(MACH_LOADK, kr, ki)); + mach_emit(cs, MACH_ABC(MACH_SETINDEX, obj_r, kr, val_r)); + } mach_free_reg_to(cs, save); return dest; } @@ -1063,7 +1080,13 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { int val_r = mach_compile_expr(cs, right, dest); if (prop_name) { int ki = mach_cpool_add_str(cs, prop_name); - mach_emit(cs, MACH_ABC(MACH_SETFIELD, obj_r, ki, val_r)); + if (ki < 256) { + mach_emit(cs, MACH_ABC(MACH_SETFIELD, obj_r, ki, val_r)); + } else { + int kr = mach_reserve_reg(cs); + mach_emit(cs, MACH_ABx(MACH_LOADK, kr, ki)); + mach_emit(cs, MACH_ABC(MACH_SETINDEX, obj_r, kr, val_r)); + } } mach_free_reg_to(cs, save); return val_r; @@ -1111,7 +1134,13 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { int obj_r = mach_compile_expr(cs, obj_expr, -1); if (prop_name) { int ki = mach_cpool_add_str(cs, prop_name); - mach_emit(cs, MACH_ABC(MACH_GETFIELD, dest, obj_r, ki)); + if (ki < 256) { + mach_emit(cs, MACH_ABC(MACH_GETFIELD, dest, obj_r, ki)); + } else { + int kr = mach_reserve_reg(cs); + mach_emit(cs, MACH_ABx(MACH_LOADK, kr, ki)); + mach_emit(cs, MACH_ABC(MACH_GETINDEX, dest, obj_r, kr)); + } } mach_free_reg_to(cs, save); return dest; @@ -1155,7 +1184,13 @@ static int mach_compile_expr(MachCompState *cs, cJSON *node, int dest) { int save = cs->freereg; int vr = mach_compile_expr(cs, val_node, -1); int ki = mach_cpool_add_str(cs, key); - mach_emit(cs, MACH_ABC(MACH_SETFIELD, dest, ki, vr)); + if (ki < 256) { + mach_emit(cs, MACH_ABC(MACH_SETFIELD, dest, ki, vr)); + } else { + int kr = mach_reserve_reg(cs); + mach_emit(cs, MACH_ABx(MACH_LOADK, kr, ki)); + mach_emit(cs, MACH_ABC(MACH_SETINDEX, dest, kr, vr)); + } mach_free_reg_to(cs, save); } }