深入PHP核心之opcode handler

來源:互聯網
上載者:User

標籤:

1、opcode結構

在Zend/zend_compile.h檔案下

struct _zend_op {        opcode_handler_t handler;        znode_op op1;        znode_op op2;        znode_op result;        ulong extended_value;        uint lineno;        zend_uchar opcode;        zend_uchar op1_type;        zend_uchar op2_type;        zend_uchar result_type;};

opcode_handler_t是函數指標為opcode定義了執行方式,每一種opcode都對應一個的handler,也就是函數的入口地址,這些地址都儲存在labels數組裡面

比如賦值:$a = 1

通過vld可以看到

op = ASSIGN 那麼對應到zend engine  操作為ZEND_ASSIGN ,對應的編號為38的  可以在Zend/zend_vm_opcodes.h中查到定義  

#define ZEND_ASSIGN                           38

可以推算出 op_type為const和cv,然後就能確定handler為函數ZEND_ASSIGN_SPEC_CV_CONST_HANDLER

然後就可以定位到具體的執行函數了

static int ZEND_FASTCALL  ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS){        USE_OPLINE        zval *value;        zval **variable_ptr_ptr;        SAVE_OPLINE();        value = opline->op2.zv;……}

 zend engine在執行的是首先會調用 zend_startup() 位於(zend.c中),然後初始化zend_init_opcodes_handlers()

int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC) /* {{{ */{#ifdef ZTS        zend_compiler_globals *compiler_globals;        zend_executor_globals *executor_globals;        extern ZEND_API ts_rsrc_id ini_scanner_globals_id;        extern ZEND_API ts_rsrc_id language_scanner_globals_id;#else        extern zend_ini_scanner_globals ini_scanner_globals;        extern zend_php_scanner_globals language_scanner_globals;#endif        start_memory_manager(TSRMLS_C);        virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */#if defined(__FreeBSD__) || defined(__DragonFly__)        /* FreeBSD and DragonFly floating point precision fix */        fpsetmask(0);#endif        zend_startup_strtod();        zend_startup_extensions_mechanism();        /* Set up utility functions and values */        zend_error_cb = utility_functions->error_function;        zend_printf = utility_functions->printf_function;        zend_write = (zend_write_func_t) utility_functions->write_function;        zend_fopen = utility_functions->fopen_function;        if (!zend_fopen) {                zend_fopen = zend_fopen_wrapper;        }        zend_stream_open_function = utility_functions->stream_open_function;        zend_message_dispatcher_p = utility_functions->message_handler;#ifndef ZEND_SIGNALS        zend_block_interruptions = utility_functions->block_interruptions;        zend_unblock_interruptions = utility_functions->unblock_interruptions;#endif        zend_get_configuration_directive_p = utility_functions->get_configuration_directive;        zend_ticks_function = utility_functions->ticks_function;        zend_on_timeout = utility_functions->on_timeout;        zend_unblock_interruptions = utility_functions->unblock_interruptions;#endif        zend_get_configuration_directive_p = utility_functions->get_configuration_directive;        zend_ticks_function = utility_functions->ticks_function;        zend_on_timeout = utility_functions->on_timeout;        zend_vspprintf = utility_functions->vspprintf_function;        zend_getenv = utility_functions->getenv_function;        zend_resolve_path = utility_functions->resolve_path_function;#if HAVE_DTRACE/* build with dtrace support */        zend_compile_file = dtrace_compile_file;        zend_execute_ex = dtrace_execute_ex;        zend_execute_internal = dtrace_execute_internal;#else        zend_compile_file = compile_file;        zend_execute_ex = execute_ex;        zend_execute_internal = NULL;#endif /* HAVE_SYS_SDT_H */        zend_compile_string = compile_string;        zend_throw_exception_hook = NULL;        zend_init_opcodes_handlers();……} 

然後會初始化labels數組,這個數組的類型是opcode_handler_t (zend_compile.h)

void zend_init_opcodes_handlers(void){  static const opcode_handler_t labels[] = {        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,        ZEND_NOP_SPEC_HANDLER,    ……    }    zend_opcode_handlers = (opcode_handler_t*)labels;}//Zend/zend_vm_execute.h

 opcode_handler_t

typedef int (*user_opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);extern ZEND_API opcode_handler_t *zend_opcode_handlers;

這個結構體包含了近4000個成員,這些成員都是函數名稱,每次執行一個opcode的時候都要到這個labels裡面找對應的handler處理函數

op_type函數

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_type] * 5 + zend_vm_decode[op->op2_type]];}ZEND_API void zend_vm_set_opcode_handler(zend_op* op){        op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);}

返回對應的handler

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

 

深入PHP核心之opcode handler

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.