#include "zend_compile.h"
#include "phpdbg_opcode.h"
#include "phpdbg_utils.h"
+#include "ext/standard/php_string.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
asprintf(&decode, "@" ZEND_ULONG_FMT, id);
} break;
- case IS_CONST:
- asprintf(&decode, "C%u", phpdbg_decode_literal(ops, RT_CONSTANT(ops, *op)));
- break;
+ case IS_CONST: {
+ zval *literal = RT_CONSTANT(ops, *op);
+ switch (Z_TYPE_P(literal)) {
+ case IS_UNDEF:
+ decode = zend_strndup("", 0);
+ break;
+ case IS_NULL:
+ decode = zend_strndup(ZEND_STRL("null"));
+ break;
+ case IS_FALSE:
+ decode = zend_strndup(ZEND_STRL("false"));
+ break;
+ case IS_TRUE:
+ decode = zend_strndup(ZEND_STRL("true"));
+ break;
+ case IS_LONG:
+ asprintf(&decode, "%lld", Z_LVAL_P(literal));
+ break;
+ case IS_DOUBLE:
+ asprintf(&decode, "%.*G", 14, Z_DVAL_P(literal));
+ break;
+ case IS_STRING: {
+ int i;
+ zend_string *str = php_addcslashes(Z_STR_P(literal), 0, "\\\"", 2);
+ for (i = 0; i < str->len; i++) {
+ if (str->val[i] < 32) {
+ str->val[i] = ' ';
+ }
+ }
+ asprintf(&decode, "\"%.*s\"%c", str->len <= 18 ? (int) str->len : 17, str->val, str->len <= 18 ? 0 : '+');
+ zend_string_release(str);
+ } break;
+ case IS_RESOURCE:
+ asprintf(&decode, "Rsrc #%d", Z_RES_HANDLE_P(literal));
+ break;
+ case IS_ARRAY:
+ asprintf(&decode, "array(%d)", zend_hash_num_elements(Z_ARR_P(literal)));
+ break;
+ case IS_OBJECT: {
+ zend_string *str = Z_OBJCE_P(literal)->name;
+ asprintf(&decode, "%.*s%c", str->len <= 18 ? (int) str->len : 18, str->val, str->len <= 18 ? 0 : '+');
+ } break;
+ case IS_CONSTANT:
+ decode = zend_strndup(ZEND_STRL("<constant>"));
+ break;
+ case IS_CONSTANT_AST:
+ decode = zend_strndup(ZEND_STRL("<ast>"));
+ break;
+ default:
+ asprintf(&decode, "unknown type: %d", Z_TYPE_P(literal));
+ break;
+ }
+ } break;
case IS_UNUSED:
asprintf(&decode, "<unused>");
switch (op->opcode) {
case ZEND_JMP:
-#ifdef ZEND_GOTO
case ZEND_GOTO:
-#endif
-#ifdef ZEND_FAST_CALL
case ZEND_FAST_CALL:
-#endif
- asprintf(&decode[1], "J%ld", OP_JMP_ADDR(op, op->op1) - ops->opcodes);
+ asprintf(&decode[1], "J%ld", OP_JMP_ADDR(op, op->op1) - ops->opcodes);
goto format;
case ZEND_JMPZNZ:
- decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
- asprintf(&decode[2], "J%u or J%" PRIu32, op->op2.opline_num, op->extended_value);
+ decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
+ asprintf(&decode[2], "J%u or J%" PRIu32, op->op2.opline_num, op->extended_value);
goto result;
case ZEND_JMPZ:
case ZEND_JMPNZ:
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
-
-#ifdef ZEND_JMP_SET
case ZEND_JMP_SET:
-#endif
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
asprintf(&decode[2], "J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes);
- goto result;
+ goto result;
case ZEND_RECV_INIT:
goto result;
- default: {
- decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
- decode[2] = phpdbg_decode_op(ops, &op->op2, op->op2_type, vars);
+ default:
+ decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
+ decode[2] = phpdbg_decode_op(ops, &op->op2, op->op2_type, vars);
result:
- decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars);
+ decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars);
format:
- asprintf(&decode[0],
- "%-20s %-20s %-20s",
- decode[1] ? decode[1] : "",
- decode[2] ? decode[2] : "",
- decode[3] ? decode[3] : "");
- }
+ asprintf(&decode[0],
+ "%-20s %-20s %-20s",
+ decode[1] ? decode[1] : "",
+ decode[2] ? decode[2] : "",
+ decode[3] ? decode[3] : "");
}
if (decode[1])
end = op_array->last-1;
if (method->common.scope) {
- phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s",
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "L%d-%d %s::%s() %s",
op_array->line_start,
op_array->line_end,
method->common.scope->name->val,
method->common.function_name->val,
op_array->filename ? op_array->filename->val : "unknown");
} else {
- phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s",
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "L%d-%d %s() %s",
method->common.function_name ? op_array->line_start : 0,
method->common.function_name ? op_array->line_end : 0,
method->common.function_name ? method->common.function_name->val : "{main}",
do {
char *decode = phpdbg_decode_opline(op_array, opline, &vars);
if (decode != NULL) {
- phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", "\t\tL%u\t%p %-30s %s",
- opline->lineno,
- opline,
- phpdbg_decode_opcode(opline->opcode),
- decode);
+ if (PHPDBG_G(flags) & PHPDBG_PRINT_OPLINE_ADDR) {
+ phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", " L%-5u %p %-36s %s",
+ opline->lineno,
+ opline,
+ phpdbg_decode_opcode(opline->opcode),
+ decode);
+ } else {
+ phpdbg_writeln("print", "line=\"%u\" opcode=\"%s\" op=\"%s\"", " L%-5u %-36s %s",
+ opline->lineno,
+ phpdbg_decode_opcode(opline->opcode),
+ decode);
+ }
free(decode);
} else {
- phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "\tFailed to decode opline %16p", opline);
+ phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "Failed to decode opline %16p", opline);
}
opline++;
} while (opcode++ < end);