@@ -8,9 +8,9 @@ use crate::ir::instructions::{CallInfo, InstructionData};
8
8
use crate :: ir:: pcc:: Fact ;
9
9
use crate :: ir:: user_stack_maps:: { UserStackMapEntry , UserStackMapEntryVec } ;
10
10
use crate :: ir:: {
11
- types, Block , BlockCall , ConstantData , ConstantPool , DynamicType , ExtFuncData , FuncRef ,
12
- Immediate , Inst , JumpTables , RelSourceLoc , SigRef , Signature , Type , Value ,
13
- ValueLabelAssignments , ValueList , ValueListPool ,
11
+ types, Block , BlockArg , BlockCall , ConstantData , ConstantPool , DynamicType , ExceptionTables ,
12
+ ExtFuncData , FuncRef , Immediate , Inst , JumpTables , RelSourceLoc , SigRef , Signature , Type ,
13
+ Value , ValueLabelAssignments , ValueList , ValueListPool ,
14
14
} ;
15
15
use crate :: packed_option:: ReservedValue ;
16
16
use crate :: write:: write_operands;
@@ -158,6 +158,9 @@ pub struct DataFlowGraph {
158
158
159
159
/// Jump tables used in this function.
160
160
pub jump_tables : JumpTables ,
161
+
162
+ /// Exception tables used in this function.
163
+ pub exception_tables : ExceptionTables ,
161
164
}
162
165
163
166
impl DataFlowGraph {
@@ -178,6 +181,7 @@ impl DataFlowGraph {
178
181
constants : ConstantPool :: new ( ) ,
179
182
immediates : PrimaryMap :: new ( ) ,
180
183
jump_tables : JumpTables :: new ( ) ,
184
+ exception_tables : ExceptionTables :: new ( ) ,
181
185
}
182
186
}
183
187
@@ -226,8 +230,12 @@ impl DataFlowGraph {
226
230
}
227
231
228
232
/// Make a BlockCall, bundling together the block and its arguments.
229
- pub fn block_call ( & mut self , block : Block , args : & [ Value ] ) -> BlockCall {
230
- BlockCall :: new ( block, args, & mut self . value_lists )
233
+ pub fn block_call < ' a > (
234
+ & mut self ,
235
+ block : Block ,
236
+ args : impl IntoIterator < Item = & ' a BlockArg > ,
237
+ ) -> BlockCall {
238
+ BlockCall :: new ( block, args. into_iter ( ) . copied ( ) , & mut self . value_lists )
231
239
}
232
240
233
241
/// Get the total number of values.
@@ -437,13 +445,18 @@ impl DataFlowGraph {
437
445
438
446
// Rewrite InstructionData in `self.insts`.
439
447
for inst in self . insts . 0 . values_mut ( ) {
440
- inst. map_values ( & mut self . value_lists , & mut self . jump_tables , |arg| {
441
- if let ValueData :: Alias { original, .. } = self . values [ arg] . into ( ) {
442
- original
443
- } else {
444
- arg
445
- }
446
- } ) ;
448
+ inst. map_values (
449
+ & mut self . value_lists ,
450
+ & mut self . jump_tables ,
451
+ & mut self . exception_tables ,
452
+ |arg| {
453
+ if let ValueData :: Alias { original, .. } = self . values [ arg] . into ( ) {
454
+ original
455
+ } else {
456
+ arg
457
+ }
458
+ } ,
459
+ ) ;
447
460
}
448
461
449
462
// - `results` and block-params in `blocks` are not aliases, by
@@ -843,23 +856,29 @@ impl DataFlowGraph {
843
856
& ' dfg self ,
844
857
inst : Inst ,
845
858
) -> impl DoubleEndedIterator < Item = Value > + ' dfg {
846
- self . inst_args ( inst)
847
- . iter ( )
848
- . chain (
849
- self . insts [ inst]
850
- . branch_destination ( & self . jump_tables )
851
- . into_iter ( )
852
- . flat_map ( |branch| branch. args_slice ( & self . value_lists ) . iter ( ) ) ,
853
- )
854
- . copied ( )
859
+ self . inst_args ( inst) . iter ( ) . copied ( ) . chain (
860
+ self . insts [ inst]
861
+ . branch_destination ( & self . jump_tables , & self . exception_tables )
862
+ . into_iter ( )
863
+ . flat_map ( |branch| {
864
+ branch
865
+ . args ( & self . value_lists )
866
+ . filter_map ( |arg| arg. as_value ( ) )
867
+ } ) ,
868
+ )
855
869
}
856
870
857
871
/// Map a function over the values of the instruction.
858
872
pub fn map_inst_values < F > ( & mut self , inst : Inst , body : F )
859
873
where
860
874
F : FnMut ( Value ) -> Value ,
861
875
{
862
- self . insts [ inst] . map_values ( & mut self . value_lists , & mut self . jump_tables , body) ;
876
+ self . insts [ inst] . map_values (
877
+ & mut self . value_lists ,
878
+ & mut self . jump_tables ,
879
+ & mut self . exception_tables ,
880
+ body,
881
+ ) ;
863
882
}
864
883
865
884
/// Overwrite the instruction's value references with values from the iterator.
@@ -869,9 +888,12 @@ impl DataFlowGraph {
869
888
where
870
889
I : Iterator < Item = Value > ,
871
890
{
872
- self . insts [ inst] . map_values ( & mut self . value_lists , & mut self . jump_tables , |_| {
873
- values. next ( ) . unwrap ( )
874
- } ) ;
891
+ self . insts [ inst] . map_values (
892
+ & mut self . value_lists ,
893
+ & mut self . jump_tables ,
894
+ & mut self . exception_tables ,
895
+ |_| values. next ( ) . unwrap ( ) ,
896
+ ) ;
875
897
}
876
898
877
899
/// Get all value arguments on `inst` as a slice.
@@ -1078,26 +1100,30 @@ impl DataFlowGraph {
1078
1100
/// Get the call signature of a direct or indirect call instruction.
1079
1101
/// Returns `None` if `inst` is not a call instruction.
1080
1102
pub fn call_signature ( & self , inst : Inst ) -> Option < SigRef > {
1081
- match self . insts [ inst] . analyze_call ( & self . value_lists ) {
1103
+ match self . insts [ inst] . analyze_call ( & self . value_lists , & self . exception_tables ) {
1082
1104
CallInfo :: NotACall => None ,
1083
1105
CallInfo :: Direct ( f, _) => Some ( self . ext_funcs [ f] . signature ) ,
1106
+ CallInfo :: DirectWithSig ( _, s, _) => Some ( s) ,
1084
1107
CallInfo :: Indirect ( s, _) => Some ( s) ,
1085
1108
}
1086
1109
}
1087
1110
1088
- /// Like `call_signature` but returns none for tail call instructions.
1089
- fn non_tail_call_signature ( & self , inst : Inst ) -> Option < SigRef > {
1111
+ /// Like `call_signature` but returns none for tail call
1112
+ /// instructions and try-call (exception-handling invoke)
1113
+ /// instructions.
1114
+ fn non_tail_call_or_try_call_signature ( & self , inst : Inst ) -> Option < SigRef > {
1090
1115
let sig = self . call_signature ( inst) ?;
1091
1116
match self . insts [ inst] . opcode ( ) {
1092
1117
ir:: Opcode :: ReturnCall | ir:: Opcode :: ReturnCallIndirect => None ,
1118
+ ir:: Opcode :: TryCall | ir:: Opcode :: TryCallIndirect => None ,
1093
1119
_ => Some ( sig) ,
1094
1120
}
1095
1121
}
1096
1122
1097
1123
// Only for use by the verifier. Everyone else should just use
1098
1124
// `dfg.inst_results(inst).len()`.
1099
1125
pub ( crate ) fn num_expected_results_for_verifier ( & self , inst : Inst ) -> usize {
1100
- match self . non_tail_call_signature ( inst) {
1126
+ match self . non_tail_call_or_try_call_signature ( inst) {
1101
1127
Some ( sig) => self . signatures [ sig] . returns . len ( ) ,
1102
1128
None => {
1103
1129
let constraints = self . insts [ inst] . opcode ( ) . constraints ( ) ;
@@ -1112,7 +1138,7 @@ impl DataFlowGraph {
1112
1138
inst : Inst ,
1113
1139
ctrl_typevar : Type ,
1114
1140
) -> impl iter:: ExactSizeIterator < Item = Type > + ' a {
1115
- return match self . non_tail_call_signature ( inst) {
1141
+ return match self . non_tail_call_or_try_call_signature ( inst) {
1116
1142
Some ( sig) => InstResultTypes :: Signature ( self , sig, 0 ) ,
1117
1143
None => {
1118
1144
let constraints = self . insts [ inst] . opcode ( ) . constraints ( ) ;
0 commit comments