0
0
mirror of https://github.com/phpv8/v8js.git synced 2025-01-03 09:21:51 +00:00

Use internal fields instead of GetHiddenValue/SetHiddenValue

The latter were deprecated and removed in V8 5.2
This commit is contained in:
Stefan Siegl 2016-05-22 15:12:44 +02:00
parent 48cb242e6c
commit 05b96a96b8
7 changed files with 37 additions and 59 deletions

View File

@ -55,9 +55,6 @@ extern "C" {
/* V8Js Version */ /* V8Js Version */
#define PHP_V8JS_VERSION "0.6.2" #define PHP_V8JS_VERSION "0.6.2"
/* Hidden field name used to link JS wrappers with underlying PHP object */
#define PHPJS_OBJECT_KEY "phpjs::object"
/* Helper macros */ /* Helper macros */
#define V8JS_GET_CLASS_NAME(var, obj) \ #define V8JS_GET_CLASS_NAME(var, obj) \
v8::String::Utf8Value var(obj->GetConstructorName()); v8::String::Utf8Value var(obj->GetConstructorName());

View File

@ -2,7 +2,7 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -73,8 +73,7 @@ void v8js_array_access_getter(uint32_t index, const v8::PropertyCallbackInfo<v8:
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
zval *php_value = v8js_array_access_dispatch(object, "offsetGet", 1, index, NULL TSRMLS_CC); zval *php_value = v8js_array_access_dispatch(object, "offsetGet", 1, index, NULL TSRMLS_CC);
v8::Local<v8::Value> ret_value = zval_to_v8js(php_value, isolate TSRMLS_CC); v8::Local<v8::Value> ret_value = zval_to_v8js(php_value, isolate TSRMLS_CC);
@ -92,8 +91,7 @@ void v8js_array_access_setter(uint32_t index, v8::Local<v8::Value> value,
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
zval *zvalue_ptr; zval *zvalue_ptr;
MAKE_STD_ZVAL(zvalue_ptr); MAKE_STD_ZVAL(zvalue_ptr);
@ -156,8 +154,7 @@ static void v8js_array_access_length(v8::Local<v8::String> property, const v8::P
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
int length = v8js_array_access_get_count_result(object TSRMLS_CC); int length = v8js_array_access_get_count_result(object TSRMLS_CC);
info.GetReturnValue().Set(V8JS_INT(length)); info.GetReturnValue().Set(V8JS_INT(length));
@ -171,8 +168,7 @@ void v8js_array_access_deleter(uint32_t index, const v8::PropertyCallbackInfo<v8
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
zval *php_value = v8js_array_access_dispatch(object, "offsetUnset", 1, index, NULL TSRMLS_CC); zval *php_value = v8js_array_access_dispatch(object, "offsetUnset", 1, index, NULL TSRMLS_CC);
zval_ptr_dtor(&php_value); zval_ptr_dtor(&php_value);
@ -188,8 +184,7 @@ void v8js_array_access_query(uint32_t index, const v8::PropertyCallbackInfo<v8::
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
/* If index is set, then return an integer encoding a v8::PropertyAttribute; /* If index is set, then return an integer encoding a v8::PropertyAttribute;
* otherwise we're expected to return an empty handle. */ * otherwise we're expected to return an empty handle. */
@ -207,8 +202,7 @@ void v8js_array_access_enumerator(const v8::PropertyCallbackInfo<v8::Array>& inf
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
int length = v8js_array_access_get_count_result(object TSRMLS_CC); int length = v8js_array_access_get_count_result(object TSRMLS_CC);
v8::Local<v8::Array> result = v8::Array::New(isolate, length); v8::Local<v8::Array> result = v8::Array::New(isolate, length);

View File

@ -475,6 +475,7 @@ static PHP_METHOD(V8Js, __construct)
c->object_name.Reset(isolate, object_name_js); c->object_name.Reset(isolate, object_name_js);
/* Add the PHP object into global object */ /* Add the PHP object into global object */
php_obj_t->InstanceTemplate()->SetInternalFieldCount(2);
v8::Local<v8::Object> php_obj = php_obj_t->InstanceTemplate()->NewInstance(); v8::Local<v8::Object> php_obj = php_obj_t->InstanceTemplate()->NewInstance();
V8JS_GLOBAL(isolate)->ForceSet(object_name_js, php_obj, v8::ReadOnly); V8JS_GLOBAL(isolate)->ForceSet(object_name_js, php_obj, v8::ReadOnly);
@ -505,7 +506,7 @@ static PHP_METHOD(V8Js, __construct)
} }
/* Add pointer to zend object */ /* Add pointer to zend object */
php_obj->SetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY), v8::External::New(isolate, getThis())); php_obj->SetAlignedPointerInInternalField(1, getThis());
/* Export public methods */ /* Export public methods */
zend_function *method_ptr; zend_function *method_ptr;

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -236,14 +237,15 @@ int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags, v
} }
else if (jsValue->IsObject()) else if (jsValue->IsObject())
{ {
v8::Handle<v8::Object> self = v8::Handle<v8::Object>::Cast(jsValue); v8::Local<v8::Object> self = jsValue->ToObject();
// if this is a wrapped PHP object, then just unwrap it. // if this is a wrapped PHP object, then just unwrap it.
v8::Local<v8::Value> php_object = self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); if (self->InternalFieldCount()) {
if (!php_object.IsEmpty()) { zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
RETVAL_ZVAL(object, 1, 0); RETVAL_ZVAL(object, 1, 0);
return SUCCESS; return SUCCESS;
} }
if ((flags & V8JS_FLAG_FORCE_ARRAY && !jsValue->IsFunction()) || jsValue->IsArray()) { if ((flags & V8JS_FLAG_FORCE_ARRAY && !jsValue->IsFunction()) || jsValue->IsArray()) {
array_init(return_value); array_init(return_value);
return v8js_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC); return v8js_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC);

View File

@ -2,7 +2,7 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2015 The PHP Group | | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -83,18 +83,13 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::
PHPV8_EXPROP(_string, JsTrace, stacktrace_string); PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
} }
if(try_catch->Exception()->IsObject()) { if(try_catch->Exception()->IsObject() && try_catch->Exception()->ToObject()->InternalFieldCount()) {
v8::Local<v8::Value> php_ref = try_catch->Exception()->ToObject()->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)); zval *php_exception = reinterpret_cast<zval *>(try_catch->Exception()->ToObject()->GetAlignedPointerFromInternalField(1));
if(!php_ref.IsEmpty()) { zend_class_entry *exception_ce = zend_exception_get_default(TSRMLS_C);
assert(php_ref->IsExternal()); if (Z_TYPE_P(php_exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(php_exception), exception_ce TSRMLS_CC)) {
zval *php_exception = reinterpret_cast<zval *>(v8::External::Cast(*php_ref)->Value()); Z_ADDREF_P(php_exception);
zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
zend_class_entry *exception_ce = zend_exception_get_default(TSRMLS_C);
if (Z_TYPE_P(php_exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(php_exception), exception_ce TSRMLS_CC)) {
Z_ADDREF_P(php_exception);
zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
}
} }
} }

View File

@ -2,12 +2,13 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 5 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2013 The PHP Group | | Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| http://www.opensource.org/licenses/mit-license.php MIT License | | http://www.opensource.org/licenses/mit-license.php MIT License |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Jani Taskinen <jani.taskinen@iki.fi> | | Author: Jani Taskinen <jani.taskinen@iki.fi> |
| Author: Patrick Reilly <preilly@php.net> | | Author: Patrick Reilly <preilly@php.net> |
| Author: Stefan Siegl <stesie@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -88,13 +89,9 @@ static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function
fci.params = (zval ***) safe_emalloc(argc, sizeof(zval **), 0); fci.params = (zval ***) safe_emalloc(argc, sizeof(zval **), 0);
argv = (zval **) safe_emalloc(argc, sizeof(zval *), 0); argv = (zval **) safe_emalloc(argc, sizeof(zval *), 0);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
v8::Local<v8::Value> php_object; if (info[i]->IsObject() && info[i]->ToObject()->InternalFieldCount()) {
if (info[i]->IsObject()) {
php_object = v8::Local<v8::Object>::Cast(info[i])->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
}
if (!php_object.IsEmpty()) {
/* This is a PHP object, passed to JS and back. */ /* This is a PHP object, passed to JS and back. */
argv[i] = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value()); argv[i] = reinterpret_cast<zval *>(info[i]->ToObject()->GetAlignedPointerFromInternalField(1));
Z_ADDREF_P(argv[i]); Z_ADDREF_P(argv[i]);
} else { } else {
MAKE_STD_ZVAL(argv[i]); MAKE_STD_ZVAL(argv[i]);
@ -178,7 +175,7 @@ void v8js_php_callback(const v8::FunctionCallbackInfo<v8::Value>& info) /* {{{ *
v8::Local<v8::Object> self = info.Holder(); v8::Local<v8::Object> self = info.Holder();
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
zval *value = reinterpret_cast<zval *>(v8::External::Cast(*self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)))->Value()); zval *value = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
zend_function *method_ptr; zend_function *method_ptr;
zend_class_entry *ce = Z_OBJCE_P(value); zend_class_entry *ce = Z_OBJCE_P(value);
@ -198,9 +195,7 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
v8::Isolate *isolate = info.GetIsolate(); v8::Isolate *isolate = info.GetIsolate();
info.GetReturnValue().Set(V8JS_UNDEFINED); info.GetReturnValue().Set(V8JS_UNDEFINED);
// @todo assert constructor call
v8::Handle<v8::Object> newobj = info.This(); v8::Handle<v8::Object> newobj = info.This();
v8::Local<v8::External> php_object;
zval *value; zval *value;
if (!info.IsConstructCall()) { if (!info.IsConstructCall()) {
@ -215,14 +210,14 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
if (info[0]->IsExternal()) { if (info[0]->IsExternal()) {
// Object created by v8js in v8js_hash_to_jsobj, PHP object passed as v8::External. // Object created by v8js in v8js_hash_to_jsobj, PHP object passed as v8::External.
php_object = v8::Local<v8::External>::Cast(info[0]); v8::Local<v8::External> php_object = v8::Local<v8::External>::Cast(info[0]);
value = reinterpret_cast<zval *>(php_object->Value()); value = reinterpret_cast<zval *>(php_object->Value());
if(ctx->weak_objects.count(value)) { if(ctx->weak_objects.count(value)) {
// We already exported this object, hence no need to add another // We already exported this object, hence no need to add another
// ref, v8 won't give us a second weak-object callback anyways. // ref, v8 won't give us a second weak-object callback anyways.
newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value()); newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value());
newobj->SetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY), php_object); newobj->SetAlignedPointerInInternalField(1, value);
return; return;
} }
@ -248,11 +243,10 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
if (ctor_ptr != NULL) { if (ctor_ptr != NULL) {
v8js_call_php_func(value, ce, ctor_ptr, isolate, info TSRMLS_CC); v8js_call_php_func(value, ce, ctor_ptr, isolate, info TSRMLS_CC);
} }
php_object = v8::External::New(isolate, value);
} }
newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value()); newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value());
newobj->SetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY), php_object); newobj->SetAlignedPointerInInternalField(1, value);
// Since we got to decrease the reference count again, in case v8 garbage collector // Since we got to decrease the reference count again, in case v8 garbage collector
// decides to dispose the JS object, we add a weak persistent handle and register // decides to dispose the JS object, we add a weak persistent handle and register
@ -319,7 +313,7 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
uint key_len; uint key_len;
ulong index; ulong index;
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)))->Value()); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
ce = Z_OBJCE_P(object); ce = Z_OBJCE_P(object);
/* enumerate all methods */ /* enumerate all methods */
@ -449,7 +443,7 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
V8JS_TSRMLS_FETCH(); V8JS_TSRMLS_FETCH();
zend_class_entry *ce; zend_class_entry *ce;
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)))->Value()); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
ce = Z_OBJCE_P(object); ce = Z_OBJCE_P(object);
// first arg is method name, second arg is array of args. // first arg is method name, second arg is array of args.
@ -541,7 +535,7 @@ inline v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> p
zend_function *method_ptr = NULL; zend_function *method_ptr = NULL;
zval *php_value; zval *php_value;
zval *object = reinterpret_cast<zval *>(v8::External::Cast(*self->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY)))->Value()); zval *object = reinterpret_cast<zval *>(self->GetAlignedPointerFromInternalField(1));
v8js_tmpl_t *tmpl_ptr = reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0)); v8js_tmpl_t *tmpl_ptr = reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0));
v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New(isolate, *tmpl_ptr); v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New(isolate, *tmpl_ptr);
ce = scope = Z_OBJCE_P(object); ce = scope = Z_OBJCE_P(object);
@ -809,7 +803,7 @@ static v8::Handle<v8::Object> v8js_wrap_object(v8::Isolate *isolate, zend_class_
new_tpl = v8::FunctionTemplate::New(isolate, 0); new_tpl = v8::FunctionTemplate::New(isolate, 0);
new_tpl->SetClassName(V8JS_STRL(ce->name, ce->name_length)); new_tpl->SetClassName(V8JS_STRL(ce->name, ce->name_length));
new_tpl->InstanceTemplate()->SetInternalFieldCount(1); new_tpl->InstanceTemplate()->SetInternalFieldCount(2);
if (ce == zend_ce_closure) { if (ce == zend_ce_closure) {
/* Got a closure, mustn't cache ... */ /* Got a closure, mustn't cache ... */

View File

@ -276,13 +276,8 @@ int v8js_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, i
const char *key = ToCString(cstr); const char *key = ToCString(cstr);
zval *value = NULL; zval *value = NULL;
v8::Local<v8::Value> php_object; if (jsVal->IsObject() && jsVal->ToObject()->InternalFieldCount()) {
if (jsVal->IsObject()) { value = reinterpret_cast<zval *>(jsVal->ToObject()->GetAlignedPointerFromInternalField(1));
php_object = v8::Local<v8::Object>::Cast(jsVal)->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
}
if (!php_object.IsEmpty()) {
/* This is a PHP object, passed to JS and back. */
value = reinterpret_cast<zval *>(v8::External::Cast(*php_object)->Value());
Z_ADDREF_P(value); Z_ADDREF_P(value);
} }
else { else {