@@ -91,7 +91,10 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
91
91
return 0 ;
92
92
}
93
93
94
- uint16_t start_offset = (uint16_t ) (globals_p -> snapshot_buffer_write_offset >> JMEM_ALIGNMENT_LOG );
94
+ /* The snapshot generator always parses a single file,
95
+ * so the base always starts right after the snapshot header. */
96
+ size_t buffer_offset = globals_p -> snapshot_buffer_write_offset - sizeof (jerry_snapshot_header_t );
97
+ uint16_t start_offset = (uint16_t ) (buffer_offset >> JMEM_ALIGNMENT_LOG );
95
98
96
99
uint8_t * copied_code_start_p = snapshot_buffer_p + globals_p -> snapshot_buffer_write_offset ;
97
100
ecma_compiled_code_t * copied_code_p = (ecma_compiled_code_t * ) copied_code_start_p ;
@@ -252,10 +255,10 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
252
255
{
253
256
for (uint32_t i = 0 ; i < argument_end ; i ++ )
254
257
{
255
- lit_mem_to_snapshot_id_map_entry_t * current_p = lit_map_p ;
256
-
257
258
if (literal_start_p [i ] != JMEM_CP_NULL )
258
259
{
260
+ lit_mem_to_snapshot_id_map_entry_t * current_p = lit_map_p ;
261
+
259
262
while (current_p -> literal_id != literal_start_p [i ])
260
263
{
261
264
current_p ++ ;
@@ -316,12 +319,14 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
316
319
* @return byte code
317
320
*/
318
321
static ecma_compiled_code_t *
319
- snapshot_load_compiled_code (const uint8_t * snapshot_data_p , /**< snapshot data */
322
+ snapshot_load_compiled_code (const uint8_t * base_addr_p , /**< base address of the
323
+ * current primary function */
320
324
size_t offset , /**< byte code offset */
321
- lit_mem_to_snapshot_id_map_entry_t * lit_map_p , /**< literal map */
325
+ const uint8_t * literal_base_p , /**< literal start */
326
+ const uint8_t * number_base_p , /**< literal number start */
322
327
bool copy_bytecode ) /**< byte code should be copied to memory */
323
328
{
324
- ecma_compiled_code_t * bytecode_p = (ecma_compiled_code_t * ) (snapshot_data_p + offset );
329
+ ecma_compiled_code_t * bytecode_p = (ecma_compiled_code_t * ) (base_addr_p + offset );
325
330
uint32_t code_size = ((uint32_t ) bytecode_p -> size ) << JMEM_ALIGNMENT_LOG ;
326
331
327
332
if (!(bytecode_p -> status_flags & CBC_CODE_FLAGS_FUNCTION ))
@@ -373,7 +378,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
373
378
{
374
379
bytecode_p = (ecma_compiled_code_t * ) jmem_heap_alloc_block (code_size );
375
380
376
- memcpy (bytecode_p , snapshot_data_p + offset , code_size );
381
+ memcpy (bytecode_p , base_addr_p + offset , code_size );
377
382
}
378
383
else
379
384
{
@@ -384,7 +389,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
384
389
385
390
bytecode_p = (ecma_compiled_code_t * ) jmem_heap_alloc_block (total_size );
386
391
387
- memcpy (bytecode_p , snapshot_data_p + offset , code_size );
392
+ memcpy (bytecode_p , base_addr_p + offset , code_size );
388
393
389
394
bytecode_p -> size = (uint16_t ) (total_size >> JMEM_ALIGNMENT_LOG );
390
395
@@ -404,17 +409,9 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
404
409
405
410
for (uint32_t i = 0 ; i < const_literal_end ; i ++ )
406
411
{
407
- lit_mem_to_snapshot_id_map_entry_t * current_p = lit_map_p ;
408
-
409
- if (literal_start_p [i ] != 0 )
410
- {
411
- while (current_p -> literal_offset != literal_start_p [i ])
412
- {
413
- current_p ++ ;
414
- }
415
-
416
- literal_start_p [i ] = current_p -> literal_id ;
417
- }
412
+ literal_start_p [i ] = ecma_snapshot_get_literal (literal_base_p ,
413
+ number_base_p ,
414
+ literal_start_p [i ]);
418
415
}
419
416
420
417
for (uint32_t i = const_literal_end ; i < literal_end ; i ++ )
@@ -430,9 +427,10 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
430
427
else
431
428
{
432
429
ecma_compiled_code_t * literal_bytecode_p ;
433
- literal_bytecode_p = snapshot_load_compiled_code (snapshot_data_p ,
430
+ literal_bytecode_p = snapshot_load_compiled_code (base_addr_p ,
434
431
literal_offset ,
435
- lit_map_p ,
432
+ literal_base_p ,
433
+ number_base_p ,
436
434
copy_bytecode );
437
435
438
436
ECMA_SET_NON_NULL_POINTER (literal_start_p [i ],
@@ -492,7 +490,13 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
492
490
jerry_snapshot_header_t header ;
493
491
header .version = JERRY_SNAPSHOT_VERSION ;
494
492
header .lit_table_offset = (uint32_t ) globals .snapshot_buffer_write_offset ;
495
- header .is_run_global = is_for_global ;
493
+ header .number_of_funcs = 1 ;
494
+ header .func_offsets [0 ] = sizeof (jerry_snapshot_header_t );
495
+
496
+ if (!is_for_global )
497
+ {
498
+ header .func_offsets [0 ] |= JERRY_SNAPSHOT_EVAL_CONTEXT ;
499
+ }
496
500
497
501
lit_mem_to_snapshot_id_map_entry_t * lit_map_p = NULL ;
498
502
uint32_t literals_num ;
@@ -501,8 +505,7 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
501
505
buffer_size ,
502
506
& globals .snapshot_buffer_write_offset ,
503
507
& lit_map_p ,
504
- & literals_num ,
505
- & header .lit_table_size ))
508
+ & literals_num ))
506
509
{
507
510
JERRY_ASSERT (lit_map_p == NULL );
508
511
return 0 ;
@@ -551,15 +554,16 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
551
554
* thrown error - otherwise
552
555
*/
553
556
jerry_value_t
554
- jerry_exec_snapshot (const uint32_t * snapshot_p , /**< snapshot */
555
- size_t snapshot_size , /**< size of snapshot */
556
- bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
557
- * buffer should be copied to the engine's memory.
558
- * If set the engine should not reference the buffer
559
- * after the function returns (in this case, the passed
560
- * buffer could be freed after the call).
561
- * Otherwise (if the flag is not set) - the buffer could only be
562
- * freed after the engine stops (i.e. after call to jerry_cleanup). */
557
+ jerry_exec_snapshot_at (const uint32_t * snapshot_p , /**< snapshot */
558
+ size_t snapshot_size , /**< size of snapshot */
559
+ size_t func_index , /**< index of primary function */
560
+ bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
561
+ * buffer should be copied to the engine's memory.
562
+ * If set the engine should not reference the buffer
563
+ * after the function returns (in this case, the passed
564
+ * buffer could be freed after the call).
565
+ * Otherwise (if the flag is not set) - the buffer could only be
566
+ * freed after the engine stops (i.e. after call to jerry_cleanup). */
563
567
{
564
568
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
565
569
JERRY_ASSERT (snapshot_p != NULL );
@@ -580,34 +584,32 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
580
584
return ecma_raise_type_error (invalid_version_error_p );
581
585
}
582
586
583
- lit_mem_to_snapshot_id_map_entry_t * lit_map_p = NULL ;
584
- uint32_t literals_num ;
585
-
586
587
if (header_p -> lit_table_offset >= snapshot_size )
587
588
{
588
589
return ecma_raise_type_error (invalid_version_error_p );
589
590
}
590
591
591
- JERRY_ASSERT ((header_p -> lit_table_offset % sizeof (uint32_t )) == 0 );
592
- if (!ecma_load_literals_from_snapshot ((uint32_t * ) (snapshot_data_p + header_p -> lit_table_offset ),
593
- header_p -> lit_table_size ,
594
- & lit_map_p ,
595
- & literals_num ))
592
+ if (func_index >= header_p -> number_of_funcs )
596
593
{
597
- JERRY_ASSERT (lit_map_p == NULL );
598
- return ecma_raise_type_error (invalid_format_error_p );
594
+ return ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum" ));
599
595
}
600
596
597
+ JERRY_ASSERT ((header_p -> lit_table_offset % sizeof (uint32_t )) == 0 );
598
+
599
+ const uint8_t * literal_base_p ;
600
+ const uint8_t * number_base_p ;
601
+
602
+ literal_base_p = ecma_snapshot_get_literals_base ((uint32_t * ) (snapshot_data_p + header_p -> lit_table_offset ),
603
+ & number_base_p );
604
+
601
605
ecma_compiled_code_t * bytecode_p ;
602
- bytecode_p = snapshot_load_compiled_code (snapshot_data_p ,
603
- sizeof (jerry_snapshot_header_t ),
604
- lit_map_p ,
605
- copy_bytecode );
606
606
607
- if (lit_map_p != NULL )
608
- {
609
- jmem_heap_free_block (lit_map_p , literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t ));
610
- }
607
+ uint32_t func_offset = header_p -> func_offsets [func_index ] & ~JERRY_SNAPSHOT_EVAL_CONTEXT ;
608
+ bytecode_p = snapshot_load_compiled_code (snapshot_data_p + func_offset ,
609
+ 0 ,
610
+ literal_base_p ,
611
+ number_base_p ,
612
+ copy_bytecode );
611
613
612
614
if (bytecode_p == NULL )
613
615
{
@@ -616,17 +618,49 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
616
618
617
619
ecma_value_t ret_val ;
618
620
619
- if (header_p -> is_run_global )
621
+ if (header_p -> func_offsets [ func_index ] & JERRY_SNAPSHOT_EVAL_CONTEXT )
620
622
{
621
- ret_val = vm_run_global (bytecode_p );
622
- ecma_bytecode_deref (bytecode_p );
623
+ ret_val = vm_run_eval (bytecode_p , false);
623
624
}
624
625
else
625
626
{
626
- ret_val = vm_run_eval (bytecode_p , false);
627
+ ret_val = vm_run_global (bytecode_p );
628
+ ecma_bytecode_deref (bytecode_p );
627
629
}
628
630
629
631
return ret_val ;
632
+ #else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
633
+ JERRY_UNUSED (snapshot_p );
634
+ JERRY_UNUSED (snapshot_size );
635
+ JERRY_UNUSED (func_index );
636
+ JERRY_UNUSED (copy_bytecode );
637
+
638
+ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE );
639
+ #endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
640
+ } /* jerry_exec_snapshot_at */
641
+
642
+ /**
643
+ * Execute snapshot from specified buffer
644
+ *
645
+ * Note:
646
+ * returned value must be freed with jerry_release_value, when it is no longer needed.
647
+ *
648
+ * @return result of bytecode - if run was successful
649
+ * thrown error - otherwise
650
+ */
651
+ jerry_value_t
652
+ jerry_exec_snapshot (const uint32_t * snapshot_p , /**< snapshot */
653
+ size_t snapshot_size , /**< size of snapshot */
654
+ bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
655
+ * buffer should be copied to the engine's memory.
656
+ * If set the engine should not reference the buffer
657
+ * after the function returns (in this case, the passed
658
+ * buffer could be freed after the call).
659
+ * Otherwise (if the flag is not set) - the buffer could only be
660
+ * freed after the engine stops (i.e. after call to jerry_cleanup). */
661
+ {
662
+ #ifdef JERRY_ENABLE_SNAPSHOT_EXEC
663
+ return jerry_exec_snapshot_at (snapshot_p , snapshot_size , 0 , copy_bytecode );
630
664
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
631
665
JERRY_UNUSED (snapshot_p );
632
666
JERRY_UNUSED (snapshot_size );
0 commit comments