19.opcode处理函数查找

这里写图片描述

ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
...
zend_vm_enter:
....
if ((ret = EX(opline)->handler(execute_data TSRMLS_CC)) > 0) {
            switch (ret) {
                case 1:
                    EG(in_execution) = original_in_execution;
                    return;
                case 2:
                    op_array = EG(active_op_array);
                    goto zend_vm_enter;
                case 3:
                    execute_data = EG(current_execute_data);
                default:
                    break;
            }
}
...
}

这里写图片描述

static opcode_handler_t
zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op)
{
        static const int zend_vm_decode[] = {
            _UNUSED_CODE, /* 0              */
            _CONST_CODE,  /* 1 = IS_CONST   */
            _TMP_CODE,    /* 2 = IS_TMP_VAR */
            _UNUSED_CODE, /* 3              */
            _VAR_CODE,    /* 4 = IS_VAR     */
            _UNUSED_CODE, /* 5              */
            _UNUSED_CODE, /* 6              */
            _UNUSED_CODE, /* 7              */
            _UNUSED_CODE, /* 8 = IS_UNUSED  */
            _UNUSED_CODE, /* 9              */
            _UNUSED_CODE, /* 10             */
            _UNUSED_CODE, /* 11             */
            _UNUSED_CODE, /* 12             */
            _UNUSED_CODE, /* 13             */
            _UNUSED_CODE, /* 14             */
            _UNUSED_CODE, /* 15             */
            _CV_CODE      /* 16 = IS_CV     */
        };  
        return zend_opcode_handlers[
             opcode * 25 + zend_vm_decode[op->op1.op_type] * 5
                     + zend_vm_decode[op->op2.op_type]];
}

这里写图片描述

//函数调用:
DO_FCALL  ==>  ZEND_DO_FCALL_SPEC_CONST_HANDLER

//变量赋值:
ASSIGN     =>      ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER
                   ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER
                   ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER
                   ZEND_ASSIGN_SPEC_VAR_CV_HANDLER            
//变量加法:
ASSIGN_SUB =>   ZEND_ASSIGN_SUB_SPEC_VAR_CONST_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_VAR_TMP_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_VAR_VAR_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_VAR_CV_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_UNUSED_TMP_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_UNUSED_VAR_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_UNUSED_UNUSED_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_UNUSED_CV_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_CV_CONST_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_CV_TMP_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_CV_VAR_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_HANDLER,
                    ZEND_ASSIGN_SUB_SPEC_CV_CV_HANDLER,

这里写图片描述

static opcode_handler_t
zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* op)
{
        static const int zend_vm_decode[] = {
            _UNUSED_CODE, /* 0              */
            _CONST_CODE,  /* 1 = IS_CONST   */
            _TMP_CODE,    /* 2 = IS_TMP_VAR */
            _UNUSED_CODE, /* 3              */
            _VAR_CODE,    /* 4 = IS_VAR     */
            _UNUSED_CODE, /* 5              */
            _UNUSED_CODE, /* 6              */
            _UNUSED_CODE, /* 7              */
            _UNUSED_CODE, /* 8 = IS_UNUSED  */
            _UNUSED_CODE, /* 9              */
            _UNUSED_CODE, /* 10             */
            _UNUSED_CODE, /* 11             */
            _UNUSED_CODE, /* 12             */
            _UNUSED_CODE, /* 13             */
            _UNUSED_CODE, /* 14             */
            _UNUSED_CODE, /* 15             */
            _CV_CODE      /* 16 = IS_CV     */
        };  

     //很显然,我们把opcode和相对应的写到了/tmp/php.log文件中
     int op_index;
     op_index = opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type];

     FILE *stream;
     if((stream = fopen("/tmp/php.log", "a+")) != NULL){
         fprintf(stream, "opcode: %d , zend_opcode_handlers_index:%d\n", opcode, op_index);
     }    
     fclose(stream);


        return zend_opcode_handlers[
             opcode * 25 + zend_vm_decode[op->op1.op_type] * 5
                     + zend_vm_decode[op->op2.op_type]];
}

这里写图片描述


http://www.php-internals.com/book/?p=chapt02/02-03-03-from-opcode-to-handler

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值