@@ -2,17 +2,17 @@ use ext_php_rs::binary::Binary;
2
2
use ext_php_rs:: builders:: ClassBuilder ;
3
3
use ext_php_rs:: convert:: { FromZval , IntoZval } ;
4
4
use ext_php_rs:: flags:: DataType ;
5
- use ext_php_rs:: types:: { ZendHashTable , ZendObject , Zval , ZendClassObject } ;
5
+ use ext_php_rs:: types:: { ZendClassObject , ZendHashTable , Zval } ;
6
6
use ext_php_rs:: zend:: { ClassEntry , ModuleEntry } ;
7
7
use ext_php_rs:: { exception:: PhpException , zend:: ce} ;
8
- use ext_php_rs:: { info_table_end, info_table_row, info_table_start, prelude:: * , php_print } ;
8
+ use ext_php_rs:: { info_table_end, info_table_row, info_table_start, php_print , prelude:: * } ;
9
9
10
10
use std:: collections:: HashMap ;
11
11
12
12
mod runtime;
13
13
14
- pub use crate :: runtime:: JSRuntime ;
15
14
pub use crate :: runtime:: Error as RuntimeError ;
15
+ pub use crate :: runtime:: JSRuntime ;
16
16
17
17
static mut V8JS_TIME_LIMIT_EXCEPTION : Option < & ' static ClassEntry > = None ;
18
18
static mut V8JS_MEMORY_LIMIT_EXCEPTION : Option < & ' static ClassEntry > = None ;
@@ -54,8 +54,10 @@ pub fn zval_from_jsvalue(result: v8::Local<v8::Value>, scope: &mut v8::HandleSco
54
54
}
55
55
if result. is_object ( ) {
56
56
let object = v8:: Local :: < v8:: Object > :: try_from ( result) . unwrap ( ) ;
57
- let properties = object. get_own_property_names ( scope, Default :: default ( ) ) . unwrap ( ) ;
58
- let mut obj = ZendClassObject :: new ( V8Object { } ) ;
57
+ let properties = object
58
+ . get_own_property_names ( scope, Default :: default ( ) )
59
+ . unwrap ( ) ;
60
+ let mut obj = ZendClassObject :: new ( V8Object { } ) ;
59
61
let zend_object = obj. get_mut_zend_obj ( ) ;
60
62
for index in 0 ..properties. length ( ) {
61
63
let key = properties. get_index ( scope, index) . unwrap ( ) ;
@@ -105,11 +107,15 @@ pub fn js_value_from_zval<'a>(
105
107
let mut values: Vec < v8:: Local < ' _ , v8:: Value > > = Vec :: new ( ) ;
106
108
let mut keys: Vec < v8:: Local < ' _ , v8:: Name > > = Vec :: new ( ) ;
107
109
for ( key, elem) in zend_array. iter ( ) {
108
- keys. push ( v8:: String :: new ( scope, key. to_string ( ) . as_str ( ) ) . unwrap ( ) . into ( ) ) ;
110
+ keys. push (
111
+ v8:: String :: new ( scope, key. to_string ( ) . as_str ( ) )
112
+ . unwrap ( )
113
+ . into ( ) ,
114
+ ) ;
109
115
values. push ( js_value_from_zval ( scope, elem) ) ;
110
116
}
111
117
112
- if ! zend_array. has_numerical_keys ( ) {
118
+ if !zend_array. has_numerical_keys ( ) {
113
119
let null: v8:: Local < v8:: Value > = v8:: null ( scope) . into ( ) ;
114
120
return v8:: Object :: with_prototype_and_properties ( scope, null, & keys[ ..] , & values[ ..] )
115
121
. into ( ) ;
@@ -152,9 +158,12 @@ impl V8Js {
152
158
let mut runtime = JSRuntime :: new ( snapshot_blob) ;
153
159
let object: v8:: Global < v8:: Value > ;
154
160
{
155
- let scope = & mut runtime. handle_scope ( ) ;
156
- let o: v8:: Local < v8:: Value > = v8:: Object :: new ( scope) . into ( ) ;
157
- object = v8:: Global :: new ( scope, o) ;
161
+ let context = runtime. global_context ( ) ;
162
+ let mut isolate = runtime. isolate ( ) ;
163
+ let isolate = & mut * isolate;
164
+ let mut scope = v8:: HandleScope :: with_context ( isolate, context) ;
165
+ let o: v8:: Local < v8:: Value > = v8:: Object :: new ( & mut scope) . into ( ) ;
166
+ object = v8:: Global :: new ( & mut scope, o) ;
158
167
}
159
168
runtime. add_global ( global_name. as_str ( ) , object) ;
160
169
runtime. add_global_function ( "var_dump" , php_callback_var_dump) ;
@@ -170,7 +179,7 @@ impl V8Js {
170
179
}
171
180
172
181
pub fn set_module_loader ( & mut self , callable : & Zval ) {
173
- let state = self . runtime . get_state ( ) ;
182
+ let state = JSRuntime :: state ( self . runtime . isolate ( ) . as_mut ( ) ) ;
174
183
let mut state = state. borrow_mut ( ) ;
175
184
state. commonjs_module_loader = Some ( callable. shallow_clone ( ) ) ;
176
185
}
@@ -194,8 +203,11 @@ impl V8Js {
194
203
match result {
195
204
Ok ( result) => match result {
196
205
Some ( result) => {
197
- let mut scope = & mut self . runtime . handle_scope ( ) ;
198
- let local = v8:: Local :: new ( scope, result) ;
206
+ let context = self . runtime . global_context ( ) ;
207
+ let mut isolate = self . runtime . isolate ( ) ;
208
+ let isolate = & mut * isolate;
209
+ let mut scope = v8:: HandleScope :: with_context ( isolate, context) ;
210
+ let local = v8:: Local :: new ( & mut scope, result) ;
199
211
Ok ( zval_from_jsvalue ( local, & mut scope) )
200
212
}
201
213
None => {
@@ -204,20 +216,20 @@ impl V8Js {
204
216
Ok ( zval)
205
217
}
206
218
} ,
207
- Err ( e) => {
208
- match e {
209
- RuntimeError :: ExecutionTimeout => {
210
- Err ( PhpException :: new ( "" . into ( ) , 0 , unsafe { V8JS_TIME_LIMIT_EXCEPTION . unwrap ( ) } ) )
211
- } ,
212
- RuntimeError :: MemoryLimitExceeded => {
213
- Err ( PhpException :: new ( "" . into ( ) , 0 , unsafe { V8JS_MEMORY_LIMIT_EXCEPTION . unwrap ( ) } ) )
214
- } ,
215
- RuntimeError :: ScriptExecutionError ( error) => {
216
- Err ( PhpException :: new ( error. message . into ( ) , 0 , unsafe { V8JS_SCRIPT_EXCEPTION . unwrap ( ) } ) )
217
- }
218
- _ => Err ( PhpException :: default ( String :: from ( "Unknown error." ) ) )
219
+ Err ( e) => match e {
220
+ RuntimeError :: ExecutionTimeout => Err ( PhpException :: new ( "" . into ( ) , 0 , unsafe {
221
+ V8JS_TIME_LIMIT_EXCEPTION . unwrap ( )
222
+ } ) ) ,
223
+ RuntimeError :: MemoryLimitExceeded => Err ( PhpException :: new ( "" . into ( ) , 0 , unsafe {
224
+ V8JS_MEMORY_LIMIT_EXCEPTION . unwrap ( )
225
+ } ) ) ,
226
+ RuntimeError :: ScriptExecutionError ( error) => {
227
+ Err ( PhpException :: new ( error. message . into ( ) , 0 , unsafe {
228
+ V8JS_SCRIPT_EXCEPTION . unwrap ( )
229
+ } ) )
219
230
}
220
- }
231
+ _ => Err ( PhpException :: default ( String :: from ( "Unknown error." ) ) ) ,
232
+ } ,
221
233
}
222
234
}
223
235
@@ -228,7 +240,12 @@ impl V8Js {
228
240
Some ( global) => global,
229
241
None => return ( ) ,
230
242
} ;
231
- let mut scope = self . runtime . handle_scope ( ) ;
243
+
244
+ let context = self . runtime . global_context ( ) ;
245
+ let mut isolate = self . runtime . isolate ( ) ;
246
+ let isolate = & mut * isolate;
247
+ let mut scope = v8:: HandleScope :: with_context ( isolate, context) ;
248
+
232
249
let global = v8:: Local :: new ( & mut scope, global) ;
233
250
let global: v8:: Local < v8:: Object > = v8:: Local :: < v8:: Object > :: try_from ( global) . unwrap ( ) ;
234
251
let property_name = v8:: String :: new ( & mut scope, property) . unwrap ( ) ;
@@ -372,7 +389,7 @@ pub fn php_callback_print(
372
389
args : v8:: FunctionCallbackArguments ,
373
390
mut _rv : v8:: ReturnValue ,
374
391
) {
375
- php_print ! ( "{}" , args. get( 0 ) . to_rust_string_lossy( scope) ) ;
392
+ php_print ! ( "{}" , args. get( 0 ) . to_rust_string_lossy( scope) ) ;
376
393
}
377
394
378
395
pub fn php_callback_exit (
@@ -465,7 +482,6 @@ pub extern "C" fn php_module_info(_module: *mut ModuleEntry) {
465
482
info_table_end ! ( ) ;
466
483
}
467
484
468
-
469
485
#[ php_startup]
470
486
pub fn startup ( ) {
471
487
let ce = ClassBuilder :: new ( "V8JsTimeLimitException" )
@@ -487,9 +503,22 @@ pub fn startup() {
487
503
unsafe { V8JS_SCRIPT_EXCEPTION . replace ( ce) } ;
488
504
}
489
505
506
+ extern "C" fn request_shutdown ( module : i32 , _: i32 ) -> i32 {
507
+ runtime:: ISOLATES . with ( |isolates| {
508
+ let mut isolates = isolates. borrow_mut ( ) ;
509
+ // Loop through each item in the isolates vec in reverse order and remove them.
510
+ for index in ( 0 ..isolates. len ( ) ) . rev ( ) {
511
+ isolates. remove ( index) ;
512
+ }
513
+ } ) ;
514
+ module
515
+ }
516
+
490
517
#[ php_module]
491
518
pub fn get_module ( module : ModuleBuilder ) -> ModuleBuilder {
492
- module. info_function ( php_module_info)
519
+ module
520
+ . info_function ( php_module_info)
521
+ . request_shutdown_function ( request_shutdown)
493
522
}
494
523
495
524
#[ cfg( test) ]
0 commit comments