php 生成类的对象 $a=new test();
程序
<?php
class test
{
...
} $a=new test();
1.BNF 范式
start:
variable '=' expr ';' expr:
new_expr
;
new_expr:
T_NEW class_name {zend_do_begin_new_class(&$$ , &$)} ctor_paramer { zend_do_end_new_class() }
;
class_name:
T_STRING {zend_do_fetch_class(&$$, &$) }
获取class_name,并生成opcode ZEND_FETCH_CLASS
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
{ zend_op *opline; fetch_class_op_number = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_FETCH_CLASS;
SET_UNUSED(opline->op1);
if (class_name->op_type == IS_CONST) {
int fetch_type;
switch (fetch_type) {
default:
zend_resolve_class_name(class_name TSRMLS_CC);
opline->op2_type = IS_CONST;
opline->op2.constant =
zend_add_class_name_literal(CG(active_op_array), &class_name->u.constant TSRMLS_CC);
break;
}
}
opline->result.var = get_temporary_variable(CG(active_op_array));
opline->result_type = IS_VAR; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
GET_NODE(result, opline->result);
}
执行 ZEND_FETCH_CLASS
static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, , opline->extended_value TSRMLS_CC);
}
void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */
{
zend_op *opline;
unsigned char *ptr = NULL; new_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_NEW;
opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable(CG(active_op_array));
SET_NODE(opline->op1, class_type);
SET_UNUSED(opline->op2); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
}
void zend_do_end_new_object(znode *result, const znode *new_token, const znode *argument_list TSRMLS_DC) /* {{{ */
{
znode ctor_result; zend_do_end_function_call(NULL, &ctor_result, argument_list, , TSRMLS_CC);
zend_do_free(&ctor_result TSRMLS_CC); CG(active_op_array)->opcodes[new_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
GET_NODE(result, CG(active_op_array)->opcodes[new_token->u.op.opline_num].result);
}
static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *object_zval;
zend_function *constructor; SAVE_OPLINE();
if (UNEXPECTED((EX_T(opline->op1.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != )) {
if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", EX_T(opline->op1.var).class_entry->name);
} else if ((EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", EX_T(opline->op1.var).class_entry->name);
} else {
zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", EX_T(opline->op1.var).class_entry->name);
}
}
ALLOC_ZVAL(object_zval);
object_init_ex(object_zval, EX_T(opline->op1.var).class_entry);
INIT_PZVAL(object_zval); constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC); if (constructor == NULL) {
if (RETURN_VALUE_USED(opline)) {
AI_SET_PTR(&EX_T(opline->result.var), object_zval);
} else {
zval_ptr_dtor(&object_zval);
}
ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num);
} else {
if (RETURN_VALUE_USED(opline)) {
PZVAL_LOCK(object_zval);
AI_SET_PTR(&EX_T(opline->result.var), object_zval);
} zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline))); /* We are not handling overloaded classes right now */
EX(object) = object_zval;
EX(fbc) = constructor;
EX(called_scope) = EX_T(opline->op1.var).class_entry; CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
}
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC TSRMLS_CC) ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
{
return _object_and_properties_init(arg, class_type, ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
} ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */
{
zend_object *object; if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
char *what = (class_type->ce_flags & ZEND_ACC_INTERFACE) ? "interface"
:((class_type->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) ? "trait"
: "abstract class";
zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name);
} zend_update_class_constants(class_type TSRMLS_CC); Z_TYPE_P(arg) = IS_OBJECT;
if (class_type->create_object == NULL) {
Z_OBJVAL_P(arg) = zend_objects_new(&object, class_type TSRMLS_CC);
// arg.value.obj=zend_objects_new(...);
if (properties) {
object->properties = properties;
object->properties_table = NULL;
} else {
object_properties_init(object, class_type);
}
} else {
Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC);
}
return SUCCESS;
}
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type) /* {{{ */
{
int i; if (class_type->default_properties_count) {
object->properties_table = emalloc(sizeof(zval*) * class_type->default_properties_count);
for (i = ; i < class_type->default_properties_count; i++) {
object->properties_table[i] = class_type->default_properties_table[i];
if (class_type->default_properties_table[i]) {
Z_ADDREF_P(object->properties_table[i]);
}
}
object->properties = NULL;
}
}
ZEND_API zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type TSRMLS_DC)
{
zend_object_value retval; *object = emalloc(sizeof(zend_object));
(*object)->ce = class_type;
(*object)->properties = NULL;
(*object)->properties_table = NULL;
(*object)->guards = NULL;
retval.handle = zend_objects_store_put(*object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC);
retval.handlers = &std_object_handlers;
return retval;
} ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_store_dtor_t dtor, zend_objects_free_object_storage_t free_storage, zend_objects_store_clone_t clone TSRMLS_DC)
{
zend_object_handle handle;
struct _store_object *obj; if (EG(objects_store).free_list_head != -) {
handle = EG(objects_store).free_list_head;
EG(objects_store).free_list_head = EG(objects_store).object_buckets[handle].bucket.free_list.next;
} else {
if (EG(objects_store).top == EG(objects_store).size) {
EG(objects_store).size <<= ;
EG(objects_store).object_buckets = (zend_object_store_bucket *) erealloc(EG(objects_store).object_buckets, EG(objects_store).size * sizeof(zend_object_store_bucket));
}
handle = EG(objects_store).top++;
}
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
EG(objects_store).object_buckets[handle].destructor_called = ;
EG(objects_store).object_buckets[handle].valid = ;
EG(objects_store).object_buckets[handle].apply_count = ; obj->refcount = ;
GC_OBJ_INIT(obj);
obj->object = object;
obj->dtor = dtor?dtor:(zend_objects_store_dtor_t)zend_objects_destroy_object;
obj->free_storage = free_storage;
obj->clone = clone;
obj->handlers = NULL; #if ZEND_DEBUG_OBJECTS
fprintf(stderr, "Allocated object id #%d\n", handle);
#endif
return handle;
}
理解版
static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zval *zv;
zv->type=IS_OBJECT;
zend_object_value object_value;
ALLOC_ZVAL(zv);
zend_object *object;
object->ce=EX_T(opline1->op1.var);
object->properties=NULL;
object->properties_table=NULL; zend_object_handle handle;
handle=EG(object_store).top++; object=&EG(object_store).object_buckets[handle].bucket.obj;
object->object=object; object_value.handle=handle; zv.value.obj=object_value; EX_T(opline->result.var).var.ptr=zv;
result->u.op=opline->result;
//#define EX_T(offset) (*EX_TMP_VAR(execute_data, offset))
//#define EX_TMP_VAR(ex, n) ((temp_variable*)(((char*)(ex)) + ((int)(n))))
}
php 生成类的对象 $a=new test();的更多相关文章
- 动态加载Dll时,通过Type生成类对象
原文:动态加载Dll时,通过Type生成类对象 转:http://www.cnblogs.com/zfanlong1314/p/4197383.html "反射"其实就是利用程序集 ...
- dagger2系列之生成类实例
上一节的最后,我讲到一次注入生成类实例的生成步骤.先来回顾一下: 1 Module中存在创建方法,则看此创建方法有没有参数 如果有参数,这些参数也是由Component提供的,返回步骤1逐一生成参数 ...
- 将Eclipse中现有的java类生成类图
需求:将Eclipse中现有的java类生成类图 一:什么是ModelGoon? 它是一个Eclipse插件,用于基于UML图的模型设计,以及逆向工程(即从已有源代码生成类图). 二:安装 下载Mod ...
- [条形码] BarCodeToHTML条码生成类 (转载)
点击下载 BarCodeToHTML.zip 过多的我就不多说了大家直接看代码吧,这是一个帮助大家生成条码的类,大小大家可以自由的设定 /// <summary> /// 类说明:条码生成 ...
- 用Enterprise Architect从源码自动生成类图
http://blog.csdn.net/zhouyong0/article/details/8281192 /*references:感谢资源分享者.info:简单记录如何通过工具从源码生成类图,便 ...
- Java 编程 订单、支付、退款、发货、退货等编号主动生成类
订单.支付.退款.发货.退货等编号主动生成类 在商城网站中,订单编号的自动生成,ERP中各个单据的编号自动生成,都可以按照一下的方式来自动生成. 第一步:定义常量订单编号前缀.订单编号起始数.订单编号 ...
- 【原】如何获取Java动态生成类?
写作目的:Java大部分框架,如Spring,Hibernate等都会利用动态代理在程序运行的时候生成新的类, 有的时候为了学习,或者深入了解动态代理,想查看动态生成类的源代码究竟长怎么个样子, 通过 ...
- IDEA设置生成类基本注释信息
在eclipse中我们按一下快捷键就会生成类的基本信息相关的注释,其实在IDEA中也是可以的,需要我们手动设置,之后再创建类的时候就会自动加上这些基本的信息. File-->Setting 在E ...
- XML之自动生成类,添加,修改,删除类的属性
1. class ClassHelperDemo { public static void Main() { #region 演示一:动态生成类. //生成一个类t. Type t = ClassHe ...
随机推荐
- PHP的$_SERVER['HTTP_HOST']获取服务器地址功能详解,$_SERVER['HTTP_X_FORWARDED_HOST']
uchome的index文件中的二级域名功能判断,使用了php的$_SERVER['HTTP_HOST'],开始对这个不是很了解,所以百度了一下,发现一篇帖子有点意思,转发过来做个记录. 在php中, ...
- Spark小课堂Week7 从Spark中一个例子看面向对象设计
Spark小课堂Week7 从Spark中一个例子看面向对象设计 今天我们讨论了个问题,来设计一个Spark中的常用功能. 功能描述:数据源是一切处理的源头,这次要实现下加载数据源的方法load() ...
- asp.net 运行时, 报控件不存在
Asp.net 运行时,报控件不存在,但系统中确实加入了控件z, 但是生成网站的时候,报控件不存在,输入代码的时候,this.edtxx.Text 确实可以输入 原因: 系统修改的时候,作了一个备份, ...
- 巧用九宫格以减少UI资源量
UI资源量对资源包大小和内存的影响 UI资源具有以下特点: (1)UI资源几乎都是图片,而图片是最占资源量的资源类型之一. (2)Unity不支持外部压缩,即使在外部将一个10MB的图片压缩到只剩1M ...
- 实时数据处理环境搭建flume+kafka+storm:4.storm安装配置
1.解压 apache-storm-0.9.3.tar.gz 2.修改配置文件 conf/storm.yaml --zk地址 storm.zookeeper.servers: - " ...
- [转载].Net中如何操作IIS(源代码)
///***********************************************************///************** IIS控制管理类 1.0 Beta ** ...
- MVC EF异常-“序列化类型为 XX 的对象时检测到循环引用”
原因:在EF实体中,两个互为主外键关系的实体类的导航属性相互引用. 解决方法一:删除一个不需要的类的导航属性 方法二:使用DTO模型 方法三:直接返回需要的属性(不能包括相互引用的属性)
- Maven SDK
Maven SDK Details Print Tags: development maven maven2 liferay v6.0 Table of Contents [-] Introdu ...
- ZOJ 3778 Talented Chef
题目链接 题意 : 这个人需要做n道菜,每道菜Ai步,他可以同时做M道不同的菜的其中一步,问你最少需要多少时间能做完所有的菜. 思路 : 这个题比赛的时候禁锢思路了,根本没想出来,就是当M > ...
- linux查看磁盘使用情况
# 查看磁盘使用情况 $ df -l # 查看某个目录在哪个分区,比如查看/root文件夹在哪个分区 $ df /root # 查看linux系统具体分区情况 $ fdisk -l