@@ -72,6 +72,7 @@ use boa_engine::{
7272 optimizer:: OptimizerOptions ,
7373 property:: Attribute ,
7474 script:: Script ,
75+ snapshot:: Snapshot ,
7576 vm:: flowgraph:: { Direction , Graph } ,
7677 Context , JsError , JsNativeError , JsResult , Source ,
7778} ;
@@ -81,7 +82,13 @@ use colored::Colorize;
8182use debug:: init_boa_debug_object;
8283use rustyline:: { config:: Config , error:: ReadlineError , EditMode , Editor } ;
8384use std:: {
84- cell:: RefCell , collections:: VecDeque , eprintln, fs:: read, fs:: OpenOptions , io, path:: PathBuf ,
85+ cell:: RefCell ,
86+ collections:: VecDeque ,
87+ eprintln,
88+ fs:: OpenOptions ,
89+ fs:: { read, File } ,
90+ io:: { self , Read } ,
91+ path:: { Path , PathBuf } ,
8592 println,
8693} ;
8794
@@ -168,6 +175,9 @@ struct Opt {
168175 /// Root path from where the module resolver will try to load the modules.
169176 #[ arg( long, short = 'r' , default_value_os_t = PathBuf :: from( "." ) , requires = "mod" ) ]
170177 root : PathBuf ,
178+
179+ #[ arg( long) ]
180+ snapshot : Option < PathBuf > ,
171181}
172182
173183impl Opt {
@@ -363,37 +373,60 @@ fn evaluate_files(
363373 Ok ( ( ) )
364374}
365375
376+ fn get_file_as_byte_vec ( filename : & Path ) -> Vec < u8 > {
377+ let mut f = File :: open ( & filename) . expect ( "no file found" ) ;
378+ let metadata = std:: fs:: metadata ( & filename) . expect ( "unable to read metadata" ) ;
379+ let mut buffer = vec ! [ 0 ; metadata. len( ) as usize ] ;
380+ f. read ( & mut buffer) . expect ( "buffer overflow" ) ;
381+
382+ buffer
383+ }
384+
366385fn main ( ) -> Result < ( ) , io:: Error > {
367386 let args = Opt :: parse ( ) ;
368387
369- let queue: & dyn JobQueue = & Jobs :: default ( ) ;
370388 let loader = & SimpleModuleLoader :: new ( & args. root )
371389 . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e. to_string ( ) ) ) ?;
390+
391+ let queue: & dyn JobQueue = & Jobs :: default ( ) ;
372392 let dyn_loader: & dyn ModuleLoader = loader;
373- let mut context = ContextBuilder :: new ( )
374- . job_queue ( queue)
375- . module_loader ( dyn_loader)
376- . build ( )
377- . expect ( "cannot fail with default global object" ) ;
378393
379- // Strict mode
380- context . strict ( args . strict ) ;
394+ let mut context = if let Some ( path ) = & args . snapshot {
395+ let bytes = get_file_as_byte_vec ( & path ) ;
381396
382- // Add `console`.
383- add_runtime ( & mut context) ;
397+ let snapshot = Snapshot :: new ( bytes) ;
384398
385- // Trace Output
386- context. set_trace ( args. trace ) ;
399+ let deser_context = snapshot. deserialize ( ) . unwrap ( ) ;
387400
388- if args. debug_object {
389- init_boa_debug_object ( & mut context) ;
390- }
401+ deser_context
402+ } else {
403+ let mut context = ContextBuilder :: new ( )
404+ . job_queue ( queue)
405+ . module_loader ( dyn_loader)
406+ . build ( )
407+ . expect ( "cannot fail with default global object" ) ;
408+
409+ // Strict mode
410+ context. strict ( args. strict ) ;
411+
412+ // Add `console`.
413+ add_runtime ( & mut context) ;
414+
415+ // Trace Output
416+ context. set_trace ( args. trace ) ;
391417
392- // Configure optimizer options
393- let mut optimizer_options = OptimizerOptions :: empty ( ) ;
394- optimizer_options. set ( OptimizerOptions :: STATISTICS , args. optimizer_statistics ) ;
395- optimizer_options. set ( OptimizerOptions :: OPTIMIZE_ALL , args. optimize ) ;
396- context. set_optimizer_options ( optimizer_options) ;
418+ if args. debug_object {
419+ init_boa_debug_object ( & mut context) ;
420+ }
421+
422+ // Configure optimizer options
423+ let mut optimizer_options = OptimizerOptions :: empty ( ) ;
424+ optimizer_options. set ( OptimizerOptions :: STATISTICS , args. optimizer_statistics ) ;
425+ optimizer_options. set ( OptimizerOptions :: OPTIMIZE_ALL , args. optimize ) ;
426+ context. set_optimizer_options ( optimizer_options) ;
427+
428+ context
429+ } ;
397430
398431 if args. files . is_empty ( ) {
399432 let config = Config :: builder ( )
0 commit comments