static PHP_METHOD(Operand, getNumber) { php_inspector_operand_t *operand = php_inspector_operand_this(); php_inspector_opline_t *opline = php_inspector_opline_fetch_from(Z_OBJ(operand->opline)); php_inspector_scope_t *scope = php_inspector_scope_fetch_from(Z_OBJ(opline->scope)); switch(opline->opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: if (operand->which == PHP_INSPECTOR_OPLINE_OP1) { ZEND_PASS_TWO_UNDO_JMP_TARGET(scope->ops, opline->opline, *operand->op); ZVAL_LONG(return_value, operand->op->num); ZEND_PASS_TWO_UPDATE_JMP_TARGET(scope->ops, opline->opline, *operand->op); break; } case ZEND_JMPZNZ: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_NEW: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: if (operand->which == PHP_INSPECTOR_OPLINE_OP2) { ZEND_PASS_TWO_UNDO_JMP_TARGET(scope->ops, opline->opline, *operand->op); ZVAL_LONG(return_value, operand->op->num); ZEND_PASS_TWO_UPDATE_JMP_TARGET(scope->ops, opline->opline, *operand->op); break; } default: { if (operand->type & IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(scope->ops, *operand->op); ZVAL_LONG(return_value, operand->op->num); ZEND_PASS_TWO_UPDATE_CONSTANT(scope->ops, *operand->op); } else if (operand->type & IS_TMP_VAR|IS_VAR) { ZVAL_LONG(return_value, EX_VAR_TO_NUM(operand->op->num - scope->ops->last_var)); } else if (operand->type & IS_CV) { ZVAL_LONG(return_value, EX_VAR_TO_NUM(operand->op->num)); } } } }
static void zend_accel_optimize(zend_op_array *op_array, zend_optimizer_ctx *ctx) { zend_op *opline, *end; /* Revert pass_two() */ opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { if (opline->op1_type == IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline->op1); } if (opline->op2_type == IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline->op2); } switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, ZEND_OP1(opline)); break; case ZEND_JMPZNZ: /* relative offset into absolute index */ opline->extended_value = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value); /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_NEW: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, ZEND_OP2(opline)); break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: opline->extended_value = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value); break; } opline++; } /* Do actual optimizations */ zend_optimize(op_array, ctx); /* Redo pass_two() */ opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { if (opline->op1_type == IS_CONST) { ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1); } if (opline->op2_type == IS_CONST) { ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2); } switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, ZEND_OP1(opline)); break; case ZEND_JMPZNZ: /* absolute index to relative offset */ opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_NEW: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, ZEND_OP2(opline)); break; case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); break; } ZEND_VM_SET_OPCODE_HANDLER(opline); opline++; } }