@@ -799,163 +799,6 @@ def serialize(insn)
799
799
end
800
800
end
801
801
802
- # This class is responsible for taking a compiled instruction sequence and
803
- # walking through it to generate equivalent Ruby code.
804
- class Disassembler
805
- module DSL
806
- def Args ( parts )
807
- Args . new ( parts : parts , location : Location . default )
808
- end
809
-
810
- def ArgParen ( arguments )
811
- ArgParen . new ( arguments : arguments , location : Location . default )
812
- end
813
-
814
- def Assign ( target , value )
815
- Assign . new ( target : target , value : value , location : Location . default )
816
- end
817
-
818
- def Binary ( left , operator , right )
819
- Binary . new ( left : left , operator : operator , right : right , location : Location . default )
820
- end
821
-
822
- def CallNode ( receiver , operator , message , arguments )
823
- CallNode . new ( receiver : receiver , operator : operator , message : message , arguments : arguments , location : Location . default )
824
- end
825
-
826
- def FloatLiteral ( value )
827
- FloatLiteral . new ( value : value , location : Location . default )
828
- end
829
-
830
- def Ident ( value )
831
- Ident . new ( value : value , location : Location . default )
832
- end
833
-
834
- def Int ( value )
835
- Int . new ( value : value , location : Location . default )
836
- end
837
-
838
- def Period ( value )
839
- Period . new ( value : value , location : Location . default )
840
- end
841
-
842
- def Program ( statements )
843
- Program . new ( statements : statements , location : Location . default )
844
- end
845
-
846
- def ReturnNode ( arguments )
847
- ReturnNode . new ( arguments : arguments , location : Location . default )
848
- end
849
-
850
- def Statements ( body )
851
- Statements . new ( nil , body : body , location : Location . default )
852
- end
853
-
854
- def VarField ( value )
855
- VarField . new ( value : value , location : Location . default )
856
- end
857
-
858
- def VarRef ( value )
859
- VarRef . new ( value : value , location : Location . default )
860
- end
861
- end
862
-
863
- include DSL
864
- attr_reader :iseq
865
-
866
- def initialize ( iseq )
867
- @iseq = iseq
868
- end
869
-
870
- def to_ruby
871
- stack = [ ]
872
-
873
- iseq . insns . each do |insn |
874
- # skip line numbers and events
875
- next unless insn . is_a? ( Array )
876
-
877
- case insn [ 0 ]
878
- when :getlocal_WC_0
879
- stack << VarRef ( Ident ( local_name ( insn [ 1 ] , 0 ) ) )
880
- when :leave
881
- stack << ReturnNode ( Args ( [ stack . pop ] ) )
882
- when :opt_and
883
- left , right = stack . pop ( 2 )
884
- stack << Binary ( left , :& , right )
885
- when :opt_div
886
- left , right = stack . pop ( 2 )
887
- stack << Binary ( left , :/ , right )
888
- when :opt_eq
889
- left , right = stack . pop ( 2 )
890
- stack << Binary ( left , :== , right )
891
- when :opt_ge
892
- left , right = stack . pop ( 2 )
893
- stack << Binary ( left , :>= , right )
894
- when :opt_gt
895
- left , right = stack . pop ( 2 )
896
- stack << Binary ( left , :> , right )
897
- when :opt_le
898
- left , right = stack . pop ( 2 )
899
- stack << Binary ( left , :<= , right )
900
- when :opt_lt
901
- left , right = stack . pop ( 2 )
902
- stack << Binary ( left , :< , right )
903
- when :opt_ltlt
904
- left , right = stack . pop ( 2 )
905
- stack << Binary ( left , :<< , right )
906
- when :opt_minus
907
- left , right = stack . pop ( 2 )
908
- stack << Binary ( left , :- , right )
909
- when :opt_mod
910
- left , right = stack . pop ( 2 )
911
- stack << Binary ( left , :% , right )
912
- when :opt_mult
913
- left , right = stack . pop ( 2 )
914
- stack << Binary ( left , :* , right )
915
- when :opt_neq
916
- left , right = stack . pop ( 2 )
917
- stack << Binary ( left , :"!=" , right )
918
- when :opt_or
919
- left , right = stack . pop ( 2 )
920
- stack << Binary ( left , :| , right )
921
- when :opt_plus
922
- left , right = stack . pop ( 2 )
923
- stack << Binary ( left , :+ , right )
924
- when :opt_send_without_block
925
- receiver , *arguments = stack . pop ( insn [ 1 ] [ :orig_argc ] + 1 )
926
- stack << CallNode ( receiver , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] ) , ArgParen ( Args ( arguments ) ) )
927
- when :putobject
928
- case insn [ 1 ]
929
- when Float
930
- stack << FloatLiteral ( insn [ 1 ] . inspect )
931
- when Integer
932
- stack << Int ( insn [ 1 ] . inspect )
933
- else
934
- raise "Unknown object type: #{ insn [ 1 ] . class . name } "
935
- end
936
- when :putobject_INT2FIX_0_
937
- stack << Int ( "0" )
938
- when :putobject_INT2FIX_1_
939
- stack << Int ( "1" )
940
- when :setlocal_WC_0
941
- stack << Assign ( VarField ( Ident ( local_name ( insn [ 1 ] , 0 ) ) ) , stack . pop )
942
- else
943
- raise "Unknown instruction #{ insn [ 0 ] } "
944
- end
945
- end
946
-
947
- Program ( Statements ( stack ) )
948
- end
949
-
950
- private
951
-
952
- def local_name ( index , level )
953
- current = iseq
954
- level . times { current = current . parent_iseq }
955
- current . local_table . locals [ index ] . name . to_s
956
- end
957
- end
958
-
959
802
# These constants correspond to the putspecialobject instruction. They are
960
803
# used to represent special objects that are pushed onto the stack.
961
804
VM_SPECIAL_OBJECT_VMCORE = 1
0 commit comments