1. Hhvm2.1 生成扩展文件方式
Hhvm2.1 的结构化变化比较大,idl的目录放到了$HPHP_HOME/hphp/system/idl下,并且他的格式已经换成了xxx.idl.json
生成*.h和*.cpp的模式为:
php$HPHP_HOME/hphp/system/idl/idl.php cpp xxx.idl.json $HPHP_HOME/hphp/runtime/ext/ext_xxx.h$HPHP_HOME/hphp/runtime/ext/ext_xxx.cpp
参数的意思:
(1) 模式,cpp ,也有其他的如inc,test 等
(2) Idl文件,如hello.idl.json
(3) 输出头文件的位置,如$HPHP_HOME/hphp/runtime/ext/ext_hello.h
(4) 输出实现的位置,如$HPHP_HOME/hphp/runtime/ext/ext_hello.cpp
例:
有一个新的扩展名字为hello.idl.json
php $HPHP_HOME/hphp/system/idl/idl.phpcpp hello.idl.json $HPHP_HOME/hphp/runtime/ext/ext_hello.h$HPHP_HOME/hphp/runtime/ext/ext_hello.cpp
2. error: 'c_TestClass' was notdeclared in this scope
/export/dev_hphp2.0/hiphop-php_hzg/hphp/runtime/ext_hhvm/ext_hhvm_infotabs.cpp:At global scope:
/export/dev_hphp2.0/hiphop-php_hzg/hphp/runtime/ext_hhvm/ext_hhvm_infotabs.cpp:6118:49:error: 'c_TestClass' was not declared in this scope
/export/dev_hphp2.0/hiphop-php_hzg/hphp/runtime/ext_hhvm/ext_hhvm_infotabs.cpp:6118:125:error: 'c_TestClass' has not been declared
报了上面的错误是因为在ext.h中没有加入新的扩展的头文件,我们只需要把新的扩展的头文件加入进去即可:
#include"hphp/runtime/ext/ext_testclass.h"
c_TestClass::c_TestClass(Class*cls):ExtObjectData(cls){
}
c_TestClass::~c_TestClass(){
}
当报下面的错误时:
(1)这个是参数的问题
/export/dev_hphp2.0/hiphop-php_hzg/hphp/runtime/ext/ext_testclass.cpp:7:57:error: default argument given for parameter 1 of'HPHP::c_TestClass::c_TestClass(HPHP::Class*)'
(2)这个是由于c_TestClass(Class* cls):ExtObjectData(cb)变量不一致造成的,比如前面是cls我后面定义的是cb
/export/dev_hphp2.0/hiphop-php_hzg/hphp/runtime/ext/ext_testclass.cpp:7:52:error: 'cb' was not declared in this scope
正常的实现是:
c_TestClass::c_TestClass(Class*cls):ExtObjectData(cls){
3. undefined reference to`HPHP::c_ICE::~c_ICE()'错误解决
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP5c_ICEE[vtablefor HPHP::c_ICE]+0x10): undefined reference to `HPHP::c_ICE::~c_ICE()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP5c_ICEE[vtablefor HPHP::c_ICE]+0x18): undefined reference to `HPHP::c_ICE::~c_ICE()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP7c_ProxyE[vtablefor HPHP::c_Proxy]+0x10): undefined reference to `HPHP::c_Proxy::~c_Proxy()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP7c_ProxyE[vtablefor HPHP::c_Proxy]+0x18): undefined reference to `HPHP::c_Proxy::~c_Proxy()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP14c_IcePHP_classE[vtablefor HPHP::c_IcePHP_class]+0x10): undefined reference to`HPHP::c_IcePHP_class::~c_IcePHP_class()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP14c_IcePHP_classE[vtablefor HPHP::c_IcePHP_class]+0x18): undefined reference to`HPHP::c_IcePHP_class::~c_IcePHP_class()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP10c_TypeInfoE[vtablefor HPHP::c_TypeInfo]+0x10): undefined reference to`HPHP::c_TypeInfo::~c_TypeInfo()'
../../bin/libext_hhvm.a(ext_ice.cpp.ext_hhvm.cpp.o):(.rodata._ZTVN4HPHP10c_TypeInfoE[vtablefor HPHP::c_TypeInfo]+0x18): undefined reference to`HPHP::c_TypeInfo::~c_TypeInfo()'
当报这个错误的时候,是由于新添加的扩展没有对类进行实现,添加实现即可:
在实现类中需要实现构造函数:
c_TestClass::c_TestClass(Class*cls):ExtObjectData(cls){
}
c_TestClass::~c_TestClass(){
}
4. Idl.json定义
args的value不能是””和非字符串;
而且必须是定义非空的只能小于等于2个;
定义String空:null_string;
定义Variant,StringMap 空:null_variant;
定义Object空:null_object;
其他的参照hphp/runtime/base/types.h
5. Hhvm创建线程失败解决
pthread_attr_t attr;
如果设置attr.stacksize=1.1M,则创建成功;
如果设置:
attr.stacksize=2B,则创建失败;
这是为什么呢?
这是由于1M是一个临界值,创建线程时需要是1M+nkb,也就是需要大于1M才可以;
如果我们需要突破这个限制,那么改如下代码:
由于src/util/ringbuffer.cpp 中设置了线程栈的大小:
static const int kMaxRBBytes = 1 << 20; // 1MB
这里改成小于1M即可;
static const int kMaxRBBytes = 1 << 19; // 512KB
这个改成512KB后,就可以支持attr.stacksize=512K+nkb了,但是小于512KB,还是会失败;
所以如果我们要设置线程栈小于1M时,这里我们可以自己控制,比如我们设置了100K,那么相对kMaxRBBytes变量就要设置为小于100K的临界值即可;
该问题是百度张慕华解决的,我这里借鉴;
解决方式见:
https://github.com/facebook/hiphop-php/issues/1015
6. 魔术函数递归调用问题解决(2.1)
提问地址:
https://github.com/facebook/hiphop-php/issues/1177#issuecomment-26334876
解决地址:
https://github.com/silvermine/hiphop-php/commit/0b59973c71ebfed5bb90976f8b6467f835170d60
php代码:
<?php class CComponent{ private $_e; private $_m; public function __get($name){ $getter='get'.$name; if(method_exists($this,$getter)) return $this->$getter(); else{ echo("enter CComponent 2\n"); exit("===================\n"); } } } class CModel extends CComponent{ private $_components=array(); private $_componentConfig=array(); public function __get($name){ $tt = false; if($tt) return "bb"; else return parent::__get($name); } } class CActiveRecord extends CModel{ private $_attributes=array(); public $tag = array( "name1" => "value1", "name2" => "value2", "name3" => "value3", "name4" => "value4", "name5" => "value5", ); public function __construct(){ $this->_attributes = $this->tag; } public function __get($name){ if(isset($this->_attributes[$name])){ echo "enter CActiveRecord 1\n"; return $this->_attributes[$name]; } else{ echo "enter CActiveRecord 2\n"; return parent::__get($name); } } } class A extends CActiveRecord{ public $b; public $attribute; public function gettakeFunc(){ echo "enter takFunc\n"; return $this->attributes; } } $a = new A(); var_dump($a->takeFunc); ?>
zend vm run result:
enter CActiveRecord 2
enter takFunc
enter CActiveRecord 2
enter CComponent 2
===================
hhvm run result :
enter CActiveRecord 2
enter takFunc
HipHop Notice: Undefined property: A::$attributes in /export/data/www/test/test_ext/classes/test_class_obj_bug.php on line 61
NULL
我们发现这里调用的时候hhvm出现了Undefined property
错误,这是由于魔术函数递归操作造成的;
我们在hphp/runtime/base/object-data.cpp
在这个文件中找到MAGIC_PROP_BODY宏,然后删除掉:
AttributeClearer a((attr), this);
改行语句即可;
最终代码为:
#define MAGIC_PROP_BODY(name, attr) \ const Func* meth = m_cls->lookupMethod(name); \ assert(meth); \ invokeUserMethod(retval, meth, CREATE_VECTOR1(CStrRef(key))); \
由于进行递归操作时,每次执行AttributeClearer清除了先前的property内容,所以就无法找到;
虽然提问时,scannell告诉我了解决方式,但是我看主线版仍然没有修复该BUG,我将继续跟踪,如果使用该功能的,可以按照上述解决方式解决;