0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-22 09:21:52 +00:00

V8 isolates need to be passed into all variable accessor and conversion functions.

This commit is contained in:
Simon Best 2013-04-14 00:36:05 +01:00
parent 8ae7606338
commit 8d8c671aa0
4 changed files with 61 additions and 45 deletions

View File

@ -92,19 +92,19 @@ extern zend_class_entry *php_ce_v8_object;
extern zend_class_entry *php_ce_v8_function;
/* Create PHP V8 object */
void php_v8js_create_v8(zval *, v8::Handle<v8::Value>, int TSRMLS_DC);
void php_v8js_create_v8(zval *, v8::Handle<v8::Value>, int, v8::Isolate * TSRMLS_DC);
/* Fetch V8 object properties */
int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value>, HashTable *, int TSRMLS_DC);
int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value>, HashTable *, int, v8::Isolate * TSRMLS_DC);
/* Convert zval into V8 value */
v8::Handle<v8::Value> zval_to_v8js(zval * TSRMLS_DC);
v8::Handle<v8::Value> zval_to_v8js(zval *, v8::Isolate * TSRMLS_DC);
/* Convert V8 value into zval */
int v8js_to_zval(v8::Handle<v8::Value>, zval *, int TSRMLS_DC);
int v8js_to_zval(v8::Handle<v8::Value>, zval *, int, v8::Isolate * TSRMLS_DC);
/* Register accessors into passed object */
void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate>, zval * TSRMLS_DC);
void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate>, zval *, v8::Isolate * TSRMLS_DC);
/* {{{ Context container */
struct php_v8js_ctx {

34
v8js.cc
View File

@ -112,6 +112,7 @@ struct php_v8js_object {
zend_object std;
v8::Persistent<v8::Value> v8obj;
int flags;
v8::Isolate *isolate;
};
/* }}} */
@ -147,7 +148,7 @@ static zval *php_v8js_v8_read_property(zval *object, zval *member, int type ZEND
MAKE_STD_ZVAL(retval);
}
if (v8js_to_zval(jsVal, retval, obj->flags TSRMLS_CC) == SUCCESS) {
if (v8js_to_zval(jsVal, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) {
return retval;
}
}
@ -164,7 +165,7 @@ static void php_v8js_v8_write_property(zval *object, zval *member, zval *value Z
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
if (obj->v8obj->IsObject() && !obj->v8obj->IsFunction()) {
obj->v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value TSRMLS_CC));
obj->v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, obj->isolate TSRMLS_CC));
}
}
/* }}} */
@ -179,7 +180,7 @@ static void php_v8js_v8_unset_property(zval *object, zval *member ZEND_HASH_KEY_
}
/* }}} */
int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags TSRMLS_DC) /* {{{ */
int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
v8::Local<v8::Object> jsObj = jsValue->ToObject();
@ -202,7 +203,7 @@ int php_v8js_v8_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *re
MAKE_STD_ZVAL(value);
if (v8js_to_zval(jsVal, value, flags TSRMLS_CC) == FAILURE) {
if (v8js_to_zval(jsVal, value, flags, isolate TSRMLS_CC) == FAILURE) {
zval_ptr_dtor(&value);
return FAILURE;
}
@ -223,19 +224,17 @@ static HashTable *php_v8js_v8_get_properties(zval *object TSRMLS_DC) /* {{{ */
{
php_v8js_object *obj = (php_v8js_object *) zend_object_store_get_object(object TSRMLS_CC);
HashTable *retval;
ALLOC_HASHTABLE(retval);
zend_hash_init(retval, 0, NULL, ZVAL_PTR_DTOR, 0);
php_v8js_ctx *c = (php_v8js_ctx *)v8::Context::GetCurrent()->GetAlignedPointerFromEmbedderData(1);
v8::Locker locker(c->isolate);
v8::Isolate::Scope isolate_scope(c->isolate);
v8::HandleScope local_scope(c->isolate);
v8::Locker locker(obj->isolate);
v8::Isolate::Scope isolate_scope(obj->isolate);
v8::HandleScope local_scope(obj->isolate);
v8::Handle<v8::Context> temp_context = v8::Context::New();
v8::Context::Scope temp_scope(temp_context);
if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags TSRMLS_CC) == SUCCESS) {
if (php_v8js_v8_get_properties_hash(obj->v8obj, retval, obj->flags, obj->isolate TSRMLS_CC) == SUCCESS) {
return retval;
}
return NULL;
@ -306,7 +305,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
v8::Local<v8::Value> js_retval;
for (i = 0; i < argc; i++) {
jsArgv[i] = v8::Local<v8::Value>::New(zval_to_v8js(*argv[i] TSRMLS_CC));
jsArgv[i] = v8::Local<v8::Value>::New(zval_to_v8js(*argv[i], obj->isolate TSRMLS_CC));
}
js_retval = cb->Call(V8JS_GLOBAL, argc, jsArgv);
@ -318,7 +317,7 @@ static int php_v8js_v8_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) /
}
if (return_value_used) {
return v8js_to_zval(js_retval, return_value, obj->flags TSRMLS_CC);
return v8js_to_zval(js_retval, return_value, obj->flags, obj->isolate TSRMLS_CC);
}
return SUCCESS;
@ -381,7 +380,7 @@ static zend_object_value php_v8js_v8_new(zend_class_entry *ce TSRMLS_DC) /* {{{
}
/* }}} */
void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags TSRMLS_DC) /* {{{ */
void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
php_v8js_object *c;
@ -391,6 +390,7 @@ void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags TSRMLS
c->v8obj = v8::Persistent<v8::Value>::New(value);
c->flags = flags;
c->isolate = isolate;
}
/* }}} */
@ -626,7 +626,7 @@ static PHP_METHOD(V8Js, __construct)
/* Register Get accessor for passed variables */
if (vars_arr && zend_hash_num_elements(Z_ARRVAL_P(vars_arr)) > 0) {
php_v8js_register_accessors(php_obj_t->InstanceTemplate(), vars_arr TSRMLS_CC);
php_v8js_register_accessors(php_obj_t->InstanceTemplate(), vars_arr, c->isolate TSRMLS_CC);
}
/* Set name for the PHP JS object */
@ -847,7 +847,7 @@ static PHP_METHOD(V8Js, executeString)
/* Convert V8 value to PHP value */
if (!result.IsEmpty()) {
v8js_to_zval(result, return_value, flags TSRMLS_CC);
v8js_to_zval(result, return_value, flags, c->isolate TSRMLS_CC);
}
}
/* }}} */
@ -1090,7 +1090,7 @@ static void php_v8js_write_property(zval *object, zval *member, zval *value ZEND
v8::Local<v8::Object> jsobj = V8JS_GLOBAL->Get(c->object_name)->ToObject();
/* Write value to PHP JS object */
jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value TSRMLS_CC), v8::ReadOnly);
jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, c->isolate TSRMLS_CC), v8::ReadOnly);
/* Write value to PHP object */
std_object_handlers.write_property(object, member, value ZEND_HASH_KEY_CC TSRMLS_CC);

View File

@ -38,6 +38,7 @@ static v8::Handle<v8::Value> php_v8js_php_callback(const v8::Arguments &args) /*
{
v8::Handle<v8::Value> return_value;
zval *value = reinterpret_cast<zval *>(args.This()->GetAlignedPointerFromInternalField(0));
v8::Isolate *isolate = reinterpret_cast<v8::Isolate *>(args.This()->GetAlignedPointerFromInternalField(1));
zend_function *method_ptr;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
@ -99,7 +100,7 @@ static v8::Handle<v8::Value> php_v8js_php_callback(const v8::Arguments &args) /*
argv = (zval **) safe_emalloc(argc, sizeof(zval *), 0);
for (i = 0; i < argc; i++) {
MAKE_STD_ZVAL(argv[i]);
if (v8js_to_zval(args[i], argv[i], flags TSRMLS_CC) == FAILURE) {
if (v8js_to_zval(args[i], argv[i], flags, isolate TSRMLS_CC) == FAILURE) {
fci.param_count++;
error_len = spprintf(&error, 0, "converting parameter #%d passed to %s() failed", i + 1, method_ptr->common.function_name);
return_value = V8JS_THROW(Error, error, error_len);
@ -134,7 +135,7 @@ failure:
}
if (retval_ptr != NULL) {
return_value = zval_to_v8js(retval_ptr TSRMLS_CC);
return_value = zval_to_v8js(retval_ptr, isolate TSRMLS_CC);
zval_ptr_dtor(&retval_ptr);
} else {
return_value = V8JS_NULL;
@ -275,7 +276,7 @@ static v8::Handle<v8::Integer> php_v8js_property_query(v8::Local<v8::String> pro
#define PHP_V8JS_CALLBACK(mptr) \
v8::FunctionTemplate::New(php_v8js_php_callback, v8::External::New(mptr))->GetFunction()
static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{{ */
static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
v8::Local<v8::FunctionTemplate> new_tpl = v8::FunctionTemplate::New();
v8::Local<v8::Object> newobj;
@ -303,7 +304,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
/* Object methods */
if (ce) {
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) {
new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_php_callback);
@ -390,6 +391,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
Z_ADDREF_P(value);
newobj->SetAlignedPointerInInternalField(0, (void *) value);
newobj->SetAlignedPointerInInternalField(1, (void *) isolate);
} else {
new_tpl->SetClassName(V8JS_SYM("Array"));
newobj = new_tpl->InstanceTemplate()->NewInstance();
@ -426,9 +428,9 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
}
continue;
}
newobj->Set(V8JS_STRL(key, key_len - 1), zval_to_v8js(*data TSRMLS_CC), v8::ReadOnly);
newobj->Set(V8JS_STRL(key, key_len - 1), zval_to_v8js(*data, isolate TSRMLS_CC), v8::ReadOnly);
} else {
newobj->Set(index, zval_to_v8js(*data TSRMLS_CC));
newobj->Set(index, zval_to_v8js(*data, isolate TSRMLS_CC));
}
if (tmp_ht) {
@ -441,14 +443,14 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value TSRMLS_DC) /* {{
}
/* }}} */
static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{{ */
static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
HashTable *myht = HASH_OF(value);
int i = myht ? zend_hash_num_elements(myht) : 0;
/* Return object if dealing with assoc array */
if (i > 0 && _php_v8js_is_assoc_array(myht TSRMLS_CC)) {
return php_v8js_hash_to_jsobj(value TSRMLS_CC);
return php_v8js_hash_to_jsobj(value, isolate TSRMLS_CC);
}
v8::Local<v8::Array> newarr;
@ -477,7 +479,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{
tmp_ht->nApplyCount++;
}
newarr->Set(index++, zval_to_v8js(*data TSRMLS_CC));
newarr->Set(index++, zval_to_v8js(*data, isolate TSRMLS_CC));
if (tmp_ht) {
tmp_ht->nApplyCount--;
@ -488,18 +490,18 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsarr(zval *value TSRMLS_DC) /* {{
}
/* }}} */
v8::Handle<v8::Value> zval_to_v8js(zval *value TSRMLS_DC) /* {{{ */
v8::Handle<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
v8::Handle<v8::Value> jsValue;
switch (Z_TYPE_P(value))
{
case IS_ARRAY:
jsValue = php_v8js_hash_to_jsarr(value TSRMLS_CC);
jsValue = php_v8js_hash_to_jsarr(value, isolate TSRMLS_CC);
break;
case IS_OBJECT:
jsValue = php_v8js_hash_to_jsobj(value TSRMLS_CC);
jsValue = php_v8js_hash_to_jsobj(value, isolate TSRMLS_CC);
break;
case IS_STRING:
@ -527,7 +529,7 @@ v8::Handle<v8::Value> zval_to_v8js(zval *value TSRMLS_DC) /* {{{ */
}
/* }}} */
int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags TSRMLS_DC) /* {{{ */
int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
if (jsValue->IsString())
{
@ -576,9 +578,9 @@ int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags TS
{
if ((flags & V8JS_FLAG_FORCE_ARRAY) || jsValue->IsArray()) {
array_init(return_value);
return php_v8js_v8_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags TSRMLS_CC);
return php_v8js_v8_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC);
} else {
php_v8js_create_v8(return_value, jsValue, flags TSRMLS_CC);
php_v8js_create_v8(return_value, jsValue, flags, isolate TSRMLS_CC);
return SUCCESS;
}
}

View File

@ -29,26 +29,34 @@ extern "C" {
#include "php_v8js_macros.h"
#include <v8.h>
#include <string>
struct php_v8js_accessor_ctx
{
char *variable_name_string;
uint variable_name_string_len;
v8::Isolate *isolate;
};
static v8::Handle<v8::Value> php_v8js_fetch_php_variable(v8::Local<v8::String> name, const v8::AccessorInfo &info) /* {{{ */
{
v8::String::Utf8Value variable_name(info.Data()->ToString());
const char *variable_name_string = ToCString(variable_name);
uint variable_name_string_len = strlen(variable_name_string);
v8::Handle<v8::External> data = v8::Handle<v8::External>::Cast(info.Data());
php_v8js_accessor_ctx *ctx = static_cast<php_v8js_accessor_ctx *>(data->Value());
zval **variable;
TSRMLS_FETCH();
zend_is_auto_global(variable_name_string, variable_name_string_len TSRMLS_CC);
zend_is_auto_global(ctx->variable_name_string, ctx->variable_name_string_len TSRMLS_CC);
if (zend_hash_find(&EG(symbol_table), variable_name_string, variable_name_string_len + 1, (void **) &variable) == SUCCESS) {
return zval_to_v8js(*variable TSRMLS_CC);
if (zend_hash_find(&EG(symbol_table), ctx->variable_name_string, ctx->variable_name_string_len + 1, (void **) &variable) == SUCCESS) {
return zval_to_v8js(*variable, ctx->isolate TSRMLS_CC);
}
return v8::Undefined();
}
/* }}} */
void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *array TSRMLS_DC) /* {{{ */
void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *array, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
{
char *property_name;
uint property_name_len;
@ -76,8 +84,14 @@ void php_v8js_register_accessors(v8::Local<v8::ObjectTemplate> php_obj, zval *ar
continue; /* Ignore invalid property names */
}
// Create context to store accessor data
php_v8js_accessor_ctx *ctx = (php_v8js_accessor_ctx *)emalloc(sizeof(php_v8js_accessor_ctx));
ctx->variable_name_string = estrdup(Z_STRVAL_PP(item));
ctx->variable_name_string_len = Z_STRLEN_PP(item);
ctx->isolate = isolate;
/* Set the variable fetch callback for given symbol on named property */
php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, V8JS_STRL(Z_STRVAL_PP(item), Z_STRLEN_PP(item)), v8::PROHIBITS_OVERWRITING, v8::ReadOnly);
php_obj->SetAccessor(V8JS_STRL(property_name, property_name_len - 1), php_v8js_fetch_php_variable, NULL, v8::External::New(ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly);
}
}
/* }}} */