@@ -64,6 +64,37 @@ static inline void php_v8_isolate_destroy(php_v8_isolate_t *php_v8_isolate) {
6464    }
6565}
6666
67+ void  php_v8_isolate_external_exceptions_maybe_clear (php_v8_isolate_t  *php_v8_isolate) {
68+     if  (!php_v8_isolate->limits .depth ) {
69+         php_v8_isolate->external_exceptions ->clear ();
70+     }
71+ }
72+ 
73+ namespace  phpv8  {
74+     int  ExternalExceptionsStack::getGcCount () {
75+         return  static_cast <int >(exceptions.size ());
76+     }
77+     void  ExternalExceptionsStack::collectGcZvals (zval *& zv) {
78+         for  (auto  const  &item : exceptions) {
79+             ZVAL_COPY_VALUE (zv++, &item);
80+         }
81+     }
82+     void  ExternalExceptionsStack::add (zval zv) {
83+         assert (IS_OBJECT == Z_TYPE (zv));
84+         Z_ADDREF (zv);
85+         exceptions.push_back (zv);
86+         assert (exceptions.size () < INT_MAX);
87+     }
88+     void  ExternalExceptionsStack::clear () {
89+         for  (auto  &item : exceptions) {
90+             zval_ptr_dtor (&item);
91+         }
92+         exceptions.clear ();
93+     }
94+     ExternalExceptionsStack::~ExternalExceptionsStack () {
95+         clear ();
96+     }
97+ }
6798
6899static  HashTable * php_v8_isolate_gc (zval *object, zval **table, int  *n) {
69100    PHP_V8_ISOLATE_FETCH_INTO (object, php_v8_isolate);
@@ -73,6 +104,7 @@ static HashTable * php_v8_isolate_gc(zval *object, zval **table, int *n) {
73104    size += php_v8_isolate->weak_function_templates ->getGcCount ();
74105    size += php_v8_isolate->weak_object_templates ->getGcCount ();
75106    size += php_v8_isolate->weak_values ->getGcCount ();
107+     size += php_v8_isolate->external_exceptions ->getGcCount ();
76108
77109    if  (php_v8_isolate->gc_data_count  < size) {
78110        php_v8_isolate->gc_data  = (zval *)safe_erealloc (php_v8_isolate->gc_data , size, sizeof (zval), 0 );
@@ -85,6 +117,7 @@ static HashTable * php_v8_isolate_gc(zval *object, zval **table, int *n) {
85117    php_v8_isolate->weak_function_templates ->collectGcZvals (gc_data);
86118    php_v8_isolate->weak_object_templates ->collectGcZvals (gc_data);
87119    php_v8_isolate->weak_values ->collectGcZvals (gc_data);
120+     php_v8_isolate->external_exceptions ->collectGcZvals (gc_data);
88121
89122    *table = php_v8_isolate->gc_data ;
90123    *n     = php_v8_isolate->gc_data_count ;
@@ -109,6 +142,10 @@ static void php_v8_isolate_free(zend_object *object) {
109142        delete  php_v8_isolate->weak_values ;
110143    }
111144
145+     if  (php_v8_isolate->external_exceptions ) {
146+         delete  php_v8_isolate->external_exceptions ;
147+     }
148+ 
112149    if  (php_v8_isolate->gc_data ) {
113150        efree (php_v8_isolate->gc_data );
114151    }
@@ -159,6 +196,7 @@ static zend_object *php_v8_isolate_ctor(zend_class_entry *ce) {
159196    php_v8_isolate->weak_function_templates  = new  phpv8::PersistentCollection<v8::FunctionTemplate>();
160197    php_v8_isolate->weak_object_templates  = new  phpv8::PersistentCollection<v8::ObjectTemplate>();
161198    php_v8_isolate->weak_values  = new  phpv8::PersistentCollection<v8::Value>();
199+     php_v8_isolate->external_exceptions  = new  phpv8::ExternalExceptionsStack ();
162200    new (&php_v8_isolate->key ) v8::Persistent<v8::Private>();
163201
164202    php_v8_isolate->std .handlers  = &php_v8_isolate_object_handlers;
@@ -409,6 +447,7 @@ static PHP_METHOD(Isolate, getEnteredContext) {
409447}
410448
411449static  PHP_METHOD (Isolate, throwException) {
450+     zval tmp;
412451    zval *php_v8_context_zv;
413452    zval *php_v8_value_zv;
414453    zval *exception_zv = NULL ;
@@ -444,6 +483,9 @@ static PHP_METHOD(Isolate, throwException) {
444483        }
445484
446485        ZVAL_COPY (&php_v8_value->exception , exception_zv);
486+ 
487+         ZVAL_OBJ (&tmp, &php_v8_value->std );
488+         php_v8_isolate->external_exceptions ->add (tmp);
447489    }
448490
449491    isolate->ThrowException (local_value);
0 commit comments