@@ -702,7 +702,13 @@ def opt_setinlinecache(inline_storage)
702702 def opt_str_freeze ( value )
703703 if specialized_instruction
704704 stack . change_by ( +1 )
705- iseq . push ( [ :opt_str_freeze , value , call_data ( :freeze , 0 , VM_CALL_ARGS_SIMPLE ) ] )
705+ iseq . push (
706+ [
707+ :opt_str_freeze ,
708+ value ,
709+ call_data ( :freeze , 0 , VM_CALL_ARGS_SIMPLE )
710+ ]
711+ )
706712 else
707713 putstring ( value )
708714 send ( :freeze , 0 , VM_CALL_ARGS_SIMPLE )
@@ -712,7 +718,9 @@ def opt_str_freeze(value)
712718 def opt_str_uminus ( value )
713719 if specialized_instruction
714720 stack . change_by ( +1 )
715- iseq . push ( [ :opt_str_uminus , value , call_data ( :-@ , 0 , VM_CALL_ARGS_SIMPLE ) ] )
721+ iseq . push (
722+ [ :opt_str_uminus , value , call_data ( :-@ , 0 , VM_CALL_ARGS_SIMPLE ) ]
723+ )
716724 else
717725 putstring ( value )
718726 send ( :-@ , 0 , VM_CALL_ARGS_SIMPLE )
@@ -1024,7 +1032,7 @@ def visit_args(node)
10241032 end
10251033
10261034 def visit_array ( node )
1027- if compiled = RubyVisitor . compile ( node )
1035+ if ( compiled = RubyVisitor . compile ( node ) )
10281036 builder . duparray ( compiled )
10291037 else
10301038 length = 0
@@ -1045,7 +1053,9 @@ def visit_array(node)
10451053 end
10461054
10471055 builder . newarray ( length ) if length > 0
1048- builder . concatarray if length > 0 && length != node . contents . parts . length
1056+ if length > 0 && length != node . contents . parts . length
1057+ builder . concatarray
1058+ end
10491059 end
10501060 end
10511061
@@ -1134,7 +1144,7 @@ def visit_backref(node)
11341144 end
11351145
11361146 def visit_bare_assoc_hash ( node )
1137- if compiled = RubyVisitor . compile ( node )
1147+ if ( compiled = RubyVisitor . compile ( node ) )
11381148 builder . duphash ( compiled )
11391149 else
11401150 visit_all ( node . assocs )
@@ -1168,6 +1178,35 @@ def visit_binary(node)
11681178 end
11691179 end
11701180
1181+ def visit_block ( node )
1182+ with_instruction_sequence (
1183+ :block ,
1184+ "block in #{ current_iseq . name } " ,
1185+ current_iseq ,
1186+ node
1187+ ) do
1188+ visit ( node . block_var )
1189+ visit ( node . bodystmt )
1190+ builder . leave
1191+ end
1192+ end
1193+
1194+ def visit_block_var ( node )
1195+ params = node . params
1196+
1197+ if params . requireds . length == 1 && params . optionals . empty? &&
1198+ !params . rest && params . posts . empty? && params . keywords . empty? &&
1199+ !params . keyword_rest && !params . block
1200+ current_iseq . argument_options [ :ambiguous_param0 ] = true
1201+ end
1202+
1203+ visit ( node . params )
1204+
1205+ node . locals . each do |local |
1206+ current_iseq . local_table . plain ( local . value . to_sym )
1207+ end
1208+ end
1209+
11711210 def visit_blockarg ( node )
11721211 current_iseq . argument_options [ :block_start ] = current_iseq . argument_size
11731212 current_iseq . local_table . block_proxy ( node . name . value . to_sym )
@@ -1184,12 +1223,14 @@ def visit_call(node)
11841223 # First we're going to check if we're calling a method on an array
11851224 # literal without any arguments. In that case there are some
11861225 # specializations we might be able to perform.
1187- if arg_parts . length == 0 && ( node . message . is_a? ( Ident ) || node . message . is_a? ( Op ) )
1226+ if arg_parts . empty? &&
1227+ ( node . message . is_a? ( Ident ) || node . message . is_a? ( Op ) )
11881228 case node . receiver
11891229 when ArrayLiteral
11901230 parts = node . receiver . contents &.parts || [ ]
11911231
1192- if parts . none? { |part | part . is_a? ( ArgStar ) } && RubyVisitor . compile ( node . receiver ) . nil?
1232+ if parts . none? { |part | part . is_a? ( ArgStar ) } &&
1233+ RubyVisitor . compile ( node . receiver ) . nil?
11931234 case node . message . value
11941235 when "max"
11951236 visit ( node . receiver . contents )
@@ -1215,13 +1256,10 @@ def visit_call(node)
12151256 end
12161257 end
12171258
1218- if node . receiver
1219- visit ( node . receiver )
1220- else
1221- builder . putself
1222- end
1259+ node . receiver ? visit ( node . receiver ) : builder . putself
12231260
12241261 visit ( node . arguments )
1262+ block_iseq = visit ( node . block ) if node . respond_to? ( :block ) && node . block
12251263
12261264 if arg_parts . last . is_a? ( ArgBlock )
12271265 flag = node . receiver . nil? ? VM_CALL_FCALL : 0
@@ -1235,7 +1273,12 @@ def visit_call(node)
12351273 flag |= VM_CALL_KW_SPLAT
12361274 end
12371275
1238- builder . send ( node . message . value . to_sym , arg_parts . length - 1 , flag )
1276+ builder . send (
1277+ node . message . value . to_sym ,
1278+ arg_parts . length - 1 ,
1279+ flag ,
1280+ block_iseq
1281+ )
12391282 else
12401283 flag = 0
12411284 arg_parts . each do |arg_part |
@@ -1247,9 +1290,14 @@ def visit_call(node)
12471290 end
12481291 end
12491292
1250- flag |= VM_CALL_ARGS_SIMPLE if flag == 0
1293+ flag |= VM_CALL_ARGS_SIMPLE if block_iseq . nil? && flag == 0
12511294 flag |= VM_CALL_FCALL if node . receiver . nil?
1252- builder . send ( node . message . value . to_sym , arg_parts . length , flag )
1295+ builder . send (
1296+ node . message . value . to_sym ,
1297+ arg_parts . length ,
1298+ flag ,
1299+ block_iseq
1300+ )
12531301 end
12541302 end
12551303
@@ -1291,23 +1339,25 @@ def visit_class(node)
12911339
12921340 def visit_command ( node )
12931341 visit_call (
1294- CallNode . new (
1342+ CommandCall . new (
12951343 receiver : nil ,
12961344 operator : nil ,
12971345 message : node . message ,
12981346 arguments : node . arguments ,
1347+ block : node . block ,
12991348 location : node . location
13001349 )
13011350 )
13021351 end
13031352
13041353 def visit_command_call ( node )
13051354 visit_call (
1306- CallNode . new (
1355+ CommandCall . new (
13071356 receiver : node . receiver ,
13081357 operator : node . operator ,
13091358 message : node . message ,
13101359 arguments : node . arguments ,
1360+ block : node . block ,
13111361 location : node . location
13121362 )
13131363 )
@@ -1537,6 +1587,19 @@ def visit_label(node)
15371587 builder . putobject ( node . accept ( RubyVisitor . new ) )
15381588 end
15391589
1590+ def visit_method_add_block ( node )
1591+ visit_call (
1592+ CommandCall . new (
1593+ receiver : node . call . receiver ,
1594+ operator : node . call . operator ,
1595+ message : node . call . message ,
1596+ arguments : node . call . arguments ,
1597+ block : node . block ,
1598+ location : node . location
1599+ )
1600+ )
1601+ end
1602+
15401603 def visit_module ( node )
15411604 name = node . constant . constant . value . to_sym
15421605 module_iseq =
@@ -1898,11 +1961,12 @@ def visit_unary(node)
18981961 end
18991962
19001963 visit_call (
1901- CallNode . new (
1964+ CommandCall . new (
19021965 receiver : node . statement ,
19031966 operator : nil ,
19041967 message : Ident . new ( value : method_id , location : Location . default ) ,
19051968 arguments : nil ,
1969+ block : nil ,
19061970 location : Location . default
19071971 )
19081972 )
0 commit comments