@@ -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 ))
@@ -377,7 +382,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
377
382
jmem_stats_allocate_byte_code_bytes (code_size );
378
383
#endif /* JMEM_STATS */
379
384
380
- memcpy (bytecode_p , snapshot_data_p + offset , code_size );
385
+ memcpy (bytecode_p , base_addr_p + offset , code_size );
381
386
}
382
387
else
383
388
{
@@ -392,7 +397,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
392
397
jmem_stats_allocate_byte_code_bytes (total_size );
393
398
#endif /* JMEM_STATS */
394
399
395
- memcpy (bytecode_p , snapshot_data_p + offset , code_size );
400
+ memcpy (bytecode_p , base_addr_p + offset , code_size );
396
401
397
402
bytecode_p -> size = (uint16_t ) (total_size >> JMEM_ALIGNMENT_LOG );
398
403
@@ -412,17 +417,9 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
412
417
413
418
for (uint32_t i = 0 ; i < const_literal_end ; i ++ )
414
419
{
415
- lit_mem_to_snapshot_id_map_entry_t * current_p = lit_map_p ;
416
-
417
- if (literal_start_p [i ] != 0 )
418
- {
419
- while (current_p -> literal_offset != literal_start_p [i ])
420
- {
421
- current_p ++ ;
422
- }
423
-
424
- literal_start_p [i ] = current_p -> literal_id ;
425
- }
420
+ literal_start_p [i ] = ecma_snapshot_get_literal (literal_base_p ,
421
+ number_base_p ,
422
+ literal_start_p [i ]);
426
423
}
427
424
428
425
for (uint32_t i = const_literal_end ; i < literal_end ; i ++ )
@@ -438,9 +435,10 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
438
435
else
439
436
{
440
437
ecma_compiled_code_t * literal_bytecode_p ;
441
- literal_bytecode_p = snapshot_load_compiled_code (snapshot_data_p ,
438
+ literal_bytecode_p = snapshot_load_compiled_code (base_addr_p ,
442
439
literal_offset ,
443
- lit_map_p ,
440
+ literal_base_p ,
441
+ number_base_p ,
444
442
copy_bytecode );
445
443
446
444
ECMA_SET_NON_NULL_POINTER (literal_start_p [i ],
@@ -500,7 +498,13 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
500
498
jerry_snapshot_header_t header ;
501
499
header .version = JERRY_SNAPSHOT_VERSION ;
502
500
header .lit_table_offset = (uint32_t ) globals .snapshot_buffer_write_offset ;
503
- header .is_run_global = is_for_global ;
501
+ header .number_of_funcs = 1 ;
502
+ header .func_offsets [0 ] = sizeof (jerry_snapshot_header_t );
503
+
504
+ if (!is_for_global )
505
+ {
506
+ header .func_offsets [0 ] |= JERRY_SNAPSHOT_EVAL_CONTEXT ;
507
+ }
504
508
505
509
lit_mem_to_snapshot_id_map_entry_t * lit_map_p = NULL ;
506
510
uint32_t literals_num ;
@@ -509,8 +513,7 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
509
513
buffer_size ,
510
514
& globals .snapshot_buffer_write_offset ,
511
515
& lit_map_p ,
512
- & literals_num ,
513
- & header .lit_table_size ))
516
+ & literals_num ))
514
517
{
515
518
JERRY_ASSERT (lit_map_p == NULL );
516
519
return 0 ;
@@ -559,15 +562,16 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
559
562
* thrown error - otherwise
560
563
*/
561
564
jerry_value_t
562
- jerry_exec_snapshot (const uint32_t * snapshot_p , /**< snapshot */
563
- size_t snapshot_size , /**< size of snapshot */
564
- bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
565
- * buffer should be copied to the engine's memory.
566
- * If set the engine should not reference the buffer
567
- * after the function returns (in this case, the passed
568
- * buffer could be freed after the call).
569
- * Otherwise (if the flag is not set) - the buffer could only be
570
- * freed after the engine stops (i.e. after call to jerry_cleanup). */
565
+ jerry_exec_snapshot_at (const uint32_t * snapshot_p , /**< snapshot */
566
+ size_t snapshot_size , /**< size of snapshot */
567
+ size_t func_index , /**< index of primary function */
568
+ bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
569
+ * buffer should be copied to the engine's memory.
570
+ * If set the engine should not reference the buffer
571
+ * after the function returns (in this case, the passed
572
+ * buffer could be freed after the call).
573
+ * Otherwise (if the flag is not set) - the buffer could only be
574
+ * freed after the engine stops (i.e. after call to jerry_cleanup). */
571
575
{
572
576
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
573
577
JERRY_ASSERT (snapshot_p != NULL );
@@ -588,34 +592,32 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
588
592
return ecma_raise_type_error (invalid_version_error_p );
589
593
}
590
594
591
- lit_mem_to_snapshot_id_map_entry_t * lit_map_p = NULL ;
592
- uint32_t literals_num ;
593
-
594
595
if (header_p -> lit_table_offset >= snapshot_size )
595
596
{
596
597
return ecma_raise_type_error (invalid_version_error_p );
597
598
}
598
599
599
- JERRY_ASSERT ((header_p -> lit_table_offset % sizeof (uint32_t )) == 0 );
600
- if (!ecma_load_literals_from_snapshot ((uint32_t * ) (snapshot_data_p + header_p -> lit_table_offset ),
601
- header_p -> lit_table_size ,
602
- & lit_map_p ,
603
- & literals_num ))
600
+ if (func_index >= header_p -> number_of_funcs )
604
601
{
605
- JERRY_ASSERT (lit_map_p == NULL );
606
- return ecma_raise_type_error (invalid_format_error_p );
602
+ return ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum" ));
607
603
}
608
604
605
+ JERRY_ASSERT ((header_p -> lit_table_offset % sizeof (uint32_t )) == 0 );
606
+
607
+ const uint8_t * literal_base_p ;
608
+ const uint8_t * number_base_p ;
609
+
610
+ literal_base_p = ecma_snapshot_get_literals_base ((uint32_t * ) (snapshot_data_p + header_p -> lit_table_offset ),
611
+ & number_base_p );
612
+
609
613
ecma_compiled_code_t * bytecode_p ;
610
- bytecode_p = snapshot_load_compiled_code (snapshot_data_p ,
611
- sizeof (jerry_snapshot_header_t ),
612
- lit_map_p ,
613
- copy_bytecode );
614
614
615
- if (lit_map_p != NULL )
616
- {
617
- jmem_heap_free_block (lit_map_p , literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t ));
618
- }
615
+ uint32_t func_offset = header_p -> func_offsets [func_index ] & ~JERRY_SNAPSHOT_EVAL_CONTEXT ;
616
+ bytecode_p = snapshot_load_compiled_code (snapshot_data_p + func_offset ,
617
+ 0 ,
618
+ literal_base_p ,
619
+ number_base_p ,
620
+ copy_bytecode );
619
621
620
622
if (bytecode_p == NULL )
621
623
{
@@ -624,17 +626,49 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
624
626
625
627
ecma_value_t ret_val ;
626
628
627
- if (header_p -> is_run_global )
629
+ if (header_p -> func_offsets [ func_index ] & JERRY_SNAPSHOT_EVAL_CONTEXT )
628
630
{
629
- ret_val = vm_run_global (bytecode_p );
630
- ecma_bytecode_deref (bytecode_p );
631
+ ret_val = vm_run_eval (bytecode_p , false);
631
632
}
632
633
else
633
634
{
634
- ret_val = vm_run_eval (bytecode_p , false);
635
+ ret_val = vm_run_global (bytecode_p );
636
+ ecma_bytecode_deref (bytecode_p );
635
637
}
636
638
637
639
return ret_val ;
640
+ #else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
641
+ JERRY_UNUSED (snapshot_p );
642
+ JERRY_UNUSED (snapshot_size );
643
+ JERRY_UNUSED (func_index );
644
+ JERRY_UNUSED (copy_bytecode );
645
+
646
+ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE );
647
+ #endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
648
+ } /* jerry_exec_snapshot_at */
649
+
650
+ /**
651
+ * Execute snapshot from specified buffer
652
+ *
653
+ * Note:
654
+ * returned value must be freed with jerry_release_value, when it is no longer needed.
655
+ *
656
+ * @return result of bytecode - if run was successful
657
+ * thrown error - otherwise
658
+ */
659
+ jerry_value_t
660
+ jerry_exec_snapshot (const uint32_t * snapshot_p , /**< snapshot */
661
+ size_t snapshot_size , /**< size of snapshot */
662
+ bool copy_bytecode ) /**< flag, indicating whether the passed snapshot
663
+ * buffer should be copied to the engine's memory.
664
+ * If set the engine should not reference the buffer
665
+ * after the function returns (in this case, the passed
666
+ * buffer could be freed after the call).
667
+ * Otherwise (if the flag is not set) - the buffer could only be
668
+ * freed after the engine stops (i.e. after call to jerry_cleanup). */
669
+ {
670
+ #ifdef JERRY_ENABLE_SNAPSHOT_EXEC
671
+ return jerry_exec_snapshot_at (snapshot_p , snapshot_size , 0 , copy_bytecode );
638
672
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
639
673
JERRY_UNUSED (snapshot_p );
640
674
JERRY_UNUSED (snapshot_size );
0 commit comments