diff --git a/v8js_convert.cc b/v8js_convert.cc index 7a6afe0..4b0e5af 100644 --- a/v8js_convert.cc +++ b/v8js_convert.cc @@ -580,30 +580,17 @@ static inline v8::Local php_v8js_named_property_callback(v8::Localhas_property(object, prop, 2 ZEND_HASH_KEY_NULL TSRMLS_CC)) - ret_value = v8::Handle(); - else { - ret_value = V8JS_NULL; - } - zval_ptr_dtor(&prop); + // special case uninitialized_zval_ptr and return an empty value + // (indicating that we don't intercept this property) if the + // property doesn't exist. + if (php_value == EG(uninitialized_zval_ptr)) { + ret_value = v8::Handle(); } else { // wrap it ret_value = zval_to_v8js(php_value, isolate TSRMLS_CC); - } - /* php_value is the value in the property table; *usually* we - * don't own a reference to it (and so don't have to deref). - * But sometimes the value is the result of a __get() call and - * the refcnt of the returned value is 0. In that case, free - * it. */ - if (php_value != EG(uninitialized_zval_ptr)) { + /* We don't own the reference to php_value... unless the + * returned refcount was 0, in which case the below code + * will free it. */ zval_add_ref(&php_value); zval_ptr_dtor(&php_value); } @@ -615,6 +602,9 @@ static inline v8::Local php_v8js_named_property_callback(v8::Local(); } + // if PHP wanted to hold on to this value, update_property would + // have bumped the refcount + zval_ptr_dtor(&php_value); } else if (callback_type == V8JS_PROP_QUERY || callback_type == V8JS_PROP_DELETER) { const zend_object_handlers *h = Z_OBJ_HT_P(object);