43
43
#define LITT_UNCOMPRESSED_SIZE_OFFSET 8
44
44
#define LITT_HEADER_SIZE 12
45
45
46
- // TODO Constants similar to these are defined in opcodesswitch.h and should
47
- // be refactored so they can be used here, as well.
48
- #define TAG_COMPACT_INT 0x01
49
- #define TAG_COMPACT_ATOM 0x02
50
- #define TAG_EXTENDED_INT 0x09
51
- #define TAG_EXTENDED_ATOM 0x0A
52
-
53
46
#define CHECK_FREE_SPACE (space , error ) \
54
47
if ((size_t) ((pos + space) - data) > len) { \
55
48
fprintf(stderr, error); \
@@ -471,22 +464,39 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
471
464
}
472
465
uint8_t tag = * pos ;
473
466
switch (tag & 0x0F ) {
474
- case TAG_COMPACT_INT : {
467
+ case COMPACT_INTEGER : {
475
468
++ i ;
476
469
++ pos ;
477
470
break ;
478
471
}
479
- case TAG_EXTENDED_INT : {
472
+ case COMPACT_LARGE_INTEGER : {
480
473
++ pos ;
474
+ switch (tag & COMPACT_LARGE_IMM_MASK ) {
475
+ case COMPACT_11BITS_VALUE : {
476
+ ++ pos ;
477
+ break ;
478
+ }
479
+ case COMPACT_NBITS_VALUE : {
480
+ int sz = (tag >> 5 ) + 2 ;
481
+ if (UNLIKELY (sz > 4 )) {
482
+ fprintf (stderr , "Invalid line_ref: expected extended int with sz <= 4 (line number <= 2^31)" );
483
+ return false;
484
+ }
485
+ pos += sz ;
486
+ break ;
487
+ }
488
+ default :
489
+ fprintf (stderr , "Invalid line_ref: expected extended int -- tag = %u" , (unsigned int ) tag );
490
+ return false;
491
+ }
481
492
if ((size_t ) (pos - * data ) > len ) {
482
493
fprintf (stderr , "Invalid line_ref: expected extended int.\n" );
483
494
return false;
484
495
}
485
496
++ i ;
486
- ++ pos ;
487
497
break ;
488
498
}
489
- case TAG_COMPACT_ATOM : {
499
+ case COMPACT_ATOM : {
490
500
uint16_t location_ix = ((tag & 0xF0 ) >> 4 );
491
501
if (location_ix > mod -> locations_count ) {
492
502
fprintf (stderr , "Invalid line_ref: location_ix = %d is greater than locations_count = %d.\n" , (int ) location_ix , (int ) mod -> locations_count );
@@ -495,11 +505,16 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
495
505
++ pos ;
496
506
break ;
497
507
}
498
- case TAG_EXTENDED_ATOM : {
508
+ case COMPACT_LARGE_ATOM : {
509
+ // We don't support more than 11bits (2048) locations.
510
+ if (UNLIKELY ((tag & COMPACT_LARGE_IMM_MASK ) != COMPACT_11BITS_VALUE )) {
511
+ fprintf (stderr , "Invalid line_ref: location_ix is larger than 2048.\n" );
512
+ return false;
513
+ }
499
514
uint16_t high_order_3_bits = (tag & 0xE0 );
500
515
++ pos ;
501
516
if ((size_t ) (pos - * data ) > len ) {
502
- fprintf (stderr , "Invalid line_ref: expected extended int .\n" );
517
+ fprintf (stderr , "Invalid line_ref: expected extended atom .\n" );
503
518
return false;
504
519
}
505
520
uint8_t next_byte = * pos ;
@@ -512,7 +527,6 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
512
527
break ;
513
528
}
514
529
default :
515
- // TODO handle integer compact encodings > 2048
516
530
fprintf (stderr , "Unsupported line_ref tag: %u\n" , tag );
517
531
return false;
518
532
}
@@ -542,7 +556,7 @@ static bool module_check_locations(Module *mod, const uint8_t *data, size_t len)
542
556
return true;
543
557
}
544
558
545
- static bool module_get_line_ref (Module * mod , uint16_t line_ref , uint16_t * out_line , uint16_t * out_location )
559
+ static bool module_get_line_ref (Module * mod , uint16_t line_ref , uint32_t * out_line , uint16_t * out_location )
546
560
{
547
561
// First is undefined
548
562
if (line_ref == 0 ) {
@@ -557,9 +571,9 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
557
571
while (i <= mod -> line_refs_count ) {
558
572
uint8_t tag = * pos ;
559
573
switch (tag & 0x0F ) {
560
- case TAG_COMPACT_INT : {
574
+ case COMPACT_INTEGER : {
561
575
if (i == line_ref ) {
562
- uint16_t line_idx = ((tag & 0xF0 ) >> 4 );
576
+ uint32_t line_idx = ((tag & 0xF0 ) >> 4 );
563
577
* out_line = line_idx ;
564
578
* out_location = location_ix ;
565
579
return true;
@@ -568,32 +582,49 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
568
582
++ pos ;
569
583
break ;
570
584
}
571
- case TAG_EXTENDED_INT : {
585
+ case COMPACT_LARGE_INTEGER : {
586
+ uint32_t line_idx ;
587
+ switch (tag & COMPACT_LARGE_IMM_MASK ) {
588
+ case COMPACT_11BITS_VALUE : {
589
+ uint16_t high_order_3_bits = (tag & 0xE0 );
590
+ line_idx = ((high_order_3_bits << 3 ) | pos [1 ]);
591
+ pos += 2 ;
592
+ break ;
593
+ }
594
+ case COMPACT_NBITS_VALUE : {
595
+ pos ++ ;
596
+ int sz = (tag >> 5 ) + 2 ;
597
+ line_idx = 0 ;
598
+ for (int i = 0 ; i < sz ; i ++ ) {
599
+ line_idx = line_idx * 256 + pos [i ];
600
+ }
601
+ pos += sz ;
602
+ break ;
603
+ }
604
+ default :
605
+ UNREACHABLE ();
606
+ }
572
607
if (i == line_ref ) {
573
- uint16_t high_order_3_bits = (tag & 0xE0 );
574
- uint16_t line_idx = ((high_order_3_bits << 3 ) | pos [1 ]);
575
608
* out_line = line_idx ;
576
609
* out_location = location_ix ;
577
610
return true;
578
611
}
579
- pos += 2 ;
580
612
++ i ;
581
613
break ;
582
614
}
583
- case TAG_COMPACT_ATOM : {
615
+ case COMPACT_ATOM : {
584
616
location_ix = ((tag & 0xF0 ) >> 4 );
585
617
++ pos ;
586
618
break ;
587
619
}
588
- case TAG_EXTENDED_ATOM : {
620
+ case COMPACT_LARGE_ATOM : {
589
621
uint16_t high_order_3_bits = (tag & 0xE0 );
590
622
location_ix = ((high_order_3_bits << 3 ) | pos [1 ]);
591
623
pos += 2 ;
592
624
break ;
593
625
}
594
626
default :
595
- // TODO handle integer compact encodings > 2048
596
- return false;
627
+ UNREACHABLE ();
597
628
}
598
629
}
599
630
@@ -702,7 +733,7 @@ void module_insert_line_ref_offset(Module *mod, int line_ref, int offset)
702
733
list_append (& mod -> line_ref_offsets , & ref_offset -> head );
703
734
}
704
735
705
- static bool module_find_line_ref (Module * mod , uint16_t line_ref , uint16_t * line , size_t * filename_len , const uint8_t * * filename )
736
+ static bool module_find_line_ref (Module * mod , uint16_t line_ref , uint32_t * line , size_t * filename_len , const uint8_t * * filename )
706
737
{
707
738
uint16_t location_ix ;
708
739
if (UNLIKELY (!module_get_line_ref (mod , line_ref , line , & location_ix ))) {
@@ -711,7 +742,7 @@ static bool module_find_line_ref(Module *mod, uint16_t line_ref, uint16_t *line,
711
742
return module_get_location (mod , location_ix , filename_len , filename );
712
743
}
713
744
714
- bool module_find_line (Module * mod , unsigned int offset , uint16_t * line , size_t * filename_len , const uint8_t * * filename )
745
+ bool module_find_line (Module * mod , unsigned int offset , uint32_t * line , size_t * filename_len , const uint8_t * * filename )
715
746
{
716
747
int i = 0 ;
717
748
struct LineRefOffset * head = GET_LIST_ENTRY (& mod -> line_ref_offsets , struct LineRefOffset , head );
0 commit comments