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

Correctly attach hidden values to objects from cached templates.

This commit is contained in:
Stefan Siegl 2013-06-12 14:46:39 +02:00
parent bc1cf7c5bb
commit ee659bdf41

View File

@ -319,13 +319,15 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
/* Object methods */ /* Object methods */
if (ce) { if (ce) {
v8::Handle<v8::FunctionTemplate> new_tpl; v8::Handle<v8::FunctionTemplate> new_tpl;
bool cached_tpl = true;
static std::map<const char *, v8::Persistent<v8::FunctionTemplate> > tpl_map; static std::map<const char *, v8::Persistent<v8::FunctionTemplate> > tpl_map;
std::map<const char *, v8::Persistent<v8::FunctionTemplate> >::iterator it;
try { try {
new_tpl = tpl_map.at(ce->name); new_tpl = tpl_map.at(ce->name);
} }
catch (const std::out_of_range &) { catch (const std::out_of_range &) {
cached_tpl = false;
/* No cached v8::FunctionTemplate available as of yet, create one. */ /* No cached v8::FunctionTemplate available as of yet, create one. */
new_tpl = v8::FunctionTemplate::New(); new_tpl = v8::FunctionTemplate::New();
@ -338,7 +340,10 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
} else { } else {
/* Add new v8::FunctionTemplate to tpl_map, as long as it is not a closure. */ /* Add new v8::FunctionTemplate to tpl_map, as long as it is not a closure. */
tpl_map[ce->name] = v8::Persistent<v8::FunctionTemplate>::New(isolate, new_tpl); tpl_map[ce->name] = v8::Persistent<v8::FunctionTemplate>::New(isolate, new_tpl);
}
}
if (ce != zend_ce_closure) {
/* Attach object methods to the instance template. */ /* Attach object methods to the instance template. */
zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos); zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
for (;; zend_hash_move_forward_ex(&ce->function_table, &pos)) { for (;; zend_hash_move_forward_ex(&ce->function_table, &pos)) {
@ -354,7 +359,7 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
(method_ptr->common.fn_flags & ZEND_ACC_CLONE) == 0 /* ..or __clone() functions */ (method_ptr->common.fn_flags & ZEND_ACC_CLONE) == 0 /* ..or __clone() functions */
) { ) {
/* Override native toString() with __tostring() if it is set in passed object */ /* Override native toString() with __tostring() if it is set in passed object */
if (IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME)) { if (!cached_tpl && IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME)) {
new_tpl->InstanceTemplate()->Set(V8JS_SYM("toString"), PHP_V8JS_CALLBACK(method_ptr)); new_tpl->InstanceTemplate()->Set(V8JS_SYM("toString"), PHP_V8JS_CALLBACK(method_ptr));
/* TODO: __set(), __unset() disabled as JS is not allowed to modify the passed PHP object yet. /* TODO: __set(), __unset() disabled as JS is not allowed to modify the passed PHP object yet.
* __sleep(), __wakeup(), __set_state() are always ignored */ * __sleep(), __wakeup(), __set_state() are always ignored */
@ -375,13 +380,13 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
invoke_ptr = method_ptr; invoke_ptr = method_ptr;
} else if (IS_MAGIC_FUNC(ZEND_ISSET_FUNC_NAME)) { } else if (IS_MAGIC_FUNC(ZEND_ISSET_FUNC_NAME)) {
isset_ptr = method_ptr; isset_ptr = method_ptr;
} else { } else if (!cached_tpl) {
new_tpl->InstanceTemplate()->Set(V8JS_STR(method_ptr->common.function_name), PHP_V8JS_CALLBACK(method_ptr), v8::ReadOnly); new_tpl->InstanceTemplate()->Set(V8JS_STR(method_ptr->common.function_name), PHP_V8JS_CALLBACK(method_ptr), v8::ReadOnly);
} }
} }
} }
if (!cached_tpl) {
/* Only register getter, etc. when they're set in PHP side */ /* Only register getter, etc. when they're set in PHP side */
if (call_ptr || get_ptr || isset_ptr) if (call_ptr || get_ptr || isset_ptr)
{ {
@ -396,7 +401,6 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
); );
} }
/* __invoke() handler */ /* __invoke() handler */
if (invoke_ptr) { if (invoke_ptr) {
new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_property_caller, V8JS_SYM(ZEND_INVOKE_FUNC_NAME)); new_tpl->InstanceTemplate()->SetCallAsFunctionHandler(php_v8js_property_caller, V8JS_SYM(ZEND_INVOKE_FUNC_NAME));
@ -416,7 +420,9 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
newobj = persist_newobj; newobj = persist_newobj;
if (ce != zend_ce_closure) { // @fixme all of those get lost, when using cached templates if (ce != zend_ce_closure) {
// These unfortunately cannot be attached to the template, hence we have to put them
// on each and every object instance manually.
if (call_ptr) { if (call_ptr) {
newobj->SetHiddenValue(V8JS_SYM(ZEND_CALL_FUNC_NAME), PHP_V8JS_CALLBACK(call_ptr)); newobj->SetHiddenValue(V8JS_SYM(ZEND_CALL_FUNC_NAME), PHP_V8JS_CALLBACK(call_ptr));
} }