php扩展开发---使用PHP Embed SAPI实现Opcodes查看器

转载:http://www.laruence.com/2008/09/23/539.html
php version:5.6.22
mac

#include <stdio.h>
#include "../php/php-5.6.22/sapi/embed/php_embed.h"

#ifdef ZTS
    void ***tsrm_ls;
#endif


//#define BUFFER_LEN 10000;

char *opname(zend_uchar opcode)
{
    switch (opcode) {
        case ZEND_NOP:
            return "ZEND_NOP";
        case ZEND_ADD:
            return "ZEND_ADD";
        case ZEND_SUB:
            return "ZEND_SUB";
        case ZEND_MUL:
            return "ZEND_MUL";
        case ZEND_DIV:
            return "ZEND_DIV";
        case ZEND_MOD:
            return "ZEND_MOD";
        case ZEND_SL:
            return "ZEND_SL";
        case ZEND_SR:
            return "ZEND_SR";
        case ZEND_CONCAT:
            return "ZEND_CONCAT";
        case ZEND_BW_OR:
            return "ZEND_BW_OR";
        case ZEND_BW_AND:
            return "ZEND_BW_AND";
        case ZEND_BW_XOR:
            return "ZEND_BW_XOR";
        case ZEND_BW_NOT:
            return "ZEND_BW_NOT";
        case ZEND_BOOL_NOT:
            return "ZEND_BOOL_NOT";
        case ZEND_BOOL_XOR:
            return "ZEND_BOOL_XOR";
        case ZEND_IS_IDENTICAL:
            return "ZEND_IS_IDENTICAL";
        case ZEND_IS_NOT_IDENTICAL:
            return "ZEND_IS_NOT_IDENTICAL";
        case ZEND_IS_EQUAL:
            return "ZEND_IS_EQUAL";
        case ZEND_IS_NOT_EQUAL:
            return "ZEND_IS_NOT_EQUAL";
        case ZEND_IS_SMALLER:
            return "ZEND_IS_SMALLER";
        case ZEND_IS_SMALLER_OR_EQUAL:
            return "ZEND_IS_SMALLER_OR_EQUAL";
        case ZEND_CAST:
            return "ZEND_CAST";
        case ZEND_QM_ASSIGN:
            return "ZEND_QM_ASSIGN";
        case ZEND_ASSIGN_ADD:
            return "ZEND_ASSIGN_ADD";
        case ZEND_ASSIGN_SUB:
            return "ZEND_ASSIGN_SUB";
        case ZEND_ASSIGN_MUL:
            return "ZEND_ASSIGN_MUL";
        case ZEND_ASSIGN_DIV:
            return "ZEND_ASSIGN_DIV";
        case ZEND_ASSIGN_MOD:
            return "ZEND_ASSIGN_MOD";
        case ZEND_ASSIGN_SL:
            return "ZEND_ASSIGN_SL";
        case ZEND_ASSIGN_SR:
            return "ZEND_ASSIGN_SR";
        case ZEND_ASSIGN_CONCAT:
            return "ZEND_ASSIGN_CONCAT";
        case ZEND_ASSIGN_BW_OR:
            return "ZEND_ASSIGN_BW_OR";
        case ZEND_ASSIGN_BW_AND:
            return "ZEND_ASSIGN_BW_AND";
        case ZEND_ASSIGN_BW_XOR:
            return "ZEND_ASSIGN_BW_XOR";
        case ZEND_PRE_INC:
            return "ZEND_PRE_INC";
        case ZEND_PRE_DEC:
            return "ZEND_PRE_DEC";
        case ZEND_POST_INC:
            return "ZEND_POST_INC";
        case ZEND_POST_DEC:
            return "ZEND_POST_DEC";
        case ZEND_ASSIGN:
            return "ZEND_ASSIGN";
        case ZEND_ASSIGN_REF:
            return "ZEND_ASSIGN_REF";
        case ZEND_ECHO:
            return "ZEND_ECHO";
        case ZEND_PRINT:
            return "ZEND_PRINT";
        case ZEND_JMP:
            return "ZEND_JMP";
        case ZEND_JMPZ:
            return "ZEND_JMPZ";
        case ZEND_JMPNZ:
            return "ZEND_JMPNZ";
        case ZEND_JMPZNZ:
            return "ZEND_JMPZNZ";
        case ZEND_JMPZ_EX:
            return "ZEND_JMPZ_EX";
        case ZEND_JMPNZ_EX:
            return "ZEND_JMPNZ_EX";
        case ZEND_CASE:
            return "ZEND_CASE";
        case ZEND_SWITCH_FREE:
            return "ZEND_SWITCH_FREE";
        case ZEND_BRK:
            return "ZEND_BRK";
        case ZEND_CONT:
            return "ZEND_CONT";
        case ZEND_BOOL:
            return "ZEND_BOOL";
        case ZEND_INIT_STRING:
            return "ZEND_INIT_STRING";
        case ZEND_ADD_CHAR:
            return "ZEND_ADD_CHAR";
        case ZEND_ADD_STRING:
            return "ZEND_ADD_STRING";
        case ZEND_ADD_VAR:
            return "ZEND_ADD_VAR";
        case ZEND_BEGIN_SILENCE:
            return "ZEND_BEGIN_SILENCE";
        case ZEND_END_SILENCE:
            return "ZEND_END_SILENCE";
        case ZEND_INIT_FCALL_BY_NAME:
            return "ZEND_INIT_FCALL_BY_NAME";
        case ZEND_DO_FCALL:
            return "ZEND_DO_FCALL";
        case ZEND_DO_FCALL_BY_NAME:
            return "ZEND_DO_FCALL_BY_NAME";
        case ZEND_RETURN:
            return "ZEND_RETURN";
        case ZEND_RECV:
            return "ZEND_RECV";
        case ZEND_RECV_INIT:
            return "ZEND_RECV_INIT";
        case ZEND_SEND_VAL:
            return "ZEND_SEND_VAL";
        case ZEND_SEND_VAR:
            return "ZEND_SEND_VAR";
        case ZEND_SEND_REF:
            return "ZEND_SEND_REF";
        case ZEND_NEW:
            return "ZEND_NEW";
        case ZEND_INIT_NS_FCALL_BY_NAME:
            return "ZEND_INIT_NS_FCALL_BY_NAME";
        case ZEND_FREE:
            return "ZEND_FREE";
        case ZEND_INIT_ARRAY:
            return "ZEND_INIT_ARRAY";
        case ZEND_ADD_ARRAY_ELEMENT:
            return "ZEND_ADD_ARRAY_ELEMENT";
        case ZEND_INCLUDE_OR_EVAL:
            return "ZEND_INCLUDE_OR_EVAL";
        case ZEND_UNSET_VAR:
            return "ZEND_UNSET_VAR";
        case ZEND_UNSET_DIM:
            return "ZEND_UNSET_DIM";
        case ZEND_UNSET_OBJ:
            return "ZEND_UNSET_OBJ";
        case ZEND_FE_RESET:
            return "ZEND_FE_RESET";
        case ZEND_FE_FETCH:
            return "ZEND_FE_FETCH";
        case ZEND_EXIT:
            return "ZEND_EXIT";
        case ZEND_FETCH_R:
            return "ZEND_FETCH_R";
        case ZEND_FETCH_DIM_R:
            return "ZEND_FETCH_DIM_R";
        case ZEND_FETCH_OBJ_R:
            return "ZEND_FETCH_OBJ_R";
        case ZEND_FETCH_W:
            return "ZEND_FETCH_W";
        case ZEND_FETCH_DIM_W:
            return "ZEND_FETCH_DIM_W";
        case ZEND_FETCH_OBJ_W:
            return "ZEND_FETCH_OBJ_W";
        case ZEND_FETCH_RW:
            return "ZEND_FETCH_RW";
        case ZEND_FETCH_DIM_RW:
            return "ZEND_FETCH_DIM_RW";
        case ZEND_FETCH_OBJ_RW:
            return "ZEND_FETCH_OBJ_RW";
        case ZEND_FETCH_IS:
            return "ZEND_FETCH_IS";
        case ZEND_FETCH_DIM_IS:
            return "ZEND_FETCH_DIM_IS";
        case ZEND_FETCH_OBJ_IS:
            return "ZEND_FETCH_OBJ_IS";
        case ZEND_FETCH_FUNC_ARG:
            return "ZEND_FETCH_FUNC_ARG";
        case ZEND_FETCH_DIM_FUNC_ARG:
            return "ZEND_FETCH_DIM_FUNC_ARG";
        case ZEND_FETCH_OBJ_FUNC_ARG:
            return "ZEND_FETCH_OBJ_FUNC_ARG";
        case ZEND_FETCH_UNSET:
            return "ZEND_FETCH_UNSET";
        case ZEND_FETCH_DIM_UNSET:
            return "ZEND_FETCH_DIM_UNSET";
        case ZEND_FETCH_OBJ_UNSET:
            return "ZEND_FETCH_OBJ_UNSET";
        case ZEND_FETCH_DIM_TMP_VAR:
            return "ZEND_FETCH_DIM_TMP_VAR";
        case ZEND_FETCH_CONSTANT:
            return "ZEND_FETCH_CONSTANT";
        case ZEND_GOTO:
            return "ZEND_GOTO";
        case ZEND_EXT_STMT:
            return "ZEND_EXT_STMT";
        case ZEND_EXT_FCALL_BEGIN:
            return "ZEND_EXT_FCALL_BEGIN";
        case ZEND_EXT_FCALL_END:
            return "ZEND_EXT_FCALL_END";
        case ZEND_EXT_NOP:
            return "ZEND_EXT_NOP";
        case ZEND_TICKS:
            return "ZEND_TICKS";
        case ZEND_SEND_VAR_NO_REF:
            return "ZEND_SEND_VAR_NO_REF";
        case ZEND_CATCH:
            return "ZEND_CATCH";
        case ZEND_THROW:
            return "ZEND_THROW";
        case ZEND_FETCH_CLASS:
            return "ZEND_FETCH_CLASS";
        case ZEND_CLONE:
            return "ZEND_CLONE";
        case ZEND_RETURN_BY_REF:
            return "ZEND_RETURN_BY_REF";
        case ZEND_INIT_METHOD_CALL:
            return "ZEND_INIT_METHOD_CALL";
        case ZEND_INIT_STATIC_METHOD_CALL:
            return "ZEND_INIT_STATIC_METHOD_CALL";
        case ZEND_ISSET_ISEMPTY_VAR:
            return "ZEND_ISSET_ISEMPTY_VAR";
        case ZEND_ISSET_ISEMPTY_DIM_OBJ:
            return "ZEND_ISSET_ISEMPTY_DIM_OBJ";
        case ZEND_PRE_INC_OBJ:
            return "ZEND_PRE_INC_OBJ";
        case ZEND_PRE_DEC_OBJ:
            return "ZEND_PRE_DEC_OBJ";
        case ZEND_POST_INC_OBJ:
            return "ZEND_POST_INC_OBJ";
        case ZEND_POST_DEC_OBJ:
            return "ZEND_POST_DEC_OBJ";
        case ZEND_ASSIGN_OBJ:
            return "ZEND_ASSIGN_OBJ";
        case ZEND_INSTANCEOF:
            return "ZEND_INSTANCEOF";
        case ZEND_DECLARE_CLASS:
            return "ZEND_DECLARE_CLASS";
        case ZEND_DECLARE_INHERITED_CLASS:
            return "ZEND_DECLARE_INHERITED_CLASS";
        case ZEND_DECLARE_FUNCTION:
            return "ZEND_DECLARE_FUNCTION";
        case ZEND_RAISE_ABSTRACT_ERROR:
            return "ZEND_RAISE_ABSTRACT_ERROR";
        case ZEND_DECLARE_CONST:
            return "ZEND_DECLARE_CONST";
        case ZEND_ADD_INTERFACE:
            return "ZEND_ADD_INTERFACE";
        case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
            return "ZEND_DECLARE_INHERITED_CLASS_DELAYED";
        case ZEND_VERIFY_ABSTRACT_CLASS:
            return "ZEND_VERIFY_ABSTRACT_CLASS";
        case ZEND_ASSIGN_DIM:
            return "ZEND_ASSIGN_DIM";
        case ZEND_ISSET_ISEMPTY_PROP_OBJ:
            return "ZEND_ISSET_ISEMPTY_PROP_OBJ";
        case ZEND_HANDLE_EXCEPTION:
            return "ZEND_HANDLE_EXCEPTION";
        case ZEND_USER_OPCODE:
            return "ZEND_USER_OPCODE";
        case ZEND_JMP_SET:
            return "ZEND_JMP_SET";
        case ZEND_DECLARE_LAMBDA_FUNCTION:
            return "ZEND_DECLARE_LAMBDA_FUNCTION";
        case ZEND_ADD_TRAIT:
            return "ZEND_ADD_TRAIT";
        case ZEND_BIND_TRAITS:
            return "ZEND_BIND_TRAITS";
        case ZEND_SEPARATE:
            return "ZEND_SEPARATE";
        case ZEND_QM_ASSIGN_VAR:
            return "ZEND_QM_ASSIGN_VAR";
        case ZEND_JMP_SET_VAR:
            return "ZEND_JMP_SET_VAR";
        case ZEND_DISCARD_EXCEPTION:
            return "ZEND_DISCARD_EXCEPTION";
        case ZEND_YIELD:
            return "ZEND_YIELD";
        case ZEND_GENERATOR_RETURN:
            return "ZEND_GENERATOR_RETURN";
        case ZEND_FAST_CALL:
            return "ZEND_FAST_CALL";
        case ZEND_FAST_RET:
            return "ZEND_FAST_RET";
        case ZEND_RECV_VARIADIC:
            return "ZEND_RECV_VARIADIC";
        case ZEND_SEND_UNPACK:
            return "ZEND_SEND_UNPACK";
        case ZEND_POW:
            return "ZEND_POW";
        case ZEND_ASSIGN_POW:
            return "ZEND_ASSIGN_POW";
        default:
            return "unknow";
    }
}

char *format_zval(zval *z)
{
    static char buffer[10000];
    int len;

    switch(z->type) {
        case IS_NULL:
            return "NULL";
        case IS_LONG:
        case IS_BOOL:
            snprintf(buffer, 10000, "%d", z->value.lval);
            return buffer;
        case IS_DOUBLE:
            snprintf(buffer, 10000, "%f", z->value.dval);
            return buffer;
        case IS_STRING:
            snprintf(buffer, 10000, "\"%s\"", z->value.str.val);
            return buffer;
        case IS_ARRAY:
        case IS_OBJECT:
        case IS_RESOURCE:
        case IS_CONSTANT:
//        case IS_CONSTANT_ARRAY:
            return "";
        default:
            return "unknown";
    }
//    efree(buffer);
}

char * format_znode(znode_op *n, zend_uint type)
{
    static char buffer[10000];

    switch (type &~ EXT_TYPE_UNUSED) {
        case IS_CONST:
            return format_zval(n->zv);
            break;
        case IS_VAR:
            snprintf(buffer, 10000, "$%d",  n->var /sizeof(temp_variable));
            return buffer;
            break;
        case IS_TMP_VAR:
            snprintf(buffer, 10000, "~%d",  n->var /sizeof(temp_variable));
            return buffer;
            break;
        default:
            return "";
            break;
    }
//    efree(buffer);
}
void dump_op(zend_op *op, int num)
{
    printf("%5d  %5d %30s %40s %40s %40s\n", num, op->lineno,
           opname(op->opcode),
           format_znode(&op->op1 , op->op1_type),
           format_znode(&op->op2, op->op2_type),
           "sss") ;

}

void dump_op_array(zend_op_array *op_array)
{
    if(op_array) {
        int i;
        printf("%5s  %5s %30s %40s %40s %40s\n", "opnum", "line", "opcode", "op1", "op2", "result");
        for(i = 0; i < op_array->last; i++) {
            dump_op(&op_array->opcodes[i], i);
        }
    }
}

int main(int argc, char **argv)
{
    zend_op_array *op_array;
    zend_file_handle file_handle;

    if(argc != 2) {
        printf("usage:  op_dumper <script>\n");
        return 1;
    }
    PHP_EMBED_START_BLOCK(argc,argv);
                    printf("Script: %s\n", argv[1]);
                    file_handle.filename = argv[1];
                    file_handle.free_filename = 0;
                    file_handle.type = ZEND_HANDLE_FILENAME;
                    file_handle.opened_path = NULL;
                    op_array =  zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC);
                    if(!op_array) {
                        printf("Error parsing script: %s\n", file_handle.filename);
                        return 1;
                    }
                    dump_op_array(op_array);
                    destroy_op_array(op_array TSRMLS_CC);
                    efree(op_array);
                    zend_destroy_file_handle(&file_handle TSRMLS_CC);
    PHP_EMBED_END_BLOCK();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值