|
@@ -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 <[email protected]> |
|
|
| Author: Jani Taskinen <[email protected]> |
|
|
| Author: Patrick Reilly <[email protected]> |
|
|
| Author: Patrick Reilly <[email protected]> |
|
|
|
|
+ | Author: Stefan Siegl <[email protected]> |
|
|
+----------------------------------------------------------------------+
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
*/
|
|
|
|
|
|
@@ -29,7 +30,7 @@ extern "C" {
|
|
#include "v8js_object_export.h"
|
|
#include "v8js_object_export.h"
|
|
#include "v8js_v8object_class.h"
|
|
#include "v8js_v8object_class.h"
|
|
|
|
|
|
-static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data);
|
|
|
|
|
|
+static void v8js_weak_object_callback(const v8::WeakCallbackInfo<zval> &data);
|
|
|
|
|
|
/* Callback for PHP methods and functions */
|
|
/* Callback for PHP methods and functions */
|
|
static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
|
static void v8js_call_php_func(zval *value, zend_class_entry *ce, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
|
@@ -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()) {
|
|
|
|
- php_object = v8::Local<v8::Object>::Cast(info[i])->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
|
|
|
|
- }
|
|
|
|
- if (!php_object.IsEmpty()) {
|
|
|
|
|
|
+ if (info[i]->IsObject() && info[i]->ToObject()->InternalFieldCount()) {
|
|
/* 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,17 +243,16 @@ 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
|
|
// a callback function that removes the reference.
|
|
// a callback function that removes the reference.
|
|
ctx->weak_objects[value].Reset(isolate, newobj);
|
|
ctx->weak_objects[value].Reset(isolate, newobj);
|
|
- ctx->weak_objects[value].SetWeak(value, v8js_weak_object_callback);
|
|
|
|
|
|
+ ctx->weak_objects[value].SetWeak(value, v8js_weak_object_callback, v8::WeakCallbackType::kParameter);
|
|
|
|
|
|
// Just tell v8 that we're allocating some external memory
|
|
// Just tell v8 that we're allocating some external memory
|
|
// (for the moment we just always tell 1k instead of trying to find out actual values)
|
|
// (for the moment we just always tell 1k instead of trying to find out actual values)
|
|
@@ -267,7 +261,7 @@ static void v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value>& i
|
|
/* }}} */
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
|
-static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data) {
|
|
|
|
|
|
+static void v8js_weak_object_callback(const v8::WeakCallbackInfo<zval> &data) {
|
|
v8::Isolate *isolate = data.GetIsolate();
|
|
v8::Isolate *isolate = data.GetIsolate();
|
|
|
|
|
|
zval *value = data.GetParameter();
|
|
zval *value = data.GetParameter();
|
|
@@ -281,7 +275,7 @@ static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zva
|
|
isolate->AdjustAmountOfExternalAllocatedMemory(-ctx->average_object_size);
|
|
isolate->AdjustAmountOfExternalAllocatedMemory(-ctx->average_object_size);
|
|
}
|
|
}
|
|
|
|
|
|
-static void v8js_weak_closure_callback(const v8::WeakCallbackData<v8::Object, v8js_tmpl_t> &data) {
|
|
|
|
|
|
+static void v8js_weak_closure_callback(const v8::WeakCallbackInfo<v8js_tmpl_t> &data) {
|
|
v8::Isolate *isolate = data.GetIsolate();
|
|
v8::Isolate *isolate = data.GetIsolate();
|
|
|
|
|
|
v8js_tmpl_t *persist_tpl_ = data.GetParameter();
|
|
v8js_tmpl_t *persist_tpl_ = data.GetParameter();
|
|
@@ -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 ... */
|
|
@@ -890,7 +884,7 @@ static v8::Handle<v8::Object> v8js_wrap_object(v8::Isolate *isolate, zend_class_
|
|
if (ce == zend_ce_closure) {
|
|
if (ce == zend_ce_closure) {
|
|
// free uncached function template when object is freed
|
|
// free uncached function template when object is freed
|
|
ctx->weak_closures[persist_tpl_].Reset(isolate, newobj);
|
|
ctx->weak_closures[persist_tpl_].Reset(isolate, newobj);
|
|
- ctx->weak_closures[persist_tpl_].SetWeak(persist_tpl_, v8js_weak_closure_callback);
|
|
|
|
|
|
+ ctx->weak_closures[persist_tpl_].SetWeak(persist_tpl_, v8js_weak_closure_callback, v8::WeakCallbackType::kParameter);
|
|
}
|
|
}
|
|
|
|
|
|
return newobj;
|
|
return newobj;
|