Home php教程 PHP开发 PHP Kernel Analysis (7) - Extension

PHP Kernel Analysis (7) - Extension

Dec 19, 2016 am 11:28 AM

Abstract: The php version read here is PHP-7.1.0 RC3, and the platform for reading the code is linux. Let's study this extension of reflection. The reflection extension directory exists in: ext/reflection. In fact, the code inside is very simple. One .h file and one .c file. Let's take a look at the .c file first, and we will see a lot...

The php version read here is PHP-7.1.0 RC3, and the platform for reading the code is linux.

Let’s study the reflection extension.

The reflection extension directory exists in: ext/reflection. In fact, the code inside is very simple. One .h file and one .c file.

Let’s take a look at the .c file first, and you will see a lot of macros corresponding to ZEND_METHOD

1    ZEND_METHOD(reflection_function, getReturnType)    
2    {    
3         ...    
4    }
Copy after login

:

1    #define ZEND_METHOD(classname, name)     ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))    
2    #define ZEND_NAMED_FUNCTION(name)          void name(INTERNAL_FUNCTION_PARAMETERS)    
3    #define ZEND_MN(name) zim_##name    
4    #define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value
Copy after login

The ## here represents the connection, and the expansion actually means:

void zim_reflection_function_getReturnType(zend_execute_data *execute_data, zval *return_value)
Copy after login

In short, we are using ZEND_METHOD here A function zim_reflection_function_getReturnType is defined, so how is it called here from the execution code?

Okay, so we can’t see the extended call stack here. Then let's use gdb to look at the call stack.

Write a script that uses reflection extension:

  1 <?php
  2
  3 class B
  4 {  
  5     public function test(): B
  6     {  
  7
  8     }  
  9 }
  10
  11 function getB(): B
  12 {
  13
  14 }
  15
  16 $rc = new ReflectionMethod(&#39;B&#39;, &#39;test&#39;);
  17 var_dump((string)$rc->getReturnType(), $rc->getReturnType());
  18
  19 $rc = new ReflectionFunction(&#39;getB&#39;);
  20 var_dump((string)$rc->getReturnType(), $rc->getReturnType());
Copy after login

Use gdb for management. We looked at the extended definition of getReturnType. There is a function reflection_type_factory in the extension code, so we used this for management.

01    (gdb) b reflection_type_factory    
02    
03    (gdb) run -f /home/xiaoju/software/php7/demo/echo.php    
04    
05    (gdb) s    
06    
07    (gdb) bt    
08    #0  reflection_type_factory (fptr=0x7ffff6004210, closure_object=0x0, arg_info=0x7ffff6079048,    
09        object=0x7ffff60140d0) at /home/xiaoju/webroot/php-src/php-src-master/ext/reflection/php_reflection.c:1280    
10    #1  0x0000000000760d23 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (execute_data=0x7ffff6014030)    
11        at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:1097    
12    #2  0x000000000073fc88 in execute_ex (ex=<value optimized="" out="">)    
13        at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:432    
14    #3  0x000000000078b670 in zend_execute (op_array=0x7ffff60782a0, return_value=<value optimized="" out="">)    
15        at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:474    
16    #4  0x00000000006e48a3 in zend_execute_scripts (type=8, retval=0x0, file_count=3)    
17        at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend.c:1464    
18    #5  0x0000000000684870 in php_execute_script (primary_file=0x7fffffffe090)    
19        at /home/xiaoju/webroot/php-src/php-src-master/main/main.c:2541    
20    #6  0x000000000078e9ea in do_cli (argc=3, argv=0xee1bc0)    
21        at /home/xiaoju/webroot/php-src/php-src-master/sapi/cli/php_cli.c:994    
22    #7  0x000000000078f1ea in main (argc=3, argv=0xee1bc0)    
23        at /home/xiaoju/webroot/php-src/php-src-master/sapi/cli/php_cli.c:1387    
24    (gdb)</value></value>
Copy after login

Okay, you can see this context very clearly:

main->do_cli->php_execute_scripts->zend_execute->execute_ex->ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER->reflection_type_factory
Copy after login

For main, do_cli, php_execute_scripts, zend_execute, execute_ex based on the previous main function analysis, we can easily understand the role of each function. In other words, execute_ex is the most important function that actually calls opcode.

Compare the opcode of this script:

01    L1-21 {main}() /home/xiaoju/software/php7/demo/echo.php - 0x7fd6a127f000 + 30 ops    
02    L3    #0     NOP    
03    L11   #1     NOP    
04    L16   #2     NEW                     "ReflectionMethod"                        @1    
05    L16   #3     SEND_VAL_EX             "B"                  1    
06    L16   #4     SEND_VAL_EX             "test"               2    
07    L16   #5     DO_FCALL    
08    L16   #6     ASSIGN                  $rc                  @1    
09    L17   #7     INIT_FCALL              112                  "var_dump"    
10    L17   #8     INIT_METHOD_CALL        $rc                  "getReturnType"    
11    L17   #9     DO_FCALL                                                          @4    
12    L17   #10    CAST                    @4                                        ~5    
13    L17   #11    SEND_VAL                ~5                   1    
14    L17   #12    INIT_METHOD_CALL        $rc                  "getReturnType"    
15    L17   #13    DO_FCALL                                                          @6    
16    L17   #14    SEND_VAR                @6                   2    
17    L17   #15    DO_ICALL    
18    L19   #16    NEW                     "ReflectionFunction"                      @8    
19    L19   #17    SEND_VAL_EX             "getB"               1    
20    L19   #18    DO_FCALL    
21    L19   #19    ASSIGN                  $rc                  @8    
22    L20   #20    INIT_FCALL              112                  "var_dump"    
23    L20   #21    INIT_METHOD_CALL        $rc                  "getReturnType"    
24    L20   #22    DO_FCALL                                                          @11    
25    L20   #23    CAST                    @11                                       ~12    
26    L20   #24    SEND_VAL                ~12                  1    
27    L20   #25    INIT_METHOD_CALL        $rc                  "getReturnType"    
28    L20   #26    DO_FCALL                                                          @13    
29    L20   #27    SEND_VAR                @13                  2    
30    L20   #28    DO_ICALL    
31    L21   #29    RETURN                  1
Copy after login

You can see that the opcode corresponding to $rc->getReturnType() is #9 DO_FCALL


Okay, let’s start from execute_ex, which can be simplified Into:

01    // 最核心的执行opcode的函数    
02    ZEND_API void execute_ex(zend_execute_data *ex)    
03    {    
04         ...    
05         while (1) {    
06              int ret;    
07              if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0)) {    
08                  ...    
09              }    
10    
11         }    
12        ...    
13    }
Copy after login

Each opcode op of the handler here corresponds to a handler. For example, the handler corresponding to DO_FCALL is ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (the same as the stack displayed in bt just now)


The simplified pseudo code is as follows:

01    // DO_FCALL这个opcode对应的处理函数    
02    static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)    
03    {    
04         ...    
05         if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {  // 如果是用户定义的函数    
06              ...    
07            zend_execute_ex(call);    
08            ...    
09         } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { // 如果是内部函数    
10              ...    
11              if (!zend_execute_internal) {    
12                   fbc->internal_function.handler(call, ret);  // 执行这个internal_function所定义的handler函数,这个就是实际的调用方法了,命名为:zim_[class]_function_[function]    
13              } else {    
14                   zend_execute_internal(call, ret);    
15              }    
16            ...    
17    
18         } else { /* ZEND_OVERLOADED_FUNCTION */    
19              ...    
20              if (UNEXPECTED(!zend_do_fcall_overloaded(fbc, call, ret))) {    
21                   HANDLE_EXCEPTION();    
22              }    
23            ...    
24         }    
25    
26    fcall_end:    
27         ...    
28         ZEND_VM_SET_OPCODE(opline + 1);    
29         ZEND_VM_CONTINUE(); // 下一条op    
30    }
Copy after login

Okay As you can see, there is a fbc->internal_function.handler in this function. The function name corresponding to internal_function here is zim_reflection_function_getReturnType, which corresponds to the function defined in our extension module. It can be said that here we have entered the expansion.

The above is the content of PHP kernel analysis (7) - extension. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

CakePHP Project Configuration CakePHP Project Configuration Sep 10, 2024 pm 05:25 PM

In this chapter, we will understand the Environment Variables, General Configuration, Database Configuration and Email Configuration in CakePHP.

PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian PHP 8.4 Installation and Upgrade guide for Ubuntu and Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

CakePHP Date and Time CakePHP Date and Time Sep 10, 2024 pm 05:27 PM

To work with date and time in cakephp4, we are going to make use of the available FrozenTime class.

CakePHP File upload CakePHP File upload Sep 10, 2024 pm 05:27 PM

To work on file upload we are going to use the form helper. Here, is an example for file upload.

CakePHP Routing CakePHP Routing Sep 10, 2024 pm 05:25 PM

In this chapter, we are going to learn the following topics related to routing ?

Discuss CakePHP Discuss CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP is an open-source framework for PHP. It is intended to make developing, deploying and maintaining applications much easier. CakePHP is based on a MVC-like architecture that is both powerful and easy to grasp. Models, Views, and Controllers gu

How To Set Up Visual Studio Code (VS Code) for PHP Development How To Set Up Visual Studio Code (VS Code) for PHP Development Dec 20, 2024 am 11:31 AM

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

CakePHP Creating Validators CakePHP Creating Validators Sep 10, 2024 pm 05:26 PM

Validator can be created by adding the following two lines in the controller.

See all articles