|  | @@ -29,6 +29,8 @@ extern "C" {
 | 
	
		
			
				|  |  |  #include <v8.h>
 | 
	
		
			
				|  |  |  #include <stdexcept>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void php_v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zval> &data);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /* Callback for PHP methods and functions */
 | 
	
		
			
				|  |  |  static void php_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) /* {{{ */
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -178,6 +180,7 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
 | 
	
		
			
				|  |  |  	// @todo assert constructor call
 | 
	
		
			
				|  |  |  	v8::Handle<v8::Object> newobj = info.This();
 | 
	
		
			
				|  |  |  	v8::Local<v8::External> php_object;
 | 
	
		
			
				|  |  | +	zval *value;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if (!info.IsConstructCall()) {
 | 
	
		
			
				|  |  |  		return;
 | 
	
	
		
			
				|  | @@ -190,6 +193,10 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
 | 
	
		
			
				|  |  |  	if (info[0]->IsExternal()) {
 | 
	
		
			
				|  |  |  		// Object created by v8js in php_v8js_hash_to_jsobj, PHP object passed as v8::External.
 | 
	
		
			
				|  |  |  		php_object = v8::Local<v8::External>::Cast(info[0]);
 | 
	
		
			
				|  |  | +		value = reinterpret_cast<zval *>(php_object->Value());
 | 
	
		
			
				|  |  | +		// Increase the reference count of this value because we're storing it internally for use later
 | 
	
		
			
				|  |  | +		// See https://github.com/preillyme/v8js/issues/6
 | 
	
		
			
				|  |  | +		Z_ADDREF_P(value);
 | 
	
		
			
				|  |  |  	} else {
 | 
	
		
			
				|  |  |  		// Object created from JavaScript context.  Need to create PHP object first.
 | 
	
		
			
				|  |  |  		V8JS_TSRMLS_FETCH();
 | 
	
	
		
			
				|  | @@ -202,7 +209,6 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
 | 
	
		
			
				|  |  |  			return;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		zval *value;
 | 
	
		
			
				|  |  |  		MAKE_STD_ZVAL(value);
 | 
	
		
			
				|  |  |  		object_init_ex(value, ce);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -215,6 +221,16 @@ static void php_v8js_construct_callback(const v8::FunctionCallbackInfo<v8::Value
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	newobj->SetAlignedPointerInInternalField(0, ext_tmpl->Value());
 | 
	
		
			
				|  |  |  	newobj->SetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY), php_object);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 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
 | 
	
		
			
				|  |  | +	// a callback function that removes the reference.
 | 
	
		
			
				|  |  | +	v8::Persistent<v8::Object> persist_newobj(isolate, newobj);
 | 
	
		
			
				|  |  | +	persist_newobj.SetWeak(value, php_v8js_weak_object_callback);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 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)
 | 
	
		
			
				|  |  | +	v8::V8::AdjustAmountOfExternalAllocatedMemory(1024);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  /* }}} */
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -734,20 +750,6 @@ static v8::Handle<v8::Value> php_v8js_hash_to_jsobj(zval *value, v8::Isolate *is
 | 
	
		
			
				|  |  |  		v8::Handle<v8::Value> external = v8::External::New(value);
 | 
	
		
			
				|  |  |  		newobj = new_tpl->GetFunction()->NewInstance(1, &external);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		// Increase the reference count of this value because we're storing it internally for use later
 | 
	
		
			
				|  |  | -		// See https://github.com/preillyme/v8js/issues/6
 | 
	
		
			
				|  |  | -		Z_ADDREF_P(value);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		// 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
 | 
	
		
			
				|  |  | -		// a callback function that removes the reference.
 | 
	
		
			
				|  |  | -		v8::Persistent<v8::Object> persist_newobj(isolate, newobj);
 | 
	
		
			
				|  |  | -		persist_newobj.SetWeak(value, php_v8js_weak_object_callback);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		// 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)
 | 
	
		
			
				|  |  | -		v8::V8::AdjustAmountOfExternalAllocatedMemory(1024);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  		if (ce == zend_ce_closure) {
 | 
	
		
			
				|  |  |  			// free uncached function template when object is freed
 | 
	
		
			
				|  |  |  			v8::Persistent<v8::Object> persist_newobj2(isolate, newobj);
 |