php 中间代码,PHP内核中用户函数、内部函数和中间代码的转换

昨天和一朋友在邮件中讨论这样一个问题:zend_internal_function,zend_function,zend_op_array这三种结构是可以相互转化的,这三者的转化是如何进行的呢? 以此文,总结。

在函数调用的执行代码中我们会看到这样一些强制转换:

EX(function_state).function = (zend_function *) op_array;

或者:

EG(active_op_array) = (zend_op_array *) EX(function_state).function;

这种不同结构间的强制转换是如何进行的呢?

首先我们来看zend_function的结构,在Zend/zend_compile.h文件中,其定义如下:

typedef union _zend_function {

zend_uchar type; /* MUST be the first element of this struct! */

struct {

zend_uchar type; /* never used */

char *function_name;

zend_class_entry *scope;

zend_uint fn_flags;

union _zend_function *prototype;

zend_uint num_args;

zend_uint required_num_args;

zend_arg_info *arg_info;

zend_bool pass_rest_by_reference;

unsigned char return_reference;

} common;

zend_op_array op_array;

zend_internal_function internal_function;

} zend_function;

这是一个联合体,我们来温习一下联合体的一些特性。 联合体的所有成员变量共享内存中的一块内存,在某个时刻只能有一个成员使用这块内存, 并且当使用某一个成员时,其仅能按照它的类型和内存大小修改对应的内存空间。 我们来看看一个例子:

#include

#include

int main() {

typedef union _utype

{

int i;

char ch[2];

} utype;

utype a;

a.i = 10;

a.ch[0] = '1';

a.ch[1] = '1';

printf("a.i= %d a.ch=%s",a.i, a.ch);

getchar();

return (EXIT_SUCCESS);

}

程序输出:a.i= 12593 a.ch=11 当修改ch的值时,它会依据自己的规则覆盖i字段对应的内存空间。 ’1′对应的ASCII码值是49,二进制为00110001,当ch字段的两个元素都为’1′时,此时内存中存储的二进制为 00110001 00110001 转成十进制,其值为12593。

回过头来看zend_function的结构,它也是一个联合体,第一个字段为type, 在common中第一个字段也为type,并且其后面注释为/* Never used*/,此处的type字段的作用就是为第一个字段的type留下内存空间。并且不让其它字段干扰了第一个字段。 我们再看zend_op_array的结构:

struct _zend_op_array {

/* Common elements */

zend_uchar type;

char *function_name;

zend_class_entry *scope;

zend_uint fn_flags;

union _zend_function *prototype;

zend_uint num_args;

zend_uint required_num_args;

zend_arg_info *arg_info;

zend_bool pass_rest_by_reference;

unsigned char return_reference;

/* END of common elements */

zend_bool done_pass_two;

....// 其它字段

}

这里的字段集和common的一样,于是在将zend_function转化成zend_op_array时并不会产生影响,这种转变是双向的。

再看zend_internal_function的结构:

typedef struct _zend_internal_function {

/* Common elements */

zend_uchar type;

char * function_name;

zend_class_entry *scope;

zend_uint fn_flags;

union _zend_function *prototype;

zend_uint num_args;

zend_uint required_num_args;

zend_arg_info *arg_info;

zend_bool pass_rest_by_reference;

unsigned char return_reference;

/* END of common elements */

void (*handler)(INTERNAL_FUNCTION_PARAMETERS);

struct _zend_module_entry *module;

} zend_internal_function;

同样存在公共元素,和common结构体一样,我们可以将zend_function结构强制转化成zend_internal_function结构,并且这种转变是双向的。

总的来说zend_internal_function,zend_function,zend_op_array这三种结构在一定程序上存在公共的元素, 于是这些元素以联合体的形式共享内存,并且在执行过程中对于一个函数,这三种结构对应的字段在值上都是一样的, 于是可以在一些结构间发生完美的强制类型转换。 可以转换的列表如下:

zend_function可以与zend_op_array互换

zend_function可以与zend_internal_function互换

但是一个zend_op_array结构转换成zend_function是不能再次转变成zend_internal_function结构的,反之亦然。

其实zend_function就是一个混合的数据结构,这种结构在一定程序上节省了内存空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Byteman –用于字节码操纵的瑞士军刀

我正在JBoss的许多社区中工作,有很多有趣的事情要谈论,以至于我自己无法将自己的每一分都缠住。 这就是为什么我非常感谢有机会不时地欢迎客座博客的主要原因。 今天是Jochen Mader,他是以代码为中心的书呆子群的一部分。 目前,他…

最短路径问题matlab作图,[MATLAB基础] matlab最短路径的输出问题,用了递归,但程序出错了,请大虾指点...

matlab最短路径的输出问题,用了递归,但程序出错了,请大虾指点 程序如下function shortestpath(w,p,q)c->;l;f;tsize(w);mt(1,1);azeros(m,m);vw;for k1:mfor i1:mfor j1:mb[w(i,j),w(i,k)w(k,j)];w(i,j)min(b);if w(i,j)~v(i,j)a(i,j)k;%a(i,j)10*a(i,j)k;vw;endendendendw;…

快速浏览JAX-RS请求与方法匹配

在本文中,我们来看一下JAX-RS中与资源方法匹配的HTTP请求 。 它是JAX-RS的最基本功能之一。 通常,使用JAX-RS API的开发人员不会接触(或真正不需要知道) 匹配过程的细节,请放心,由于我们的RESTful&#xff…

$stat php,php stat函数怎么用

php stat函数用于返回关于文件的信息,其语法是fstat(file),参数file必需,指规定要检查的文件。php stat函数怎么用?定义和用法stat() 函数返回关于文件的信息。语法fstat(file)参数file必需。规定要检查的文件。说明获取由 file 指…

在Java中调用祖父母方法:您不能

在文章保护的重点中,我详细介绍了“受保护”如何扩展“包私有”访问。 我在那儿写道: 你能做的是 覆盖子类中的方法或 使用关键字super调用parent方法。 通常,这实际上是您可以使用受保护的方法完成的所有操作。 (请注意&…

Handler(2)

andriod提供了Handler 和 Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(MessageExchange)。1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。 2)Handler: 你可以构造Han…

OSGi服务测试助手:ServiceCollector

OSGi服务对于基于松耦合组件的系统开发非常有用。 但是,松散的耦合可能使得难以识别与悬挂服务引用有关的问题。 因此,我们通常运行集成测试以确保运行时服务组件的可用性。 为了减少此类测试所需的样板,我编写了一个简单的实用程序类来获取…

搭建struts2框架

struts是一个经典的MVC模式拦截器比过滤器拦截的力度更大 搭建struts2框架1.引入lib包 9个(2.3版本的)common-fileupload;common-io;common-lang3;common-logging;freemaker;javassistGA;ognl;struts2-core;xwork-core; 2. struts2.xml3. web.xml将所有的跳转都交给struts2处…

adams与matlab联合仿真天线,雷达天线模型MATLAB与ADAMS联合仿真 实验.doc

雷达天线模型MATLAB与ADAMS联合仿真 实验雷达天线模型MATLAB与ADAMS联合仿真实验1.导入雷达天线机械系统模型启动ADAMS,弹出如图1所示的对话框,选择“Open an existing database”,打开保存雷达天线模型的文件夹X:\antenna_test(注:X表示盘符…

【ACM】nyoj_139_我排第几个_201308062046

我排第几个时间限制:1000 ms | 内存限制:65535 KB 难度:3描述 现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? …

Apache Cassandra和低延迟应用程序

介绍 多年来, Grid Dynamics拥有许多与NoSQL相关的项目,尤其是Apache Cassandra。 在这篇文章中,我们要讨论一个给我们带来挑战的项目,而我们在该项目中试图回答的问题今天也仍然适用。 数字营销和在线广告在2012年很受欢迎&…

php换设备登录逻辑,登录和退出登录的操作逻辑

登录功能的操作逻辑步骤如下:可以分为五个步骤来实现。1、进入页面先判断用户是否已经登录private void isLogin() {//查看本地是否有用户的登录信息SharedPreferences sp this.getActivity().getSharedPreferences("user_info", Context.MODE_PRIVATE);…

Visual studio代码行数统计

Visual studio代码行数统计 Visual Studio中的搜索功能支持正则表达式(虽然语法比较诡异),我们完全可以通过正则表达式来遍历整个解决方案从而获得代码行数。 ^:b*[^:b#/].*$ 需要注意:#开头和/开头或者空行都不计入代码量。 如…

在JAX-RS中处理异步请求中的超时

JAX-RS 2.0在客户端和服务器端都支持异步编程范例。 这篇文章重点介绍了使用JAX-RS(2.0)API在服务器端执行异步REST请求时的超时功能 无需过多介绍,这里是一个快速概述。 为了以异步方式执行方法,您只需 需要指定AsyncResponse接…

strspn php,php返回在字符串中包含 charlist 参数中指定的字符数目的函数strspn()

实例返回在字符串 "Hello world!" 中包含字符 "kHlleo" 的数目&#xff1a;<?php echo strspn("Hello world!","kHlleo");?>定义和用法strspn() 函数返回在字符串中包含 charlist 参数中指定的字符数目。提示&#xff1a;请使…

Java十大简单性能优化

关于“ web scale ”这个流行词有很多炒作&#xff0c;人们花了很多时间来重新组织他们的应用程序体系结构&#xff0c;以使其系统“规模化”。 但是什么是扩展&#xff0c;我们如何确保可以扩展&#xff1f; 缩放的不同方面 上面提到的炒作主要是关于扩展负载 &#xff0c;即…

C#_获取汉字拼音

using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Ctr.Common.Tools {/// <summary>/// 汉字转拼音静态类,包括功能全拼和缩写&#xff0c;方法全部是静态的/// </summary>public static cla…

php在苹果手机上传不了图片大小,ThinkPHP后台上传图片无默认尺寸解决方法

原标题&#xff1a;ThinkPHP后台上传图片无默认尺寸解决方法随着网站移动端的日益普及&#xff0c;对后台数据的兼容性要求也越来越高。后台数据涵盖范围不断扩大的同时&#xff0c;使得程序处理能力也必须逐步提高。使用ThinkPHP进行长沙网站开发时&#xff0c;后台kindeditor…

幂等与时间解耦之旅

HTTP中的幂等性意味着相同的请求可以执行多次&#xff0c;并且效果与仅执行一次一样。 如果用新资源替换某个资源的当前状态&#xff0c;则无论您执行多少次&#xff0c;最终状态都将与您仅执行一次相同。 举一个更具体的例子&#xff1a;删除用户是幂等的&#xff0c;因为无论…

开发者最容易犯的13个JavaScript错误

开发者最容易犯的JavaScript错误&#xff0c;总结出13个。这些当中可能少不了你犯的错误。我们描述了这些陋习&#xff0c;并列出来解决办法&#xff0c;希望对开发者有帮助。 1.for...数组迭代的用法 Usage of for..in to iterate Arrays 举例&#xff1a; var myArray [ “a…