@@ -78,7 +78,13 @@ def change_by(value)
7878 # These are various compilation options provided.
7979 attr_reader :options
8080
81- def initialize ( type , name , parent_iseq , location , options = Compiler ::Options . new )
81+ def initialize (
82+ type ,
83+ name ,
84+ parent_iseq ,
85+ location ,
86+ options = Compiler ::Options . new
87+ )
8288 @type = type
8389 @name = name
8490 @parent_iseq = parent_iseq
@@ -413,6 +419,10 @@ def opt_aset_with(object, calldata)
413419 push ( OptAsetWith . new ( object , calldata ) )
414420 end
415421
422+ def opt_case_dispatch ( case_dispatch_hash , else_label )
423+ push ( OptCaseDispatch . new ( case_dispatch_hash , else_label ) )
424+ end
425+
416426 def opt_getconstant_path ( names )
417427 if RUBY_VERSION < "3.2" || !options . inline_const_cache?
418428 cache = nil
@@ -655,13 +665,223 @@ def swap
655665 push ( Swap . new )
656666 end
657667
668+ def throw ( type )
669+ push ( Throw . new ( type ) )
670+ end
671+
658672 def topn ( number )
659673 push ( TopN . new ( number ) )
660674 end
661675
662676 def toregexp ( options , length )
663677 push ( ToRegExp . new ( options , length ) )
664678 end
679+
680+ # This method will create a new instruction sequence from a serialized
681+ # RubyVM::InstructionSequence object.
682+ def self . from ( source , options = Compiler ::Options . new , parent_iseq = nil )
683+ iseq = new ( source [ 9 ] , source [ 5 ] , parent_iseq , Location . default , options )
684+
685+ # set up the correct argument size
686+ iseq . argument_size = source [ 4 ] [ :arg_size ]
687+
688+ # set up all of the locals
689+ source [ 10 ] . each { |local | iseq . local_table . plain ( local ) }
690+
691+ # set up the argument options
692+ iseq . argument_options . merge! ( source [ 11 ] )
693+
694+ # set up all of the instructions
695+ source [ 13 ] . each do |insn |
696+ # skip line numbers
697+ next if insn . is_a? ( Integer )
698+
699+ # put events into the array and then continue
700+ if insn . is_a? ( Symbol )
701+ iseq . event ( insn )
702+ next
703+ end
704+
705+ type , *opnds = insn
706+ case type
707+ when :adjuststack
708+ iseq . adjuststack ( opnds [ 0 ] )
709+ when :anytostring
710+ iseq . anytostring
711+ when :branchif
712+ iseq . branchif ( opnds [ 0 ] )
713+ when :branchnil
714+ iseq . branchnil ( opnds [ 0 ] )
715+ when :branchunless
716+ iseq . branchunless ( opnds [ 0 ] )
717+ when :checkkeyword
718+ iseq . checkkeyword ( iseq . local_table . size - opnds [ 0 ] + 2 , opnds [ 1 ] )
719+ when :checkmatch
720+ iseq . checkmatch ( opnds [ 0 ] )
721+ when :checktype
722+ iseq . checktype ( opnds [ 0 ] )
723+ when :concatarray
724+ iseq . concatarray
725+ when :concatstrings
726+ iseq . concatstrings ( opnds [ 0 ] )
727+ when :defineclass
728+ iseq . defineclass ( opnds [ 0 ] , from ( opnds [ 1 ] , options , iseq ) , opnds [ 2 ] )
729+ when :defined
730+ iseq . defined ( opnds [ 0 ] , opnds [ 1 ] , opnds [ 2 ] )
731+ when :definemethod
732+ iseq . definemethod ( opnds [ 0 ] , from ( opnds [ 1 ] , options , iseq ) )
733+ when :definesmethod
734+ iseq . definesmethod ( opnds [ 0 ] , from ( opnds [ 1 ] , options , iseq ) )
735+ when :dup
736+ iseq . dup
737+ when :duparray
738+ iseq . duparray ( opnds [ 0 ] )
739+ when :duphash
740+ iseq . duphash ( opnds [ 0 ] )
741+ when :dupn
742+ iseq . dupn ( opnds [ 0 ] )
743+ when :expandarray
744+ iseq . expandarray ( opnds [ 0 ] , opnds [ 1 ] )
745+ when :getblockparam , :getblockparamproxy , :getlocal , :getlocal_WC_0 ,
746+ :getlocal_WC_1 , :setblockparam , :setlocal , :setlocal_WC_0 ,
747+ :setlocal_WC_1
748+ current = iseq
749+ level = 0
750+
751+ case type
752+ when :getlocal_WC_1 , :setlocal_WC_1
753+ level = 1
754+ when :getblockparam , :getblockparamproxy , :getlocal , :setblockparam ,
755+ :setlocal
756+ level = opnds [ 1 ]
757+ end
758+
759+ level . times { current = current . parent_iseq }
760+ index = current . local_table . size - opnds [ 0 ] + 2
761+
762+ case type
763+ when :getblockparam
764+ iseq . getblockparam ( index , level )
765+ when :getblockparamproxy
766+ iseq . getblockparamproxy ( index , level )
767+ when :getlocal , :getlocal_WC_0 , :getlocal_WC_1
768+ iseq . getlocal ( index , level )
769+ when :setblockparam
770+ iseq . setblockparam ( index , level )
771+ when :setlocal , :setlocal_WC_0 , :setlocal_WC_1
772+ iseq . setlocal ( index , level )
773+ end
774+ when :getclassvariable
775+ iseq . push ( GetClassVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
776+ when :getconstant
777+ iseq . getconstant ( opnds [ 0 ] )
778+ when :getglobal
779+ iseq . getglobal ( opnds [ 0 ] )
780+ when :getinstancevariable
781+ iseq . push ( GetInstanceVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
782+ when :getspecial
783+ iseq . getspecial ( opnds [ 0 ] , opnds [ 1 ] )
784+ when :intern
785+ iseq . intern
786+ when :invokeblock
787+ iseq . invokeblock ( CallData . from ( opnds [ 0 ] ) )
788+ when :invokesuper
789+ block_iseq = opnds [ 1 ] ? from ( opnds [ 1 ] , options , iseq ) : nil
790+ iseq . invokesuper ( CallData . from ( opnds [ 0 ] ) , block_iseq )
791+ when :jump
792+ iseq . jump ( opnds [ 0 ] )
793+ when :leave
794+ iseq . leave
795+ when :newarray
796+ iseq . newarray ( opnds [ 0 ] )
797+ when :newarraykwsplat
798+ iseq . newarraykwsplat ( opnds [ 0 ] )
799+ when :newhash
800+ iseq . newhash ( opnds [ 0 ] )
801+ when :newrange
802+ iseq . newrange ( opnds [ 0 ] )
803+ when :nop
804+ iseq . nop
805+ when :objtostring
806+ iseq . objtostring ( CallData . from ( opnds [ 0 ] ) )
807+ when :once
808+ iseq . once ( from ( opnds [ 0 ] , options , iseq ) , opnds [ 1 ] )
809+ when :opt_and , :opt_aref , :opt_aset , :opt_div , :opt_empty_p , :opt_eq ,
810+ :opt_ge , :opt_gt , :opt_le , :opt_length , :opt_lt , :opt_ltlt ,
811+ :opt_minus , :opt_mod , :opt_mult , :opt_nil_p , :opt_not , :opt_or ,
812+ :opt_plus , :opt_regexpmatch2 , :opt_send_without_block , :opt_size ,
813+ :opt_succ
814+ iseq . send ( CallData . from ( opnds [ 0 ] ) , nil )
815+ when :opt_aref_with
816+ iseq . opt_aref_with ( opnds [ 0 ] , CallData . from ( opnds [ 1 ] ) )
817+ when :opt_aset_with
818+ iseq . opt_aset_with ( opnds [ 0 ] , CallData . from ( opnds [ 1 ] ) )
819+ when :opt_case_dispatch
820+ iseq . opt_case_dispatch ( opnds [ 0 ] , opnds [ 1 ] )
821+ when :opt_getinlinecache
822+ iseq . opt_getinlinecache ( opnds [ 0 ] , opnds [ 1 ] )
823+ when :opt_newarray_max
824+ iseq . opt_newarray_max ( opnds [ 0 ] )
825+ when :opt_newarray_min
826+ iseq . opt_newarray_min ( opnds [ 0 ] )
827+ when :opt_neq
828+ iseq . push (
829+ OptNEq . new ( CallData . from ( opnds [ 0 ] ) , CallData . from ( opnds [ 1 ] ) )
830+ )
831+ when :opt_setinlinecache
832+ iseq . opt_setinlinecache ( opnds [ 0 ] )
833+ when :opt_str_freeze
834+ iseq . opt_str_freeze ( opnds [ 0 ] )
835+ when :opt_str_uminus
836+ iseq . opt_str_uminus ( opnds [ 0 ] )
837+ when :pop
838+ iseq . pop
839+ when :putnil
840+ iseq . putnil
841+ when :putobject
842+ iseq . putobject ( opnds [ 0 ] )
843+ when :putobject_INT2FIX_0_
844+ iseq . putobject ( 0 )
845+ when :putobject_INT2FIX_1_
846+ iseq . putobject ( 1 )
847+ when :putself
848+ iseq . putself
849+ when :putstring
850+ iseq . putstring ( opnds [ 0 ] )
851+ when :putspecialobject
852+ iseq . putspecialobject ( opnds [ 0 ] )
853+ when :send
854+ block_iseq = opnds [ 1 ] ? from ( opnds [ 1 ] , options , iseq ) : nil
855+ iseq . send ( CallData . from ( opnds [ 0 ] ) , block_iseq )
856+ when :setclassvariable
857+ iseq . push ( SetClassVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
858+ when :setconstant
859+ iseq . setconstant ( opnds [ 0 ] )
860+ when :setglobal
861+ iseq . setglobal ( opnds [ 0 ] )
862+ when :setinstancevariable
863+ iseq . push ( SetInstanceVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
864+ when :setn
865+ iseq . setn ( opnds [ 0 ] )
866+ when :setspecial
867+ iseq . setspecial ( opnds [ 0 ] )
868+ when :splatarray
869+ iseq . splatarray ( opnds [ 0 ] )
870+ when :swap
871+ iseq . swap
872+ when :throw
873+ iseq . throw ( opnds [ 0 ] )
874+ when :topn
875+ iseq . topn ( opnds [ 0 ] )
876+ when :toregexp
877+ iseq . toregexp ( opnds [ 0 ] , opnds [ 1 ] )
878+ else
879+ raise "Unknown instruction type: #{ type } "
880+ end
881+ end
882+
883+ iseq
884+ end
665885 end
666886 end
667887end
0 commit comments