4343#define LITT_UNCOMPRESSED_SIZE_OFFSET 8
4444#define LITT_HEADER_SIZE 12
4545
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-
5346#define CHECK_FREE_SPACE (space , error ) \
5447 if ((size_t) ((pos + space) - data) > len) { \
5548 fprintf(stderr, error); \
@@ -471,22 +464,39 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
471464 }
472465 uint8_t tag = * pos ;
473466 switch (tag & 0x0F ) {
474- case TAG_COMPACT_INT : {
467+ case COMPACT_INTEGER : {
475468 ++ i ;
476469 ++ pos ;
477470 break ;
478471 }
479- case TAG_EXTENDED_INT : {
472+ case COMPACT_LARGE_INTEGER : {
480473 ++ 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+ }
481492 if ((size_t ) (pos - * data ) > len ) {
482493 fprintf (stderr , "Invalid line_ref: expected extended int.\n" );
483494 return false;
484495 }
485496 ++ i ;
486- ++ pos ;
487497 break ;
488498 }
489- case TAG_COMPACT_ATOM : {
499+ case COMPACT_ATOM : {
490500 uint16_t location_ix = ((tag & 0xF0 ) >> 4 );
491501 if (location_ix > mod -> locations_count ) {
492502 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
495505 ++ pos ;
496506 break ;
497507 }
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+ }
499514 uint16_t high_order_3_bits = (tag & 0xE0 );
500515 ++ pos ;
501516 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" );
503518 return false;
504519 }
505520 uint8_t next_byte = * pos ;
@@ -512,7 +527,6 @@ static bool module_check_line_refs(Module *mod, const uint8_t **data, size_t len
512527 break ;
513528 }
514529 default :
515- // TODO handle integer compact encodings > 2048
516530 fprintf (stderr , "Unsupported line_ref tag: %u\n" , tag );
517531 return false;
518532 }
@@ -542,7 +556,7 @@ static bool module_check_locations(Module *mod, const uint8_t *data, size_t len)
542556 return true;
543557}
544558
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 )
546560{
547561 // First is undefined
548562 if (line_ref == 0 ) {
@@ -557,9 +571,9 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
557571 while (i <= mod -> line_refs_count ) {
558572 uint8_t tag = * pos ;
559573 switch (tag & 0x0F ) {
560- case TAG_COMPACT_INT : {
574+ case COMPACT_INTEGER : {
561575 if (i == line_ref ) {
562- uint16_t line_idx = ((tag & 0xF0 ) >> 4 );
576+ uint32_t line_idx = ((tag & 0xF0 ) >> 4 );
563577 * out_line = line_idx ;
564578 * out_location = location_ix ;
565579 return true;
@@ -568,32 +582,49 @@ static bool module_get_line_ref(Module *mod, uint16_t line_ref, uint16_t *out_li
568582 ++ pos ;
569583 break ;
570584 }
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+ }
572607 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 ]);
575608 * out_line = line_idx ;
576609 * out_location = location_ix ;
577610 return true;
578611 }
579- pos += 2 ;
580612 ++ i ;
581613 break ;
582614 }
583- case TAG_COMPACT_ATOM : {
615+ case COMPACT_ATOM : {
584616 location_ix = ((tag & 0xF0 ) >> 4 );
585617 ++ pos ;
586618 break ;
587619 }
588- case TAG_EXTENDED_ATOM : {
620+ case COMPACT_LARGE_ATOM : {
589621 uint16_t high_order_3_bits = (tag & 0xE0 );
590622 location_ix = ((high_order_3_bits << 3 ) | pos [1 ]);
591623 pos += 2 ;
592624 break ;
593625 }
594626 default :
595- // TODO handle integer compact encodings > 2048
596- return false;
627+ UNREACHABLE ();
597628 }
598629 }
599630
@@ -702,7 +733,7 @@ void module_insert_line_ref_offset(Module *mod, int line_ref, int offset)
702733 list_append (& mod -> line_ref_offsets , & ref_offset -> head );
703734}
704735
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 )
706737{
707738 uint16_t location_ix ;
708739 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,
711742 return module_get_location (mod , location_ix , filename_len , filename );
712743}
713744
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 )
715746{
716747 int i = 0 ;
717748 struct LineRefOffset * head = GET_LIST_ENTRY (& mod -> line_ref_offsets , struct LineRefOffset , head );
0 commit comments