@@ -130,6 +130,7 @@ pub struct TableType {
130130#[ derive( Debug , Copy , Clone ) ]
131131pub struct MemoryType {
132132 pub limits : ResizableLimits ,
133+ pub shared : bool ,
133134}
134135
135136#[ derive( Debug , Copy , Clone ) ]
@@ -455,6 +456,11 @@ pub enum Operator<'a> {
455456 I64ReinterpretF64 ,
456457 F32ReinterpretI32 ,
457458 F64ReinterpretI64 ,
459+ I32Extend8S ,
460+ I32Extend16S ,
461+ I64Extend8S ,
462+ I64Extend16S ,
463+ I64Extend32S ,
458464
459465 // 0xFC operators
460466 // Non-trapping Float-to-int Conversions
@@ -466,6 +472,75 @@ pub enum Operator<'a> {
466472 I64TruncUSatF32 ,
467473 I64TruncSSatF64 ,
468474 I64TruncUSatF64 ,
475+
476+ // 0xFE operators
477+ // https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md
478+ Wake { memarg : MemoryImmediate } ,
479+ I32Wait { memarg : MemoryImmediate } ,
480+ I64Wait { memarg : MemoryImmediate } ,
481+ I32AtomicLoad { memarg : MemoryImmediate } ,
482+ I64AtomicLoad { memarg : MemoryImmediate } ,
483+ I32AtomicLoad8U { memarg : MemoryImmediate } ,
484+ I32AtomicLoad16U { memarg : MemoryImmediate } ,
485+ I64AtomicLoad8U { memarg : MemoryImmediate } ,
486+ I64AtomicLoad16U { memarg : MemoryImmediate } ,
487+ I64AtomicLoad32U { memarg : MemoryImmediate } ,
488+ I32AtomicStore { memarg : MemoryImmediate } ,
489+ I64AtomicStore { memarg : MemoryImmediate } ,
490+ I32AtomicStore8 { memarg : MemoryImmediate } ,
491+ I32AtomicStore16 { memarg : MemoryImmediate } ,
492+ I64AtomicStore8 { memarg : MemoryImmediate } ,
493+ I64AtomicStore16 { memarg : MemoryImmediate } ,
494+ I64AtomicStore32 { memarg : MemoryImmediate } ,
495+ I32AtomicRmwAdd { memarg : MemoryImmediate } ,
496+ I64AtomicRmwAdd { memarg : MemoryImmediate } ,
497+ I32AtomicRmw8UAdd { memarg : MemoryImmediate } ,
498+ I32AtomicRmw16UAdd { memarg : MemoryImmediate } ,
499+ I64AtomicRmw8UAdd { memarg : MemoryImmediate } ,
500+ I64AtomicRmw16UAdd { memarg : MemoryImmediate } ,
501+ I64AtomicRmw32UAdd { memarg : MemoryImmediate } ,
502+ I32AtomicRmwSub { memarg : MemoryImmediate } ,
503+ I64AtomicRmwSub { memarg : MemoryImmediate } ,
504+ I32AtomicRmw8USub { memarg : MemoryImmediate } ,
505+ I32AtomicRmw16USub { memarg : MemoryImmediate } ,
506+ I64AtomicRmw8USub { memarg : MemoryImmediate } ,
507+ I64AtomicRmw16USub { memarg : MemoryImmediate } ,
508+ I64AtomicRmw32USub { memarg : MemoryImmediate } ,
509+ I32AtomicRmwAnd { memarg : MemoryImmediate } ,
510+ I64AtomicRmwAnd { memarg : MemoryImmediate } ,
511+ I32AtomicRmw8UAnd { memarg : MemoryImmediate } ,
512+ I32AtomicRmw16UAnd { memarg : MemoryImmediate } ,
513+ I64AtomicRmw8UAnd { memarg : MemoryImmediate } ,
514+ I64AtomicRmw16UAnd { memarg : MemoryImmediate } ,
515+ I64AtomicRmw32UAnd { memarg : MemoryImmediate } ,
516+ I32AtomicRmwOr { memarg : MemoryImmediate } ,
517+ I64AtomicRmwOr { memarg : MemoryImmediate } ,
518+ I32AtomicRmw8UOr { memarg : MemoryImmediate } ,
519+ I32AtomicRmw16UOr { memarg : MemoryImmediate } ,
520+ I64AtomicRmw8UOr { memarg : MemoryImmediate } ,
521+ I64AtomicRmw16UOr { memarg : MemoryImmediate } ,
522+ I64AtomicRmw32UOr { memarg : MemoryImmediate } ,
523+ I32AtomicRmwXor { memarg : MemoryImmediate } ,
524+ I64AtomicRmwXor { memarg : MemoryImmediate } ,
525+ I32AtomicRmw8UXor { memarg : MemoryImmediate } ,
526+ I32AtomicRmw16UXor { memarg : MemoryImmediate } ,
527+ I64AtomicRmw8UXor { memarg : MemoryImmediate } ,
528+ I64AtomicRmw16UXor { memarg : MemoryImmediate } ,
529+ I64AtomicRmw32UXor { memarg : MemoryImmediate } ,
530+ I32AtomicRmwXchg { memarg : MemoryImmediate } ,
531+ I64AtomicRmwXchg { memarg : MemoryImmediate } ,
532+ I32AtomicRmw8UXchg { memarg : MemoryImmediate } ,
533+ I32AtomicRmw16UXchg { memarg : MemoryImmediate } ,
534+ I64AtomicRmw8UXchg { memarg : MemoryImmediate } ,
535+ I64AtomicRmw16UXchg { memarg : MemoryImmediate } ,
536+ I64AtomicRmw32UXchg { memarg : MemoryImmediate } ,
537+ I32AtomicRmwCmpxchg { memarg : MemoryImmediate } ,
538+ I64AtomicRmwCmpxchg { memarg : MemoryImmediate } ,
539+ I32AtomicRmw8UCmpxchg { memarg : MemoryImmediate } ,
540+ I32AtomicRmw16UCmpxchg { memarg : MemoryImmediate } ,
541+ I64AtomicRmw8UCmpxchg { memarg : MemoryImmediate } ,
542+ I64AtomicRmw16UCmpxchg { memarg : MemoryImmediate } ,
543+ I64AtomicRmw32UCmpxchg { memarg : MemoryImmediate } ,
469544}
470545
471546fn is_name ( name : & [ u8 ] , expected : & ' static str ) -> bool {
@@ -681,35 +756,43 @@ impl<'a> BinaryReader<'a> {
681756 } )
682757 }
683758
684- fn read_resizable_limits ( & mut self ) -> Result < ResizableLimits > {
685- let flags = self . read_var_u32 ( ) ?;
686- if ( flags & !0x1 ) != 0 {
687- return Err ( BinaryReaderError {
688- message : "invalid resizable limits flags" ,
689- offset : self . position - 1 ,
690- } ) ;
691- }
759+ fn read_resizable_limits ( & mut self , max_present : bool ) -> Result < ResizableLimits > {
692760 let initial = self . read_var_u32 ( ) ?;
693- let maximum = if ( flags & 0x1 ) != 0 {
761+ let maximum = if max_present {
694762 Some ( self . read_var_u32 ( ) ?)
695763 } else {
696764 None
697765 } ;
698- Ok ( ResizableLimits {
699- initial : initial,
700- maximum : maximum,
701- } )
766+ Ok ( ResizableLimits { initial, maximum } )
702767 }
703768
704769 fn read_table_type ( & mut self ) -> Result < TableType > {
770+ let element_type = self . read_type ( ) ?;
771+ let flags = self . read_var_u32 ( ) ?;
772+ if ( flags & !0x1 ) != 0 {
773+ return Err ( BinaryReaderError {
774+ message : "invalid table resizable limits flags" ,
775+ offset : self . position - 1 ,
776+ } ) ;
777+ }
778+ let limits = self . read_resizable_limits ( ( flags & 0x1 ) != 0 ) ?;
705779 Ok ( TableType {
706- element_type : self . read_type ( ) ? ,
707- limits : self . read_resizable_limits ( ) ? ,
780+ element_type,
781+ limits,
708782 } )
709783 }
710784
711785 fn read_memory_type ( & mut self ) -> Result < MemoryType > {
712- Ok ( MemoryType { limits : self . read_resizable_limits ( ) ? } )
786+ let flags = self . read_var_u32 ( ) ?;
787+ if ( flags & !0x3 ) != 0 {
788+ return Err ( BinaryReaderError {
789+ message : "invalid table resizable limits flags" ,
790+ offset : self . position - 1 ,
791+ } ) ;
792+ }
793+ let limits = self . read_resizable_limits ( ( flags & 0x1 ) != 0 ) ?;
794+ let shared = ( flags & 0x2 ) != 0 ;
795+ Ok ( MemoryType { limits, shared } )
713796 }
714797
715798 fn read_global_type ( & mut self ) -> Result < GlobalType > {
@@ -961,6 +1044,96 @@ impl<'a> BinaryReader<'a> {
9611044 self . read_bytes ( len)
9621045 }
9631046
1047+ fn read_memarg_of_align ( & mut self , align : u32 ) -> Result < MemoryImmediate > {
1048+ let imm = self . read_memarg ( ) ?;
1049+ if align != imm. flags {
1050+ return Err ( BinaryReaderError {
1051+ message : "Unexpected memarg alignment" ,
1052+ offset : self . position - 1 ,
1053+ } ) ;
1054+ }
1055+ Ok ( imm)
1056+ }
1057+
1058+ fn read_0xfe_operator ( & mut self ) -> Result < Operator < ' a > > {
1059+ let code = self . read_u8 ( ) ? as u8 ;
1060+ Ok ( match code {
1061+ 0x00 => Operator :: Wake { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1062+ 0x01 => Operator :: I32Wait { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1063+ 0x02 => Operator :: I64Wait { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1064+ 0x10 => Operator :: I32AtomicLoad { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1065+ 0x11 => Operator :: I64AtomicLoad { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1066+ 0x12 => Operator :: I32AtomicLoad8U { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1067+ 0x13 => Operator :: I32AtomicLoad16U { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1068+ 0x14 => Operator :: I64AtomicLoad8U { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1069+ 0x15 => Operator :: I64AtomicLoad16U { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1070+ 0x16 => Operator :: I64AtomicLoad32U { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1071+ 0x17 => Operator :: I32AtomicStore { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1072+ 0x18 => Operator :: I64AtomicStore { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1073+ 0x19 => Operator :: I32AtomicStore8 { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1074+ 0x1a => Operator :: I32AtomicStore16 { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1075+ 0x1b => Operator :: I64AtomicStore8 { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1076+ 0x1c => Operator :: I64AtomicStore16 { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1077+ 0x1d => Operator :: I64AtomicStore32 { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1078+ 0x1e => Operator :: I32AtomicRmwAdd { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1079+ 0x1f => Operator :: I64AtomicRmwAdd { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1080+ 0x20 => Operator :: I32AtomicRmw8UAdd { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1081+ 0x21 => Operator :: I32AtomicRmw16UAdd { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1082+ 0x22 => Operator :: I64AtomicRmw8UAdd { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1083+ 0x23 => Operator :: I64AtomicRmw16UAdd { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1084+ 0x24 => Operator :: I64AtomicRmw32UAdd { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1085+ 0x25 => Operator :: I32AtomicRmwSub { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1086+ 0x26 => Operator :: I64AtomicRmwSub { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1087+ 0x27 => Operator :: I32AtomicRmw8USub { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1088+ 0x28 => Operator :: I32AtomicRmw16USub { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1089+ 0x29 => Operator :: I64AtomicRmw8USub { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1090+ 0x2a => Operator :: I64AtomicRmw16USub { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1091+ 0x2b => Operator :: I64AtomicRmw32USub { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1092+ 0x2c => Operator :: I32AtomicRmwAnd { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1093+ 0x2d => Operator :: I64AtomicRmwAnd { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1094+ 0x2e => Operator :: I32AtomicRmw8UAnd { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1095+ 0x2f => Operator :: I32AtomicRmw16UAnd { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1096+ 0x30 => Operator :: I64AtomicRmw8UAnd { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1097+ 0x31 => Operator :: I64AtomicRmw16UAnd { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1098+ 0x32 => Operator :: I64AtomicRmw32UAnd { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1099+ 0x33 => Operator :: I32AtomicRmwOr { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1100+ 0x34 => Operator :: I64AtomicRmwOr { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1101+ 0x35 => Operator :: I32AtomicRmw8UOr { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1102+ 0x36 => Operator :: I32AtomicRmw16UOr { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1103+ 0x37 => Operator :: I64AtomicRmw8UOr { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1104+ 0x38 => Operator :: I64AtomicRmw16UOr { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1105+ 0x39 => Operator :: I64AtomicRmw32UOr { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1106+ 0x3a => Operator :: I32AtomicRmwXor { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1107+ 0x3b => Operator :: I64AtomicRmwXor { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1108+ 0x3c => Operator :: I32AtomicRmw8UXor { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1109+ 0x3d => Operator :: I32AtomicRmw16UXor { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1110+ 0x3e => Operator :: I64AtomicRmw8UXor { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1111+ 0x3f => Operator :: I64AtomicRmw16UXor { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1112+ 0x40 => Operator :: I64AtomicRmw32UXor { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1113+ 0x41 => Operator :: I32AtomicRmwXchg { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1114+ 0x42 => Operator :: I64AtomicRmwXchg { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1115+ 0x43 => Operator :: I32AtomicRmw8UXchg { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1116+ 0x44 => Operator :: I32AtomicRmw16UXchg { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1117+ 0x45 => Operator :: I64AtomicRmw8UXchg { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1118+ 0x46 => Operator :: I64AtomicRmw16UXchg { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1119+ 0x47 => Operator :: I64AtomicRmw32UXchg { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1120+ 0x48 => Operator :: I32AtomicRmwCmpxchg { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1121+ 0x49 => Operator :: I64AtomicRmwCmpxchg { memarg : self . read_memarg_of_align ( 3 ) ? } ,
1122+ 0x4a => Operator :: I32AtomicRmw8UCmpxchg { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1123+ 0x4b => Operator :: I32AtomicRmw16UCmpxchg { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1124+ 0x4c => Operator :: I64AtomicRmw8UCmpxchg { memarg : self . read_memarg_of_align ( 0 ) ? } ,
1125+ 0x4d => Operator :: I64AtomicRmw16UCmpxchg { memarg : self . read_memarg_of_align ( 1 ) ? } ,
1126+ 0x4e => Operator :: I64AtomicRmw32UCmpxchg { memarg : self . read_memarg_of_align ( 2 ) ? } ,
1127+
1128+ _ => {
1129+ return Err ( BinaryReaderError {
1130+ message : "Unknown 0xFE opcode" ,
1131+ offset : self . position - 1 ,
1132+ } )
1133+ }
1134+ } )
1135+ }
1136+
9641137 pub fn read_operator ( & mut self ) -> Result < Operator < ' a > > {
9651138 let code = self . read_u8 ( ) ? as u8 ;
9661139 Ok ( match code {
@@ -1142,8 +1315,16 @@ impl<'a> BinaryReader<'a> {
11421315 0xbe => Operator :: F32ReinterpretI32 ,
11431316 0xbf => Operator :: F64ReinterpretI64 ,
11441317
1318+ 0xc0 => Operator :: I32Extend8S ,
1319+ 0xc1 => Operator :: I32Extend16S ,
1320+ 0xc2 => Operator :: I64Extend8S ,
1321+ 0xc3 => Operator :: I64Extend16S ,
1322+ 0xc4 => Operator :: I64Extend32S ,
1323+
11451324 0xfc => self . read_0xfc_operator ( ) ?,
11461325
1326+ 0xfe => self . read_0xfe_operator ( ) ?,
1327+
11471328 _ => {
11481329 return Err ( BinaryReaderError {
11491330 message : "Unknown opcode" ,
0 commit comments