@@ -116,7 +116,7 @@ impl LocalInits {
116116 self . local_inits . resize ( new_len, is_defaultable) ;
117117 }
118118
119- /// Returns `true` if the local at `local_index` has already been initialized.
119+ /// Returns `true` if the local at `local_index` has not been initialized.
120120 #[ inline]
121121 pub fn is_uninit ( & self , local_index : u32 ) -> bool {
122122 if local_index < self . first_non_default_local {
@@ -134,8 +134,8 @@ impl LocalInits {
134134 }
135135 }
136136
137- /// Registers a new control frame and returns its `height` .
138- pub fn push_ctrl ( & mut self ) -> usize {
137+ /// Returns the current `height` (number of local inits) .
138+ pub fn height ( & self ) -> usize {
139139 self . inits . len ( )
140140 }
141141
@@ -951,23 +951,29 @@ where
951951 /// breaks interact with this block's type. Additionally the type signature
952952 /// of the block is specified by `ty`.
953953 fn push_ctrl ( & mut self , kind : FrameKind , ty : BlockType ) -> Result < ( ) > {
954+ self . push_bare_ctrl ( kind, ty) ;
955+ // All of the parameters are now also available in this control frame,
956+ // so we push them here in order.
957+ for ty in self . params ( ty) ? {
958+ self . push_operand ( ty) ?;
959+ }
960+ Ok ( ( ) )
961+ }
962+
963+ /// Pushes a new frame onto the control stack, without its block params.
964+ /// This is used by `push_ctrl` above and directly by LegacyCatch and LegacyCatchAll.
965+ fn push_bare_ctrl ( & mut self , kind : FrameKind , ty : BlockType ) {
954966 // Push a new frame which has a snapshot of the height of the current
955967 // operand stack.
956968 let height = self . operands . len ( ) ;
957- let init_height = self . local_inits . push_ctrl ( ) ;
969+ let init_height = self . local_inits . height ( ) ;
958970 self . control . push ( Frame {
959971 kind,
960972 block_type : ty,
961973 height,
962974 unreachable : false ,
963975 init_height,
964976 } ) ;
965- // All of the parameters are now also available in this control frame,
966- // so we push them here in order.
967- for ty in self . params ( ty) ? {
968- self . push_operand ( ty) ?;
969- }
970- Ok ( ( ) )
971977 }
972978
973979 /// Pops a frame from the control stack.
@@ -1987,9 +1993,7 @@ where
19871993 }
19881994 fn visit_else ( & mut self ) -> Self :: Output {
19891995 let frame = self . pop_ctrl ( ) ?;
1990- if frame. kind != FrameKind :: If {
1991- bail ! ( self . offset, "else found outside of an `if` block" ) ;
1992- }
1996+ debug_assert_eq ! ( frame. kind, FrameKind :: If ) ; // syntactic requirement, enforced by reader
19931997 self . push_ctrl ( FrameKind :: Else , frame. block_type ) ?;
19941998 Ok ( ( ) )
19951999 }
@@ -4210,20 +4214,9 @@ where
42104214 }
42114215 fn visit_catch ( & mut self , index : u32 ) -> Self :: Output {
42124216 let frame = self . pop_ctrl ( ) ?;
4213- if frame. kind != FrameKind :: LegacyTry && frame. kind != FrameKind :: LegacyCatch {
4214- bail ! ( self . offset, "catch found outside of an `try` block" ) ;
4215- }
4216- // Start a new frame and push `exnref` value.
4217- let height = self . operands . len ( ) ;
4218- let init_height = self . local_inits . push_ctrl ( ) ;
4219- self . control . push ( Frame {
4220- kind : FrameKind :: LegacyCatch ,
4221- block_type : frame. block_type ,
4222- height,
4223- unreachable : false ,
4224- init_height,
4225- } ) ;
4226- // Push exception argument types.
4217+ debug_assert ! ( frame. kind == FrameKind :: LegacyTry || frame. kind == FrameKind :: LegacyCatch ) ;
4218+ // Start a new frame and push exception argument types.
4219+ self . push_bare_ctrl ( FrameKind :: LegacyCatch , frame. block_type ) ;
42274220 let ty = self . exception_tag_at ( index) ?;
42284221 for ty in ty. params ( ) {
42294222 self . push_operand ( * ty) ?;
@@ -4245,9 +4238,7 @@ where
42454238 }
42464239 fn visit_delegate ( & mut self , relative_depth : u32 ) -> Self :: Output {
42474240 let frame = self . pop_ctrl ( ) ?;
4248- if frame. kind != FrameKind :: LegacyTry {
4249- bail ! ( self . offset, "delegate found outside of an `try` block" ) ;
4250- }
4241+ debug_assert_eq ! ( frame. kind, FrameKind :: LegacyTry ) ;
42514242 // This operation is not a jump, but we need to check the
42524243 // depth for validity
42534244 let _ = self . jump ( relative_depth) ?;
@@ -4258,20 +4249,8 @@ where
42584249 }
42594250 fn visit_catch_all ( & mut self ) -> Self :: Output {
42604251 let frame = self . pop_ctrl ( ) ?;
4261- if frame. kind == FrameKind :: LegacyCatchAll {
4262- bail ! ( self . offset, "only one catch_all allowed per `try` block" ) ;
4263- } else if frame. kind != FrameKind :: LegacyTry && frame. kind != FrameKind :: LegacyCatch {
4264- bail ! ( self . offset, "catch_all found outside of a `try` block" ) ;
4265- }
4266- let height = self . operands . len ( ) ;
4267- let init_height = self . local_inits . push_ctrl ( ) ;
4268- self . control . push ( Frame {
4269- kind : FrameKind :: LegacyCatchAll ,
4270- block_type : frame. block_type ,
4271- height,
4272- unreachable : false ,
4273- init_height,
4274- } ) ;
4252+ debug_assert ! ( frame. kind == FrameKind :: LegacyTry || frame. kind == FrameKind :: LegacyCatch ) ;
4253+ self . push_bare_ctrl ( FrameKind :: LegacyCatchAll , frame. block_type ) ;
42754254 Ok ( ( ) )
42764255 }
42774256 fn visit_cont_new ( & mut self , type_index : u32 ) -> Self :: Output {
0 commit comments