@@ -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 )
@@ -1024,7 +1032,7 @@ def visit_args(node)
1024
1032
end
1025
1033
1026
1034
def visit_array ( node )
1027
- if compiled = RubyVisitor . compile ( node )
1035
+ if ( compiled = RubyVisitor . compile ( node ) )
1028
1036
builder . duparray ( compiled )
1029
1037
else
1030
1038
length = 0
@@ -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
@@ -1134,7 +1144,7 @@ def visit_backref(node)
1134
1144
end
1135
1145
1136
1146
def visit_bare_assoc_hash ( node )
1137
- if compiled = RubyVisitor . compile ( node )
1147
+ if ( compiled = RubyVisitor . compile ( node ) )
1138
1148
builder . duphash ( compiled )
1139
1149
else
1140
1150
visit_all ( node . assocs )
@@ -1168,6 +1178,35 @@ 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? &&
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
+
1171
1210
def visit_blockarg ( node )
1172
1211
current_iseq . argument_options [ :block_start ] = current_iseq . argument_size
1173
1212
current_iseq . local_table . block_proxy ( node . name . value . to_sym )
@@ -1184,12 +1223,14 @@ def visit_call(node)
1184
1223
# First we're going to check if we're calling a method on an array
1185
1224
# literal without any arguments. In that case there are some
1186
1225
# 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 ) )
1188
1228
case node . receiver
1189
1229
when ArrayLiteral
1190
1230
parts = node . receiver . contents &.parts || [ ]
1191
1231
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?
1193
1234
case node . message . value
1194
1235
when "max"
1195
1236
visit ( node . receiver . contents )
@@ -1215,13 +1256,10 @@ def visit_call(node)
1215
1256
end
1216
1257
end
1217
1258
1218
- if node . receiver
1219
- visit ( node . receiver )
1220
- else
1221
- builder . putself
1222
- end
1259
+ node . receiver ? visit ( node . receiver ) : builder . putself
1223
1260
1224
1261
visit ( node . arguments )
1262
+ block_iseq = visit ( node . block ) if node . respond_to? ( :block ) && node . block
1225
1263
1226
1264
if arg_parts . last . is_a? ( ArgBlock )
1227
1265
flag = node . receiver . nil? ? VM_CALL_FCALL : 0
@@ -1235,7 +1273,12 @@ def visit_call(node)
1235
1273
flag |= VM_CALL_KW_SPLAT
1236
1274
end
1237
1275
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
+ )
1239
1282
else
1240
1283
flag = 0
1241
1284
arg_parts . each do |arg_part |
@@ -1247,9 +1290,14 @@ def visit_call(node)
1247
1290
end
1248
1291
end
1249
1292
1250
- flag |= VM_CALL_ARGS_SIMPLE if flag == 0
1293
+ flag |= VM_CALL_ARGS_SIMPLE if block_iseq . nil? && flag == 0
1251
1294
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
+ )
1253
1301
end
1254
1302
end
1255
1303
@@ -1291,23 +1339,25 @@ def visit_class(node)
1291
1339
1292
1340
def visit_command ( node )
1293
1341
visit_call (
1294
- CallNode . new (
1342
+ CommandCall . new (
1295
1343
receiver : nil ,
1296
1344
operator : nil ,
1297
1345
message : node . message ,
1298
1346
arguments : node . arguments ,
1347
+ block : node . block ,
1299
1348
location : node . location
1300
1349
)
1301
1350
)
1302
1351
end
1303
1352
1304
1353
def visit_command_call ( node )
1305
1354
visit_call (
1306
- CallNode . new (
1355
+ CommandCall . new (
1307
1356
receiver : node . receiver ,
1308
1357
operator : node . operator ,
1309
1358
message : node . message ,
1310
1359
arguments : node . arguments ,
1360
+ block : node . block ,
1311
1361
location : node . location
1312
1362
)
1313
1363
)
@@ -1537,6 +1587,19 @@ def visit_label(node)
1537
1587
builder . putobject ( node . accept ( RubyVisitor . new ) )
1538
1588
end
1539
1589
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
+
1540
1603
def visit_module ( node )
1541
1604
name = node . constant . constant . value . to_sym
1542
1605
module_iseq =
@@ -1898,11 +1961,12 @@ def visit_unary(node)
1898
1961
end
1899
1962
1900
1963
visit_call (
1901
- CallNode . new (
1964
+ CommandCall . new (
1902
1965
receiver : node . statement ,
1903
1966
operator : nil ,
1904
1967
message : Ident . new ( value : method_id , location : Location . default ) ,
1905
1968
arguments : nil ,
1969
+ block : nil ,
1906
1970
location : Location . default
1907
1971
)
1908
1972
)
0 commit comments