@@ -512,6 +512,119 @@ impl Instruction {
512512 } )
513513 }
514514
515+ /// Map a specialized opcode back to its adaptive (base) variant.
516+ /// `_PyOpcode_Deopt`
517+ pub fn deoptimize ( self ) -> Self {
518+ match self {
519+ // LOAD_ATTR specializations
520+ Self :: LoadAttrClass
521+ | Self :: LoadAttrClassWithMetaclassCheck
522+ | Self :: LoadAttrGetattributeOverridden
523+ | Self :: LoadAttrInstanceValue
524+ | Self :: LoadAttrMethodLazyDict
525+ | Self :: LoadAttrMethodNoDict
526+ | Self :: LoadAttrMethodWithValues
527+ | Self :: LoadAttrModule
528+ | Self :: LoadAttrNondescriptorNoDict
529+ | Self :: LoadAttrNondescriptorWithValues
530+ | Self :: LoadAttrProperty
531+ | Self :: LoadAttrSlot
532+ | Self :: LoadAttrWithHint => Self :: LoadAttr { idx : Arg :: marker ( ) } ,
533+ // BINARY_OP specializations
534+ Self :: BinaryOpAddFloat
535+ | Self :: BinaryOpAddInt
536+ | Self :: BinaryOpAddUnicode
537+ | Self :: BinaryOpExtend
538+ | Self :: BinaryOpInplaceAddUnicode
539+ | Self :: BinaryOpMultiplyFloat
540+ | Self :: BinaryOpMultiplyInt
541+ | Self :: BinaryOpSubscrDict
542+ | Self :: BinaryOpSubscrGetitem
543+ | Self :: BinaryOpSubscrListInt
544+ | Self :: BinaryOpSubscrListSlice
545+ | Self :: BinaryOpSubscrStrInt
546+ | Self :: BinaryOpSubscrTupleInt
547+ | Self :: BinaryOpSubtractFloat
548+ | Self :: BinaryOpSubtractInt => Self :: BinaryOp { op : Arg :: marker ( ) } ,
549+ // CALL specializations
550+ Self :: CallAllocAndEnterInit
551+ | Self :: CallBoundMethodExactArgs
552+ | Self :: CallBoundMethodGeneral
553+ | Self :: CallBuiltinClass
554+ | Self :: CallBuiltinFast
555+ | Self :: CallBuiltinFastWithKeywords
556+ | Self :: CallBuiltinO
557+ | Self :: CallIsinstance
558+ | Self :: CallLen
559+ | Self :: CallListAppend
560+ | Self :: CallMethodDescriptorFast
561+ | Self :: CallMethodDescriptorFastWithKeywords
562+ | Self :: CallMethodDescriptorNoargs
563+ | Self :: CallMethodDescriptorO
564+ | Self :: CallNonPyGeneral
565+ | Self :: CallPyExactArgs
566+ | Self :: CallPyGeneral
567+ | Self :: CallStr1
568+ | Self :: CallTuple1
569+ | Self :: CallType1 => Self :: Call {
570+ nargs : Arg :: marker ( ) ,
571+ } ,
572+ // CALL_KW specializations
573+ Self :: CallKwBoundMethod | Self :: CallKwNonPy | Self :: CallKwPy => Self :: CallKw {
574+ nargs : Arg :: marker ( ) ,
575+ } ,
576+ // TO_BOOL specializations
577+ Self :: ToBoolAlwaysTrue
578+ | Self :: ToBoolBool
579+ | Self :: ToBoolInt
580+ | Self :: ToBoolList
581+ | Self :: ToBoolNone
582+ | Self :: ToBoolStr => Self :: ToBool ,
583+ // COMPARE_OP specializations
584+ Self :: CompareOpFloat | Self :: CompareOpInt | Self :: CompareOpStr => {
585+ Self :: CompareOp { op : Arg :: marker ( ) }
586+ }
587+ // CONTAINS_OP specializations
588+ Self :: ContainsOpDict | Self :: ContainsOpSet => Self :: ContainsOp ( Arg :: marker ( ) ) ,
589+ // FOR_ITER specializations
590+ Self :: ForIterGen | Self :: ForIterList | Self :: ForIterRange | Self :: ForIterTuple => {
591+ Self :: ForIter {
592+ target : Arg :: marker ( ) ,
593+ }
594+ }
595+ // LOAD_GLOBAL specializations
596+ Self :: LoadGlobalBuiltin | Self :: LoadGlobalModule => Self :: LoadGlobal ( Arg :: marker ( ) ) ,
597+ // STORE_ATTR specializations
598+ Self :: StoreAttrInstanceValue | Self :: StoreAttrSlot | Self :: StoreAttrWithHint => {
599+ Self :: StoreAttr { idx : Arg :: marker ( ) }
600+ }
601+ // LOAD_SUPER_ATTR specializations
602+ Self :: LoadSuperAttrAttr | Self :: LoadSuperAttrMethod => {
603+ Self :: LoadSuperAttr { arg : Arg :: marker ( ) }
604+ }
605+ // STORE_SUBSCR specializations
606+ Self :: StoreSubscrDict | Self :: StoreSubscrListInt => Self :: StoreSubscr ,
607+ // UNPACK_SEQUENCE specializations
608+ Self :: UnpackSequenceList | Self :: UnpackSequenceTuple | Self :: UnpackSequenceTwoTuple => {
609+ Self :: UnpackSequence {
610+ size : Arg :: marker ( ) ,
611+ }
612+ }
613+ // SEND specializations
614+ Self :: SendGen => Self :: Send {
615+ target : Arg :: marker ( ) ,
616+ } ,
617+ // LOAD_CONST specializations
618+ Self :: LoadConstImmortal | Self :: LoadConstMortal => {
619+ Self :: LoadConst { idx : Arg :: marker ( ) }
620+ }
621+ // RESUME specializations
622+ Self :: ResumeCheck => Self :: Resume { arg : Arg :: marker ( ) } ,
623+ // Everything else maps to itself
624+ _ => self ,
625+ }
626+ }
627+
515628 /// Number of CACHE code units that follow this instruction.
516629 /// _PyOpcode_Caches
517630 pub fn cache_entries ( self ) -> usize {
0 commit comments