@@ -17,7 +17,7 @@ def initialize(iseq)
1717 end
1818
1919 def to_ruby
20- Program ( Statements ( disassemble ( iseq . insns ) ) )
20+ Program ( disassemble ( iseq ) )
2121 end
2222
2323 private
@@ -31,12 +31,12 @@ def node_for(value)
3131 end
3232 end
3333
34- def disassemble ( insns )
34+ def disassemble ( iseq )
3535 label = :label_0
3636 clauses = { }
3737 clause = [ ]
3838
39- insns . each do |insn |
39+ iseq . insns . each do |insn |
4040 if insn . is_a? ( Symbol ) && insn . start_with? ( "label_" )
4141 clause << Assign ( label_field , node_for ( insn ) ) unless clause . last . is_a? ( Next )
4242 clauses [ label ] = clause
@@ -61,7 +61,8 @@ def disassemble(insns)
6161 clause << Assign ( label_field , node_for ( insn [ 1 ] ) )
6262 clause << Next ( Args ( [ ] ) )
6363 when :leave
64- clause << ReturnNode ( Args ( [ clause . pop ] ) )
64+ value = Args ( [ clause . pop ] )
65+ clause << ( iseq . type == :top ? Break ( value ) : ReturnNode ( value ) )
6566 when :opt_and
6667 left , right = clause . pop ( 2 )
6768 clause << Binary ( left , :& , right )
@@ -116,14 +117,27 @@ def disassemble(insns)
116117 left , right = clause . pop ( 2 )
117118 clause << Binary ( left , :+ , right )
118119 when :opt_send_without_block
119- if insn [ 1 ] [ :orig_argc ] == 0
120- clause << CallNode ( clause . pop , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] ) , nil )
121- elsif insn [ 1 ] [ :orig_argc ] == 1 && insn [ 1 ] [ :mid ] . end_with? ( "=" )
122- receiver , argument = clause . pop ( 2 )
123- clause << Assign ( CallNode ( receiver , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] [ 0 ..-2 ] ) , nil ) , argument )
120+ if insn [ 1 ] [ :flag ] & VM_CALL_FCALL > 0
121+ if insn [ 1 ] [ :orig_argc ] == 0
122+ clause . pop
123+ clause << CallNode ( nil , nil , Ident ( insn [ 1 ] [ :mid ] ) , Args ( [ ] ) )
124+ elsif insn [ 1 ] [ :orig_argc ] == 1 && insn [ 1 ] [ :mid ] . end_with? ( "=" )
125+ _receiver , argument = clause . pop ( 2 )
126+ clause << Assign ( CallNode ( nil , nil , Ident ( insn [ 1 ] [ :mid ] [ 0 ..-2 ] ) , nil ) , argument )
127+ else
128+ _receiver , *arguments = clause . pop ( insn [ 1 ] [ :orig_argc ] + 1 )
129+ clause << CallNode ( nil , nil , Ident ( insn [ 1 ] [ :mid ] ) , ArgParen ( Args ( arguments ) ) )
130+ end
124131 else
125- receiver , *arguments = clause . pop ( insn [ 1 ] [ :orig_argc ] + 1 )
126- clause << CallNode ( receiver , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] ) , ArgParen ( Args ( arguments ) ) )
132+ if insn [ 1 ] [ :orig_argc ] == 0
133+ clause << CallNode ( clause . pop , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] ) , nil )
134+ elsif insn [ 1 ] [ :orig_argc ] == 1 && insn [ 1 ] [ :mid ] . end_with? ( "=" )
135+ receiver , argument = clause . pop ( 2 )
136+ clause << Assign ( CallNode ( receiver , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] [ 0 ..-2 ] ) , nil ) , argument )
137+ else
138+ receiver , *arguments = clause . pop ( insn [ 1 ] [ :orig_argc ] + 1 )
139+ clause << CallNode ( receiver , Period ( "." ) , Ident ( insn [ 1 ] [ :mid ] ) , ArgParen ( Args ( arguments ) ) )
140+ end
127141 end
128142 when :putobject
129143 case insn [ 1 ]
@@ -166,7 +180,7 @@ def disassemble(insns)
166180 # If there's only one clause, then we don't need a case statement, and
167181 # we can just disassemble the first clause.
168182 clauses [ label ] = clause
169- return clauses . values . first if clauses . size == 1
183+ return Statements ( clauses . values . first ) if clauses . size == 1
170184
171185 # Here we're going to build up a big case statement that will handle all
172186 # of the different labels.
@@ -196,7 +210,7 @@ def disassemble(insns)
196210 # statement.
197211 stack << Assign ( label_field , node_for ( :label_0 ) )
198212 stack << MethodAddBlock ( CallNode ( nil , nil , Ident ( "loop" ) , Args ( [ ] ) ) , BlockNode ( Kw ( "do" ) , nil , BodyStmt ( Statements ( [ switch ] ) , nil , nil , nil , nil ) ) )
199- stack
213+ Statements ( stack )
200214 end
201215
202216 def local_name ( index , level )
0 commit comments