@@ -276,48 +276,6 @@ impl fmt::Display for ConvertValueOparg {
276276 }
277277}
278278
279- /// Resume type for the RESUME instruction
280- #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
281- pub enum ResumeType {
282- AtFuncStart ,
283- AfterYield ,
284- AfterYieldFrom ,
285- AfterAwait ,
286- Other ( u32 ) ,
287- }
288-
289- impl From < u32 > for ResumeType {
290- fn from ( value : u32 ) -> Self {
291- match value {
292- 0 => Self :: AtFuncStart ,
293- 5 => Self :: AfterYield ,
294- 2 => Self :: AfterYieldFrom ,
295- 3 => Self :: AfterAwait ,
296- _ => Self :: Other ( value) ,
297- }
298- }
299- }
300-
301- impl From < ResumeType > for u32 {
302- fn from ( typ : ResumeType ) -> Self {
303- match typ {
304- ResumeType :: AtFuncStart => 0 ,
305- ResumeType :: AfterYield => 5 ,
306- ResumeType :: AfterYieldFrom => 2 ,
307- ResumeType :: AfterAwait => 3 ,
308- ResumeType :: Other ( v) => v,
309- }
310- }
311- }
312-
313- impl core:: fmt:: Display for ResumeType {
314- fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
315- u32:: from ( * self ) . fmt ( f)
316- }
317- }
318-
319- impl OpArgType for ResumeType { }
320-
321279pub type NameIdx = u32 ;
322280
323281impl OpArgType for u32 { }
@@ -756,14 +714,8 @@ macro_rules! newtype_oparg {
756714 impl $name {
757715 /// Creates a new [`$name`] instance.
758716 #[ must_use]
759- pub const fn new( value: u32 ) -> Self {
760- Self ( value)
761- }
762-
763- /// Alias to [`$name::new`].
764- #[ must_use]
765717 pub const fn from_u32( value: u32 ) -> Self {
766- Self :: new ( value)
718+ Self ( value)
767719 }
768720
769721 /// Returns the oparg as a `u32` value.
@@ -843,15 +795,119 @@ newtype_oparg!(
843795 pub struct Label ( u32 )
844796) ;
845797
798+ newtype_oparg ! (
799+ /// Context for [`Instruction::Resume`].
800+ ///
801+ /// The oparg consists of two parts:
802+ /// 1. [`ResumeContext::location`]: Indicates where the instruction occurs.
803+ /// 2. [`ResumeContext::is_exception_depth1`]: Is the instruction is at except-depth 1.
804+ #[ derive( Clone , Copy ) ]
805+ #[ repr( transparent) ]
806+ pub struct ResumeContext ( u32 )
807+ ) ;
808+
809+ impl ResumeContext {
810+ /// [CPython `RESUME_OPARG_LOCATION_MASK`](https://github.com/python/cpython/blob/v3.14.3/Include/internal/pycore_opcode_utils.h#L84)
811+ pub const LOCATION_MASK : u32 = 0x3 ;
812+
813+ /// [CPython `RESUME_OPARG_DEPTH1_MASK`](https://github.com/python/cpython/blob/v3.14.3/Include/internal/pycore_opcode_utils.h#L85)
814+ pub const DEPTH1_MASK : u32 = 0x4 ;
815+
816+ #[ must_use]
817+ pub const fn new ( location : ResumeLocation , is_exception_depth1 : bool ) -> Self {
818+ let value = if is_exception_depth1 {
819+ Self :: DEPTH1_MASK
820+ } else {
821+ 0
822+ } ;
823+
824+ Self :: from_u32 ( location. as_u32 ( ) | value)
825+ }
826+
827+ /// Resume location is determined by [`Self::LOCATION_MASK`].
828+ #[ must_use]
829+ pub fn location ( & self ) -> ResumeLocation {
830+ // SAFETY: The mask should return a value that is in range.
831+ unsafe { ResumeLocation :: try_from ( self . as_u32 ( ) & Self :: LOCATION_MASK ) . unwrap_unchecked ( ) }
832+ }
833+
834+ /// True if the bit at [`Self::DEPTH1_MASK`] is on.
835+ #[ must_use]
836+ pub const fn is_exception_depth1 ( & self ) -> bool {
837+ ( self . as_u32 ( ) & Self :: DEPTH1_MASK ) != 0
838+ }
839+ }
840+
841+ #[ derive( Copy , Clone ) ]
842+ pub enum ResumeLocation {
843+ /// At the start of a function, which is neither a generator, coroutine nor an async generator.
844+ AtFuncStart ,
845+ /// After a `yield` expression.
846+ AfterYield ,
847+ /// After a `yield from` expression.
848+ AfterYieldFrom ,
849+ /// After an `await` expression.
850+ AfterAwait ,
851+ }
852+
853+ impl From < ResumeLocation > for ResumeContext {
854+ fn from ( location : ResumeLocation ) -> Self {
855+ Self :: new ( location, false )
856+ }
857+ }
858+
859+ impl TryFrom < u32 > for ResumeLocation {
860+ type Error = MarshalError ;
861+
862+ fn try_from ( value : u32 ) -> Result < Self , Self :: Error > {
863+ Ok ( match value {
864+ 0 => Self :: AtFuncStart ,
865+ 1 => Self :: AfterYield ,
866+ 2 => Self :: AfterYieldFrom ,
867+ 3 => Self :: AfterAwait ,
868+ _ => return Err ( Self :: Error :: InvalidBytecode ) ,
869+ } )
870+ }
871+ }
872+
873+ impl ResumeLocation {
874+ #[ must_use]
875+ pub const fn as_u8 ( & self ) -> u8 {
876+ match self {
877+ Self :: AtFuncStart => 0 ,
878+ Self :: AfterYield => 1 ,
879+ Self :: AfterYieldFrom => 2 ,
880+ Self :: AfterAwait => 3 ,
881+ }
882+ }
883+
884+ #[ must_use]
885+ pub const fn as_u32 ( & self ) -> u32 {
886+ self . as_u8 ( ) as u32
887+ }
888+ }
889+
890+ impl From < ResumeLocation > for u8 {
891+ fn from ( location : ResumeLocation ) -> Self {
892+ location. as_u8 ( )
893+ }
894+ }
895+
896+ impl From < ResumeLocation > for u32 {
897+ fn from ( location : ResumeLocation ) -> Self {
898+ location. as_u32 ( )
899+ }
900+ }
901+
846902impl VarNums {
847903 #[ must_use]
848904 pub const fn idx_1 ( self ) -> VarNum {
849- VarNum :: new ( self . 0 >> 4 )
905+ VarNum :: from_u32 ( self . 0 >> 4 )
850906 }
851907
852908 #[ must_use]
853909 pub const fn idx_2 ( self ) -> VarNum {
854- VarNum :: new ( self . 0 & 15 )
910+ VarNum :: from_u32 ( self . 0 & 15 )
855911 }
856912
857913 #[ must_use]
@@ -887,7 +943,7 @@ impl LoadAttrBuilder {
887943 #[ must_use]
888944 pub const fn build ( self ) -> LoadAttr {
889945 let value = ( self . name_idx << 1 ) | ( self . is_method as u32 ) ;
890- LoadAttr :: new ( value)
946+ LoadAttr :: from_u32 ( value)
891947 }
892948
893949 #[ must_use]
@@ -937,7 +993,7 @@ impl LoadSuperAttrBuilder {
937993 pub const fn build ( self ) -> LoadSuperAttr {
938994 let value =
939995 ( self . name_idx << 2 ) | ( ( self . has_class as u32 ) << 1 ) | ( self . is_load_method as u32 ) ;
940- LoadSuperAttr :: new ( value)
996+ LoadSuperAttr :: from_u32 ( value)
941997 }
942998
943999 #[ must_use]
0 commit comments