@@ -702,7 +702,13 @@ def opt_setinlinecache(inline_storage)
702
702
def opt_str_freeze ( value )
703
703
if specialized_instruction
704
704
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
+ )
706
712
else
707
713
putstring ( value )
708
714
send ( :freeze , 0 , VM_CALL_ARGS_SIMPLE )
@@ -712,7 +718,9 @@ def opt_str_freeze(value)
712
718
def opt_str_uminus ( value )
713
719
if specialized_instruction
714
720
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
+ )
716
724
else
717
725
putstring ( value )
718
726
send ( :-@ , 0 , VM_CALL_ARGS_SIMPLE )
@@ -1045,7 +1053,9 @@ def visit_array(node)
1045
1053
end
1046
1054
1047
1055
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
1049
1059
end
1050
1060
end
1051
1061
@@ -1168,6 +1178,33 @@ def visit_binary(node)
1168
1178
end
1169
1179
end
1170
1180
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? && !params . rest && params . posts . empty? && params . keywords . empty? && !params . keyword_rest && !params . block
1198
+ current_iseq . argument_options [ :ambiguous_param0 ] = true
1199
+ end
1200
+
1201
+ visit ( node . params )
1202
+
1203
+ node . locals . each do |local |
1204
+ current_iseq . local_table . plain ( local . value . to_sym )
1205
+ end
1206
+ end
1207
+
1171
1208
def visit_blockarg ( node )
1172
1209
current_iseq . argument_options [ :block_start ] = current_iseq . argument_size
1173
1210
current_iseq . local_table . block_proxy ( node . name . value . to_sym )
@@ -1184,12 +1221,14 @@ def visit_call(node)
1184
1221
# First we're going to check if we're calling a method on an array
1185
1222
# literal without any arguments. In that case there are some
1186
1223
# specializations we might be able to perform.
1187
- if arg_parts . length == 0 && ( node . message . is_a? ( Ident ) || node . message . is_a? ( Op ) )
1224
+ if arg_parts . length == 0 &&
1225
+ ( node . message . is_a? ( Ident ) || node . message . is_a? ( Op ) )
1188
1226
case node . receiver
1189
1227
when ArrayLiteral
1190
1228
parts = node . receiver . contents &.parts || [ ]
1191
1229
1192
- if parts . none? { |part | part . is_a? ( ArgStar ) } && RubyVisitor . compile ( node . receiver ) . nil?
1230
+ if parts . none? { |part | part . is_a? ( ArgStar ) } &&
1231
+ RubyVisitor . compile ( node . receiver ) . nil?
1193
1232
case node . message . value
1194
1233
when "max"
1195
1234
visit ( node . receiver . contents )
@@ -1215,13 +1254,10 @@ def visit_call(node)
1215
1254
end
1216
1255
end
1217
1256
1218
- if node . receiver
1219
- visit ( node . receiver )
1220
- else
1221
- builder . putself
1222
- end
1257
+ node . receiver ? visit ( node . receiver ) : builder . putself
1223
1258
1224
1259
visit ( node . arguments )
1260
+ block_iseq = visit ( node . block ) if node . respond_to? ( :block ) && node . block
1225
1261
1226
1262
if arg_parts . last . is_a? ( ArgBlock )
1227
1263
flag = node . receiver . nil? ? VM_CALL_FCALL : 0
@@ -1235,7 +1271,12 @@ def visit_call(node)
1235
1271
flag |= VM_CALL_KW_SPLAT
1236
1272
end
1237
1273
1238
- builder . send ( node . message . value . to_sym , arg_parts . length - 1 , flag )
1274
+ builder . send (
1275
+ node . message . value . to_sym ,
1276
+ arg_parts . length - 1 ,
1277
+ flag ,
1278
+ block_iseq
1279
+ )
1239
1280
else
1240
1281
flag = 0
1241
1282
arg_parts . each do |arg_part |
@@ -1247,9 +1288,14 @@ def visit_call(node)
1247
1288
end
1248
1289
end
1249
1290
1250
- flag |= VM_CALL_ARGS_SIMPLE if flag == 0
1291
+ flag |= VM_CALL_ARGS_SIMPLE if block_iseq . nil? && flag == 0
1251
1292
flag |= VM_CALL_FCALL if node . receiver . nil?
1252
- builder . send ( node . message . value . to_sym , arg_parts . length , flag )
1293
+ builder . send (
1294
+ node . message . value . to_sym ,
1295
+ arg_parts . length ,
1296
+ flag ,
1297
+ block_iseq
1298
+ )
1253
1299
end
1254
1300
end
1255
1301
@@ -1291,23 +1337,25 @@ def visit_class(node)
1291
1337
1292
1338
def visit_command ( node )
1293
1339
visit_call (
1294
- CallNode . new (
1340
+ CommandCall . new (
1295
1341
receiver : nil ,
1296
1342
operator : nil ,
1297
1343
message : node . message ,
1298
1344
arguments : node . arguments ,
1345
+ block : node . block ,
1299
1346
location : node . location
1300
1347
)
1301
1348
)
1302
1349
end
1303
1350
1304
1351
def visit_command_call ( node )
1305
1352
visit_call (
1306
- CallNode . new (
1353
+ CommandCall . new (
1307
1354
receiver : node . receiver ,
1308
1355
operator : node . operator ,
1309
1356
message : node . message ,
1310
1357
arguments : node . arguments ,
1358
+ block : node . block ,
1311
1359
location : node . location
1312
1360
)
1313
1361
)
@@ -1537,6 +1585,19 @@ def visit_label(node)
1537
1585
builder . putobject ( node . accept ( RubyVisitor . new ) )
1538
1586
end
1539
1587
1588
+ def visit_method_add_block ( node )
1589
+ visit_call (
1590
+ CommandCall . new (
1591
+ receiver : node . call . receiver ,
1592
+ operator : node . call . operator ,
1593
+ message : node . call . message ,
1594
+ arguments : node . call . arguments ,
1595
+ block : node . block ,
1596
+ location : node . location
1597
+ )
1598
+ )
1599
+ end
1600
+
1540
1601
def visit_module ( node )
1541
1602
name = node . constant . constant . value . to_sym
1542
1603
module_iseq =
@@ -1898,11 +1959,12 @@ def visit_unary(node)
1898
1959
end
1899
1960
1900
1961
visit_call (
1901
- CallNode . new (
1962
+ CommandCall . new (
1902
1963
receiver : node . statement ,
1903
1964
operator : nil ,
1904
1965
message : Ident . new ( value : method_id , location : Location . default ) ,
1905
1966
arguments : nil ,
1967
+ block : nil ,
1906
1968
location : Location . default
1907
1969
)
1908
1970
)
0 commit comments