@@ -78,7 +78,13 @@ def change_by(value)
78
78
# These are various compilation options provided.
79
79
attr_reader :options
80
80
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
+ )
82
88
@type = type
83
89
@name = name
84
90
@parent_iseq = parent_iseq
@@ -413,6 +419,10 @@ def opt_aset_with(object, calldata)
413
419
push ( OptAsetWith . new ( object , calldata ) )
414
420
end
415
421
422
+ def opt_case_dispatch ( case_dispatch_hash , else_label )
423
+ push ( OptCaseDispatch . new ( case_dispatch_hash , else_label ) )
424
+ end
425
+
416
426
def opt_getconstant_path ( names )
417
427
if RUBY_VERSION < "3.2" || !options . inline_const_cache?
418
428
cache = nil
@@ -655,13 +665,225 @@ def swap
655
665
push ( Swap . new )
656
666
end
657
667
668
+ def throw ( type )
669
+ push ( Throw . new ( type ) )
670
+ end
671
+
658
672
def topn ( number )
659
673
push ( TopN . new ( number ) )
660
674
end
661
675
662
676
def toregexp ( options , length )
663
677
push ( ToRegExp . new ( options , length ) )
664
678
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_getconstant_path
822
+ iseq . opt_getconstant_path ( opnds [ 0 ] )
823
+ when :opt_getinlinecache
824
+ iseq . opt_getinlinecache ( opnds [ 0 ] , opnds [ 1 ] )
825
+ when :opt_newarray_max
826
+ iseq . opt_newarray_max ( opnds [ 0 ] )
827
+ when :opt_newarray_min
828
+ iseq . opt_newarray_min ( opnds [ 0 ] )
829
+ when :opt_neq
830
+ iseq . push (
831
+ OptNEq . new ( CallData . from ( opnds [ 0 ] ) , CallData . from ( opnds [ 1 ] ) )
832
+ )
833
+ when :opt_setinlinecache
834
+ iseq . opt_setinlinecache ( opnds [ 0 ] )
835
+ when :opt_str_freeze
836
+ iseq . opt_str_freeze ( opnds [ 0 ] )
837
+ when :opt_str_uminus
838
+ iseq . opt_str_uminus ( opnds [ 0 ] )
839
+ when :pop
840
+ iseq . pop
841
+ when :putnil
842
+ iseq . putnil
843
+ when :putobject
844
+ iseq . putobject ( opnds [ 0 ] )
845
+ when :putobject_INT2FIX_0_
846
+ iseq . putobject ( 0 )
847
+ when :putobject_INT2FIX_1_
848
+ iseq . putobject ( 1 )
849
+ when :putself
850
+ iseq . putself
851
+ when :putstring
852
+ iseq . putstring ( opnds [ 0 ] )
853
+ when :putspecialobject
854
+ iseq . putspecialobject ( opnds [ 0 ] )
855
+ when :send
856
+ block_iseq = opnds [ 1 ] ? from ( opnds [ 1 ] , options , iseq ) : nil
857
+ iseq . send ( CallData . from ( opnds [ 0 ] ) , block_iseq )
858
+ when :setclassvariable
859
+ iseq . push ( SetClassVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
860
+ when :setconstant
861
+ iseq . setconstant ( opnds [ 0 ] )
862
+ when :setglobal
863
+ iseq . setglobal ( opnds [ 0 ] )
864
+ when :setinstancevariable
865
+ iseq . push ( SetInstanceVariable . new ( opnds [ 0 ] , opnds [ 1 ] ) )
866
+ when :setn
867
+ iseq . setn ( opnds [ 0 ] )
868
+ when :setspecial
869
+ iseq . setspecial ( opnds [ 0 ] )
870
+ when :splatarray
871
+ iseq . splatarray ( opnds [ 0 ] )
872
+ when :swap
873
+ iseq . swap
874
+ when :throw
875
+ iseq . throw ( opnds [ 0 ] )
876
+ when :topn
877
+ iseq . topn ( opnds [ 0 ] )
878
+ when :toregexp
879
+ iseq . toregexp ( opnds [ 0 ] , opnds [ 1 ] )
880
+ else
881
+ raise "Unknown instruction type: #{ type } "
882
+ end
883
+ end
884
+
885
+ iseq
886
+ end
665
887
end
666
888
end
667
889
end
0 commit comments