@@ -64,6 +64,37 @@ static inline void php_v8_isolate_destroy(php_v8_isolate_t *php_v8_isolate) {
64
64
}
65
65
}
66
66
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
+ }
67
98
68
99
static HashTable * php_v8_isolate_gc (zval *object, zval **table, int *n) {
69
100
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) {
73
104
size += php_v8_isolate->weak_function_templates ->getGcCount ();
74
105
size += php_v8_isolate->weak_object_templates ->getGcCount ();
75
106
size += php_v8_isolate->weak_values ->getGcCount ();
107
+ size += php_v8_isolate->external_exceptions ->getGcCount ();
76
108
77
109
if (php_v8_isolate->gc_data_count < size) {
78
110
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) {
85
117
php_v8_isolate->weak_function_templates ->collectGcZvals (gc_data);
86
118
php_v8_isolate->weak_object_templates ->collectGcZvals (gc_data);
87
119
php_v8_isolate->weak_values ->collectGcZvals (gc_data);
120
+ php_v8_isolate->external_exceptions ->collectGcZvals (gc_data);
88
121
89
122
*table = php_v8_isolate->gc_data ;
90
123
*n = php_v8_isolate->gc_data_count ;
@@ -109,6 +142,10 @@ static void php_v8_isolate_free(zend_object *object) {
109
142
delete php_v8_isolate->weak_values ;
110
143
}
111
144
145
+ if (php_v8_isolate->external_exceptions ) {
146
+ delete php_v8_isolate->external_exceptions ;
147
+ }
148
+
112
149
if (php_v8_isolate->gc_data ) {
113
150
efree (php_v8_isolate->gc_data );
114
151
}
@@ -159,6 +196,7 @@ static zend_object *php_v8_isolate_ctor(zend_class_entry *ce) {
159
196
php_v8_isolate->weak_function_templates = new phpv8::PersistentCollection<v8::FunctionTemplate>();
160
197
php_v8_isolate->weak_object_templates = new phpv8::PersistentCollection<v8::ObjectTemplate>();
161
198
php_v8_isolate->weak_values = new phpv8::PersistentCollection<v8::Value>();
199
+ php_v8_isolate->external_exceptions = new phpv8::ExternalExceptionsStack ();
162
200
new (&php_v8_isolate->key ) v8::Persistent<v8::Private>();
163
201
164
202
php_v8_isolate->std .handlers = &php_v8_isolate_object_handlers;
@@ -409,6 +447,7 @@ static PHP_METHOD(Isolate, getEnteredContext) {
409
447
}
410
448
411
449
static PHP_METHOD (Isolate, throwException) {
450
+ zval tmp;
412
451
zval *php_v8_context_zv;
413
452
zval *php_v8_value_zv;
414
453
zval *exception_zv = NULL ;
@@ -444,6 +483,9 @@ static PHP_METHOD(Isolate, throwException) {
444
483
}
445
484
446
485
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);
447
489
}
448
490
449
491
isolate->ThrowException (local_value);
0 commit comments