@@ -130,6 +130,7 @@ pub struct TableType {
130
130
#[ derive( Debug , Copy , Clone ) ]
131
131
pub struct MemoryType {
132
132
pub limits : ResizableLimits ,
133
+ pub shared : bool ,
133
134
}
134
135
135
136
#[ derive( Debug , Copy , Clone ) ]
@@ -455,6 +456,11 @@ pub enum Operator<'a> {
455
456
I64ReinterpretF64 ,
456
457
F32ReinterpretI32 ,
457
458
F64ReinterpretI64 ,
459
+ I32Extend8S ,
460
+ I32Extend16S ,
461
+ I64Extend8S ,
462
+ I64Extend16S ,
463
+ I64Extend32S ,
458
464
459
465
// 0xFC operators
460
466
// Non-trapping Float-to-int Conversions
@@ -466,6 +472,75 @@ pub enum Operator<'a> {
466
472
I64TruncUSatF32 ,
467
473
I64TruncSSatF64 ,
468
474
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 } ,
469
544
}
470
545
471
546
fn is_name ( name : & [ u8 ] , expected : & ' static str ) -> bool {
@@ -681,35 +756,43 @@ impl<'a> BinaryReader<'a> {
681
756
} )
682
757
}
683
758
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 > {
692
760
let initial = self . read_var_u32 ( ) ?;
693
- let maximum = if ( flags & 0x1 ) != 0 {
761
+ let maximum = if max_present {
694
762
Some ( self . read_var_u32 ( ) ?)
695
763
} else {
696
764
None
697
765
} ;
698
- Ok ( ResizableLimits {
699
- initial : initial,
700
- maximum : maximum,
701
- } )
766
+ Ok ( ResizableLimits { initial, maximum } )
702
767
}
703
768
704
769
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 ) ?;
705
779
Ok ( TableType {
706
- element_type : self . read_type ( ) ? ,
707
- limits : self . read_resizable_limits ( ) ? ,
780
+ element_type,
781
+ limits,
708
782
} )
709
783
}
710
784
711
785
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 } )
713
796
}
714
797
715
798
fn read_global_type ( & mut self ) -> Result < GlobalType > {
@@ -961,6 +1044,96 @@ impl<'a> BinaryReader<'a> {
961
1044
self . read_bytes ( len)
962
1045
}
963
1046
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
+
964
1137
pub fn read_operator ( & mut self ) -> Result < Operator < ' a > > {
965
1138
let code = self . read_u8 ( ) ? as u8 ;
966
1139
Ok ( match code {
@@ -1142,8 +1315,16 @@ impl<'a> BinaryReader<'a> {
1142
1315
0xbe => Operator :: F32ReinterpretI32 ,
1143
1316
0xbf => Operator :: F64ReinterpretI64 ,
1144
1317
1318
+ 0xc0 => Operator :: I32Extend8S ,
1319
+ 0xc1 => Operator :: I32Extend16S ,
1320
+ 0xc2 => Operator :: I64Extend8S ,
1321
+ 0xc3 => Operator :: I64Extend16S ,
1322
+ 0xc4 => Operator :: I64Extend32S ,
1323
+
1145
1324
0xfc => self . read_0xfc_operator ( ) ?,
1146
1325
1326
+ 0xfe => self . read_0xfe_operator ( ) ?,
1327
+
1147
1328
_ => {
1148
1329
return Err ( BinaryReaderError {
1149
1330
message : "Unknown opcode" ,
0 commit comments