|
|
|
@ -1108,16 +1108,24 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
DEFINE_OP(OP_BC_GEPZ) { |
|
|
|
|
int64_t ptr; |
|
|
|
|
int64_t ptr, iptr; |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
|
|
|
|
|
// negative values checking, valid for intermediate GEP calculations
|
|
|
|
|
if (off < 0) { |
|
|
|
|
cli_dbgmsg("bytecode warning: found GEP with negative offset %d!\n", off); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(inst->interp_op%5)) { |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
// how do negative offsets affect pointer intialization?
|
|
|
|
|
WRITE64(inst->dest, ptr_compose(stackid, |
|
|
|
|
inst->u.three[1]+off)); |
|
|
|
|
} else { |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
READ64(ptr, inst->u.three[1]); |
|
|
|
|
off += (ptr & 0x00000000ffffffff); |
|
|
|
|
iptr = (ptr & 0xffffffff00000000) + (uint64_t)(off); |
|
|
|
|
WRITE64(inst->dest, ptr+off); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
@ -1211,21 +1219,34 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct |
|
|
|
|
WRITE64(inst->dest, ptr); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
DEFINE_OP(OP_BC_GEP1) { |
|
|
|
|
int64_t ptr; |
|
|
|
|
if (!(inst->interp_op%5)) { |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
WRITE64(inst->dest, ptr_compose(stackid, |
|
|
|
|
inst->u.three[1]+off*inst->u.three[0])); |
|
|
|
|
} else { |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
READ64(ptr, inst->u.three[1]); |
|
|
|
|
WRITE64(inst->dest, ptr+off*inst->u.three[0]); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
DEFINE_OP(OP_BC_GEP1) { |
|
|
|
|
int64_t ptr, iptr; |
|
|
|
|
int32_t off; |
|
|
|
|
READ32(off, inst->u.three[2]); |
|
|
|
|
|
|
|
|
|
// negative values checking, valid for intermediate GEP calculations
|
|
|
|
|
if (off < 0) { |
|
|
|
|
cli_dbgmsg("bytecode warning: GEP with negative offset %d!\n", off); |
|
|
|
|
} |
|
|
|
|
if (inst->u.three[0] < 0) { |
|
|
|
|
cli_dbgmsg("bytecode warning: GEP with negative size %d!\n", inst->u.three[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(inst->interp_op%5)) { |
|
|
|
|
// how do negative offsets affect pointer intialization?
|
|
|
|
|
cli_dbgmsg("bytecode warning: untested case for GEP1\n"); |
|
|
|
|
off *= inst->u.three[0]; |
|
|
|
|
WRITE64(inst->dest, ptr_compose(stackid, |
|
|
|
|
inst->u.three[1]+off)); |
|
|
|
|
} else { |
|
|
|
|
READ64(ptr, inst->u.three[1]); |
|
|
|
|
off *= inst->u.three[0]; |
|
|
|
|
off += (ptr & 0x00000000ffffffff); |
|
|
|
|
iptr = (ptr & 0xffffffff00000000) + (uint64_t)(off); |
|
|
|
|
WRITE64(inst->dest, iptr); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/* TODO: implement OP_BC_GEP1, OP_BC_GEP2, OP_BC_GEPN */ |
|
|
|
|
default: |
|
|
|
|
cli_errmsg("Opcode %u of type %u is not implemented yet!\n", |
|
|
|
|