syntax_tree 5.3.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -1
  3. data/CHANGELOG.md +64 -1
  4. data/Gemfile.lock +2 -2
  5. data/README.md +28 -9
  6. data/Rakefile +12 -8
  7. data/bin/console +1 -0
  8. data/bin/whitequark +79 -0
  9. data/doc/changing_structure.md +16 -0
  10. data/lib/syntax_tree/basic_visitor.rb +44 -5
  11. data/lib/syntax_tree/cli.rb +2 -2
  12. data/lib/syntax_tree/dsl.rb +23 -11
  13. data/lib/syntax_tree/{visitor/field_visitor.rb → field_visitor.rb} +54 -55
  14. data/lib/syntax_tree/formatter.rb +1 -1
  15. data/lib/syntax_tree/index.rb +56 -54
  16. data/lib/syntax_tree/json_visitor.rb +55 -0
  17. data/lib/syntax_tree/language_server.rb +157 -2
  18. data/lib/syntax_tree/match_visitor.rb +120 -0
  19. data/lib/syntax_tree/mermaid.rb +177 -0
  20. data/lib/syntax_tree/mermaid_visitor.rb +69 -0
  21. data/lib/syntax_tree/{visitor/mutation_visitor.rb → mutation_visitor.rb} +27 -27
  22. data/lib/syntax_tree/node.rb +198 -107
  23. data/lib/syntax_tree/parser.rb +322 -118
  24. data/lib/syntax_tree/pretty_print_visitor.rb +83 -0
  25. data/lib/syntax_tree/reflection.rb +241 -0
  26. data/lib/syntax_tree/translation/parser.rb +3019 -0
  27. data/lib/syntax_tree/translation/rubocop_ast.rb +21 -0
  28. data/lib/syntax_tree/translation.rb +28 -0
  29. data/lib/syntax_tree/version.rb +1 -1
  30. data/lib/syntax_tree/with_scope.rb +244 -0
  31. data/lib/syntax_tree/yarv/basic_block.rb +53 -0
  32. data/lib/syntax_tree/yarv/calldata.rb +91 -0
  33. data/lib/syntax_tree/yarv/compiler.rb +110 -100
  34. data/lib/syntax_tree/yarv/control_flow_graph.rb +257 -0
  35. data/lib/syntax_tree/yarv/data_flow_graph.rb +338 -0
  36. data/lib/syntax_tree/yarv/decompiler.rb +1 -1
  37. data/lib/syntax_tree/yarv/disassembler.rb +104 -80
  38. data/lib/syntax_tree/yarv/instruction_sequence.rb +43 -18
  39. data/lib/syntax_tree/yarv/instructions.rb +203 -649
  40. data/lib/syntax_tree/yarv/legacy.rb +12 -24
  41. data/lib/syntax_tree/yarv/sea_of_nodes.rb +534 -0
  42. data/lib/syntax_tree/yarv.rb +18 -0
  43. data/lib/syntax_tree.rb +88 -56
  44. data/tasks/sorbet.rake +277 -0
  45. data/tasks/whitequark.rake +87 -0
  46. metadata +23 -11
  47. data/.gitmodules +0 -9
  48. data/lib/syntax_tree/language_server/inlay_hints.rb +0 -159
  49. data/lib/syntax_tree/visitor/environment.rb +0 -84
  50. data/lib/syntax_tree/visitor/json_visitor.rb +0 -55
  51. data/lib/syntax_tree/visitor/match_visitor.rb +0 -122
  52. data/lib/syntax_tree/visitor/pretty_print_visitor.rb +0 -85
  53. data/lib/syntax_tree/visitor/with_environment.rb +0 -140
@@ -2,65 +2,55 @@
2
2
 
3
3
  module SyntaxTree
4
4
  module YARV
5
- # This is an operand to various YARV instructions that represents the
6
- # information about a specific call site.
7
- class CallData
8
- CALL_ARGS_SPLAT = 1 << 0
9
- CALL_ARGS_BLOCKARG = 1 << 1
10
- CALL_FCALL = 1 << 2
11
- CALL_VCALL = 1 << 3
12
- CALL_ARGS_SIMPLE = 1 << 4
13
- CALL_BLOCKISEQ = 1 << 5
14
- CALL_KWARG = 1 << 6
15
- CALL_KW_SPLAT = 1 << 7
16
- CALL_TAILCALL = 1 << 8
17
- CALL_SUPER = 1 << 9
18
- CALL_ZSUPER = 1 << 10
19
- CALL_OPT_SEND = 1 << 11
20
- CALL_KW_SPLAT_MUT = 1 << 12
21
-
22
- attr_reader :method, :argc, :flags, :kw_arg
23
-
24
- def initialize(
25
- method,
26
- argc = 0,
27
- flags = CallData::CALL_ARGS_SIMPLE,
28
- kw_arg = nil
29
- )
30
- @method = method
31
- @argc = argc
32
- @flags = flags
33
- @kw_arg = kw_arg
5
+ # This is a base class for all YARV instructions. It provides a few
6
+ # convenience methods for working with instructions.
7
+ class Instruction
8
+ # This method creates an instruction that represents the canonical
9
+ # (non-specialized) form of this instruction. If this instruction is not
10
+ # a specialized instruction, then this method returns `self`.
11
+ def canonical
12
+ self
34
13
  end
35
14
 
36
- def flag?(mask)
37
- (flags & mask) > 0
15
+ # This returns the size of the instruction in terms of the number of slots
16
+ # it occupies in the instruction sequence. Effectively this is 1 plus the
17
+ # number of operands.
18
+ def length
19
+ 1
38
20
  end
39
21
 
40
- def to_h
41
- result = { mid: method, flag: flags, orig_argc: argc }
42
- result[:kw_arg] = kw_arg if kw_arg
43
- result
22
+ # This returns the number of values that are pushed onto the stack.
23
+ def pushes
24
+ 0
44
25
  end
45
26
 
46
- def self.from(serialized)
47
- new(
48
- serialized[:mid],
49
- serialized[:orig_argc],
50
- serialized[:flag],
51
- serialized[:kw_arg]
52
- )
27
+ # This returns the number of values that are popped off the stack.
28
+ def pops
29
+ 0
30
+ end
31
+
32
+ # This returns an array of labels.
33
+ def branch_targets
34
+ []
35
+ end
36
+
37
+ # Whether or not this instruction leaves the current frame.
38
+ def leaves?
39
+ false
53
40
  end
54
- end
55
41
 
56
- # A convenience method for creating a CallData object.
57
- def self.calldata(
58
- method,
59
- argc = 0,
60
- flags = CallData::CALL_ARGS_SIMPLE,
61
- kw_arg = nil
62
- )
63
- CallData.new(method, argc, flags, kw_arg)
42
+ # Whether or not this instruction falls through to the next instruction if
43
+ # its branching fails.
44
+ def falls_through?
45
+ false
46
+ end
47
+
48
+ # Does the instruction have side effects? Control-flow counts as a
49
+ # side-effect, as do some special-case instructions like Leave. By default
50
+ # every instruction is marked as having side effects.
51
+ def side_effects?
52
+ true
53
+ end
64
54
  end
65
55
 
66
56
  # ### Summary
@@ -76,7 +66,7 @@ module SyntaxTree
76
66
  # x[0]
77
67
  # ~~~
78
68
  #
79
- class AdjustStack
69
+ class AdjustStack < Instruction
80
70
  attr_reader :number
81
71
 
82
72
  def initialize(number)
@@ -107,14 +97,6 @@ module SyntaxTree
107
97
  number
108
98
  end
109
99
 
110
- def pushes
111
- 0
112
- end
113
-
114
- def canonical
115
- self
116
- end
117
-
118
100
  def call(vm)
119
101
  vm.pop(number)
120
102
  end
@@ -138,7 +120,7 @@ module SyntaxTree
138
120
  # "#{5}"
139
121
  # ~~~
140
122
  #
141
- class AnyToString
123
+ class AnyToString < Instruction
142
124
  def disasm(fmt)
143
125
  fmt.instruction("anytostring")
144
126
  end
@@ -155,10 +137,6 @@ module SyntaxTree
155
137
  other.is_a?(AnyToString)
156
138
  end
157
139
 
158
- def length
159
- 1
160
- end
161
-
162
140
  def pops
163
141
  2
164
142
  end
@@ -167,10 +145,6 @@ module SyntaxTree
167
145
  1
168
146
  end
169
147
 
170
- def canonical
171
- self
172
- end
173
-
174
148
  def call(vm)
175
149
  original, value = vm.pop(2)
176
150
 
@@ -198,7 +172,7 @@ module SyntaxTree
198
172
  # puts x
199
173
  # ~~~
200
174
  #
201
- class BranchIf
175
+ class BranchIf < Instruction
202
176
  attr_reader :label
203
177
 
204
178
  def initialize(label)
@@ -229,16 +203,16 @@ module SyntaxTree
229
203
  1
230
204
  end
231
205
 
232
- def pushes
233
- 0
206
+ def call(vm)
207
+ vm.jump(label) if vm.pop
234
208
  end
235
209
 
236
- def canonical
237
- self
210
+ def branch_targets
211
+ [label]
238
212
  end
239
213
 
240
- def call(vm)
241
- vm.jump(label) if vm.pop
214
+ def falls_through?
215
+ true
242
216
  end
243
217
  end
244
218
 
@@ -259,7 +233,7 @@ module SyntaxTree
259
233
  # end
260
234
  # ~~~
261
235
  #
262
- class BranchNil
236
+ class BranchNil < Instruction
263
237
  attr_reader :label
264
238
 
265
239
  def initialize(label)
@@ -290,16 +264,16 @@ module SyntaxTree
290
264
  1
291
265
  end
292
266
 
293
- def pushes
294
- 0
267
+ def call(vm)
268
+ vm.jump(label) if vm.pop.nil?
295
269
  end
296
270
 
297
- def canonical
298
- self
271
+ def branch_targets
272
+ [label]
299
273
  end
300
274
 
301
- def call(vm)
302
- vm.jump(label) if vm.pop.nil?
275
+ def falls_through?
276
+ true
303
277
  end
304
278
  end
305
279
 
@@ -319,7 +293,7 @@ module SyntaxTree
319
293
  # end
320
294
  # ~~~
321
295
  #
322
- class BranchUnless
296
+ class BranchUnless < Instruction
323
297
  attr_reader :label
324
298
 
325
299
  def initialize(label)
@@ -350,16 +324,16 @@ module SyntaxTree
350
324
  1
351
325
  end
352
326
 
353
- def pushes
354
- 0
327
+ def call(vm)
328
+ vm.jump(label) unless vm.pop
355
329
  end
356
330
 
357
- def canonical
358
- self
331
+ def branch_targets
332
+ [label]
359
333
  end
360
334
 
361
- def call(vm)
362
- vm.jump(label) unless vm.pop
335
+ def falls_through?
336
+ true
363
337
  end
364
338
  end
365
339
 
@@ -382,7 +356,7 @@ module SyntaxTree
382
356
  # evaluate(value: 3)
383
357
  # ~~~
384
358
  #
385
- class CheckKeyword
359
+ class CheckKeyword < Instruction
386
360
  attr_reader :keyword_bits_index, :keyword_index
387
361
 
388
362
  def initialize(keyword_bits_index, keyword_index)
@@ -419,18 +393,10 @@ module SyntaxTree
419
393
  3
420
394
  end
421
395
 
422
- def pops
423
- 0
424
- end
425
-
426
396
  def pushes
427
397
  1
428
398
  end
429
399
 
430
- def canonical
431
- self
432
- end
433
-
434
400
  def call(vm)
435
401
  vm.push(vm.local_get(keyword_bits_index, 0)[keyword_index])
436
402
  end
@@ -448,7 +414,7 @@ module SyntaxTree
448
414
  # foo in Foo
449
415
  # ~~~
450
416
  #
451
- class CheckMatch
417
+ class CheckMatch < Instruction
452
418
  VM_CHECKMATCH_TYPE_WHEN = 1
453
419
  VM_CHECKMATCH_TYPE_CASE = 2
454
420
  VM_CHECKMATCH_TYPE_RESCUE = 3
@@ -489,10 +455,6 @@ module SyntaxTree
489
455
  1
490
456
  end
491
457
 
492
- def canonical
493
- self
494
- end
495
-
496
458
  def call(vm)
497
459
  target, pattern = vm.pop(2)
498
460
 
@@ -536,7 +498,7 @@ module SyntaxTree
536
498
  # foo in [bar]
537
499
  # ~~~
538
500
  #
539
- class CheckType
501
+ class CheckType < Instruction
540
502
  TYPE_OBJECT = 0x01
541
503
  TYPE_CLASS = 0x02
542
504
  TYPE_MODULE = 0x03
@@ -643,10 +605,6 @@ module SyntaxTree
643
605
  2
644
606
  end
645
607
 
646
- def canonical
647
- self
648
- end
649
-
650
608
  def call(vm)
651
609
  object = vm.pop
652
610
  result =
@@ -713,7 +671,7 @@ module SyntaxTree
713
671
  # [1, *2]
714
672
  # ~~~
715
673
  #
716
- class ConcatArray
674
+ class ConcatArray < Instruction
717
675
  def disasm(fmt)
718
676
  fmt.instruction("concatarray")
719
677
  end
@@ -730,10 +688,6 @@ module SyntaxTree
730
688
  other.is_a?(ConcatArray)
731
689
  end
732
690
 
733
- def length
734
- 1
735
- end
736
-
737
691
  def pops
738
692
  2
739
693
  end
@@ -742,10 +696,6 @@ module SyntaxTree
742
696
  1
743
697
  end
744
698
 
745
- def canonical
746
- self
747
- end
748
-
749
699
  def call(vm)
750
700
  left, right = vm.pop(2)
751
701
  vm.push([*left, *right])
@@ -767,7 +717,7 @@ module SyntaxTree
767
717
  # "#{5}"
768
718
  # ~~~
769
719
  #
770
- class ConcatStrings
720
+ class ConcatStrings < Instruction
771
721
  attr_reader :number
772
722
 
773
723
  def initialize(number)
@@ -802,10 +752,6 @@ module SyntaxTree
802
752
  1
803
753
  end
804
754
 
805
- def canonical
806
- self
807
- end
808
-
809
755
  def call(vm)
810
756
  vm.push(vm.pop(number).join)
811
757
  end
@@ -826,7 +772,7 @@ module SyntaxTree
826
772
  # end
827
773
  # ~~~
828
774
  #
829
- class DefineClass
775
+ class DefineClass < Instruction
830
776
  TYPE_CLASS = 0
831
777
  TYPE_SINGLETON_CLASS = 1
832
778
  TYPE_MODULE = 2
@@ -874,10 +820,6 @@ module SyntaxTree
874
820
  1
875
821
  end
876
822
 
877
- def canonical
878
- self
879
- end
880
-
881
823
  def call(vm)
882
824
  object, superclass = vm.pop(2)
883
825
 
@@ -914,7 +856,7 @@ module SyntaxTree
914
856
  # defined?(x)
915
857
  # ~~~
916
858
  #
917
- class Defined
859
+ class Defined < Instruction
918
860
  TYPE_NIL = 1
919
861
  TYPE_IVAR = 2
920
862
  TYPE_LVAR = 3
@@ -1011,10 +953,6 @@ module SyntaxTree
1011
953
  1
1012
954
  end
1013
955
 
1014
- def canonical
1015
- self
1016
- end
1017
-
1018
956
  def call(vm)
1019
957
  object = vm.pop
1020
958
 
@@ -1069,7 +1007,7 @@ module SyntaxTree
1069
1007
  # def value = "value"
1070
1008
  # ~~~
1071
1009
  #
1072
- class DefineMethod
1010
+ class DefineMethod < Instruction
1073
1011
  attr_reader :method_name, :method_iseq
1074
1012
 
1075
1013
  def initialize(method_name, method_iseq)
@@ -1102,18 +1040,6 @@ module SyntaxTree
1102
1040
  3
1103
1041
  end
1104
1042
 
1105
- def pops
1106
- 0
1107
- end
1108
-
1109
- def pushes
1110
- 0
1111
- end
1112
-
1113
- def canonical
1114
- self
1115
- end
1116
-
1117
1043
  def call(vm)
1118
1044
  name = method_name
1119
1045
  nesting = vm.frame.nesting
@@ -1150,7 +1076,7 @@ module SyntaxTree
1150
1076
  # def self.value = "value"
1151
1077
  # ~~~
1152
1078
  #
1153
- class DefineSMethod
1079
+ class DefineSMethod < Instruction
1154
1080
  attr_reader :method_name, :method_iseq
1155
1081
 
1156
1082
  def initialize(method_name, method_iseq)
@@ -1187,14 +1113,6 @@ module SyntaxTree
1187
1113
  1
1188
1114
  end
1189
1115
 
1190
- def pushes
1191
- 0
1192
- end
1193
-
1194
- def canonical
1195
- self
1196
- end
1197
-
1198
1116
  def call(vm)
1199
1117
  name = method_name
1200
1118
  nesting = vm.frame.nesting
@@ -1227,7 +1145,7 @@ module SyntaxTree
1227
1145
  # $global = 5
1228
1146
  # ~~~
1229
1147
  #
1230
- class Dup
1148
+ class Dup < Instruction
1231
1149
  def disasm(fmt)
1232
1150
  fmt.instruction("dup")
1233
1151
  end
@@ -1244,10 +1162,6 @@ module SyntaxTree
1244
1162
  other.is_a?(Dup)
1245
1163
  end
1246
1164
 
1247
- def length
1248
- 1
1249
- end
1250
-
1251
1165
  def pops
1252
1166
  1
1253
1167
  end
@@ -1256,13 +1170,13 @@ module SyntaxTree
1256
1170
  2
1257
1171
  end
1258
1172
 
1259
- def canonical
1260
- self
1261
- end
1262
-
1263
1173
  def call(vm)
1264
1174
  vm.push(vm.stack.last.dup)
1265
1175
  end
1176
+
1177
+ def side_effects?
1178
+ false
1179
+ end
1266
1180
  end
1267
1181
 
1268
1182
  # ### Summary
@@ -1275,7 +1189,7 @@ module SyntaxTree
1275
1189
  # [true]
1276
1190
  # ~~~
1277
1191
  #
1278
- class DupArray
1192
+ class DupArray < Instruction
1279
1193
  attr_reader :object
1280
1194
 
1281
1195
  def initialize(object)
@@ -1302,18 +1216,10 @@ module SyntaxTree
1302
1216
  2
1303
1217
  end
1304
1218
 
1305
- def pops
1306
- 0
1307
- end
1308
-
1309
1219
  def pushes
1310
1220
  1
1311
1221
  end
1312
1222
 
1313
- def canonical
1314
- self
1315
- end
1316
-
1317
1223
  def call(vm)
1318
1224
  vm.push(object.dup)
1319
1225
  end
@@ -1329,7 +1235,7 @@ module SyntaxTree
1329
1235
  # { a: 1 }
1330
1236
  # ~~~
1331
1237
  #
1332
- class DupHash
1238
+ class DupHash < Instruction
1333
1239
  attr_reader :object
1334
1240
 
1335
1241
  def initialize(object)
@@ -1356,18 +1262,10 @@ module SyntaxTree
1356
1262
  2
1357
1263
  end
1358
1264
 
1359
- def pops
1360
- 0
1361
- end
1362
-
1363
1265
  def pushes
1364
1266
  1
1365
1267
  end
1366
1268
 
1367
- def canonical
1368
- self
1369
- end
1370
-
1371
1269
  def call(vm)
1372
1270
  vm.push(object.dup)
1373
1271
  end
@@ -1383,7 +1281,7 @@ module SyntaxTree
1383
1281
  # Object::X ||= true
1384
1282
  # ~~~
1385
1283
  #
1386
- class DupN
1284
+ class DupN < Instruction
1387
1285
  attr_reader :number
1388
1286
 
1389
1287
  def initialize(number)
@@ -1410,18 +1308,10 @@ module SyntaxTree
1410
1308
  2
1411
1309
  end
1412
1310
 
1413
- def pops
1414
- 0
1415
- end
1416
-
1417
1311
  def pushes
1418
1312
  number
1419
1313
  end
1420
1314
 
1421
- def canonical
1422
- self
1423
- end
1424
-
1425
1315
  def call(vm)
1426
1316
  values = vm.pop(number)
1427
1317
  vm.push(*values)
@@ -1441,7 +1331,7 @@ module SyntaxTree
1441
1331
  # x, = [true, false, nil]
1442
1332
  # ~~~
1443
1333
  #
1444
- class ExpandArray
1334
+ class ExpandArray < Instruction
1445
1335
  attr_reader :number, :flags
1446
1336
 
1447
1337
  def initialize(number, flags)
@@ -1478,10 +1368,6 @@ module SyntaxTree
1478
1368
  number
1479
1369
  end
1480
1370
 
1481
- def canonical
1482
- self
1483
- end
1484
-
1485
1371
  def call(vm)
1486
1372
  object = vm.pop
1487
1373
  object =
@@ -1539,7 +1425,7 @@ module SyntaxTree
1539
1425
  # end
1540
1426
  # ~~~
1541
1427
  #
1542
- class GetBlockParam
1428
+ class GetBlockParam < Instruction
1543
1429
  attr_reader :index, :level
1544
1430
 
1545
1431
  def initialize(index, level)
@@ -1570,18 +1456,10 @@ module SyntaxTree
1570
1456
  3
1571
1457
  end
1572
1458
 
1573
- def pops
1574
- 0
1575
- end
1576
-
1577
1459
  def pushes
1578
1460
  1
1579
1461
  end
1580
1462
 
1581
- def canonical
1582
- self
1583
- end
1584
-
1585
1463
  def call(vm)
1586
1464
  vm.push(vm.local_get(index, level))
1587
1465
  end
@@ -1602,7 +1480,7 @@ module SyntaxTree
1602
1480
  # end
1603
1481
  # ~~~
1604
1482
  #
1605
- class GetBlockParamProxy
1483
+ class GetBlockParamProxy < Instruction
1606
1484
  attr_reader :index, :level
1607
1485
 
1608
1486
  def initialize(index, level)
@@ -1636,18 +1514,10 @@ module SyntaxTree
1636
1514
  3
1637
1515
  end
1638
1516
 
1639
- def pops
1640
- 0
1641
- end
1642
-
1643
1517
  def pushes
1644
1518
  1
1645
1519
  end
1646
1520
 
1647
- def canonical
1648
- self
1649
- end
1650
-
1651
1521
  def call(vm)
1652
1522
  vm.push(vm.local_get(index, level))
1653
1523
  end
@@ -1665,7 +1535,7 @@ module SyntaxTree
1665
1535
  # @@class_variable
1666
1536
  # ~~~
1667
1537
  #
1668
- class GetClassVariable
1538
+ class GetClassVariable < Instruction
1669
1539
  attr_reader :name, :cache
1670
1540
 
1671
1541
  def initialize(name, cache)
@@ -1697,18 +1567,10 @@ module SyntaxTree
1697
1567
  3
1698
1568
  end
1699
1569
 
1700
- def pops
1701
- 0
1702
- end
1703
-
1704
1570
  def pushes
1705
1571
  1
1706
1572
  end
1707
1573
 
1708
- def canonical
1709
- self
1710
- end
1711
-
1712
1574
  def call(vm)
1713
1575
  clazz = vm.frame._self
1714
1576
  clazz = clazz.class unless clazz.is_a?(Class)
@@ -1728,7 +1590,7 @@ module SyntaxTree
1728
1590
  # Constant
1729
1591
  # ~~~
1730
1592
  #
1731
- class GetConstant
1593
+ class GetConstant < Instruction
1732
1594
  attr_reader :name
1733
1595
 
1734
1596
  def initialize(name)
@@ -1763,10 +1625,6 @@ module SyntaxTree
1763
1625
  1
1764
1626
  end
1765
1627
 
1766
- def canonical
1767
- self
1768
- end
1769
-
1770
1628
  def call(vm)
1771
1629
  const_base, allow_nil = vm.pop(2)
1772
1630
 
@@ -1798,7 +1656,7 @@ module SyntaxTree
1798
1656
  # $$
1799
1657
  # ~~~
1800
1658
  #
1801
- class GetGlobal
1659
+ class GetGlobal < Instruction
1802
1660
  attr_reader :name
1803
1661
 
1804
1662
  def initialize(name)
@@ -1825,18 +1683,10 @@ module SyntaxTree
1825
1683
  2
1826
1684
  end
1827
1685
 
1828
- def pops
1829
- 0
1830
- end
1831
-
1832
1686
  def pushes
1833
1687
  1
1834
1688
  end
1835
1689
 
1836
- def canonical
1837
- self
1838
- end
1839
-
1840
1690
  def call(vm)
1841
1691
  # Evaluating the name of the global variable because there isn't a
1842
1692
  # reflection API for global variables.
@@ -1861,7 +1711,7 @@ module SyntaxTree
1861
1711
  # @instance_variable
1862
1712
  # ~~~
1863
1713
  #
1864
- class GetInstanceVariable
1714
+ class GetInstanceVariable < Instruction
1865
1715
  attr_reader :name, :cache
1866
1716
 
1867
1717
  def initialize(name, cache)
@@ -1893,18 +1743,10 @@ module SyntaxTree
1893
1743
  3
1894
1744
  end
1895
1745
 
1896
- def pops
1897
- 0
1898
- end
1899
-
1900
1746
  def pushes
1901
1747
  1
1902
1748
  end
1903
1749
 
1904
- def canonical
1905
- self
1906
- end
1907
-
1908
1750
  def call(vm)
1909
1751
  method = Object.instance_method(:instance_variable_get)
1910
1752
  vm.push(method.bind(vm.frame._self).call(name))
@@ -1925,7 +1767,7 @@ module SyntaxTree
1925
1767
  # tap { tap { value } }
1926
1768
  # ~~~
1927
1769
  #
1928
- class GetLocal
1770
+ class GetLocal < Instruction
1929
1771
  attr_reader :index, :level
1930
1772
 
1931
1773
  def initialize(index, level)
@@ -1955,18 +1797,10 @@ module SyntaxTree
1955
1797
  3
1956
1798
  end
1957
1799
 
1958
- def pops
1959
- 0
1960
- end
1961
-
1962
1800
  def pushes
1963
1801
  1
1964
1802
  end
1965
1803
 
1966
- def canonical
1967
- self
1968
- end
1969
-
1970
1804
  def call(vm)
1971
1805
  vm.push(vm.local_get(index, level))
1972
1806
  end
@@ -1985,7 +1819,7 @@ module SyntaxTree
1985
1819
  # value
1986
1820
  # ~~~
1987
1821
  #
1988
- class GetLocalWC0
1822
+ class GetLocalWC0 < Instruction
1989
1823
  attr_reader :index
1990
1824
 
1991
1825
  def initialize(index)
@@ -2012,10 +1846,6 @@ module SyntaxTree
2012
1846
  2
2013
1847
  end
2014
1848
 
2015
- def pops
2016
- 0
2017
- end
2018
-
2019
1849
  def pushes
2020
1850
  1
2021
1851
  end
@@ -2042,7 +1872,7 @@ module SyntaxTree
2042
1872
  # self.then { value }
2043
1873
  # ~~~
2044
1874
  #
2045
- class GetLocalWC1
1875
+ class GetLocalWC1 < Instruction
2046
1876
  attr_reader :index
2047
1877
 
2048
1878
  def initialize(index)
@@ -2069,10 +1899,6 @@ module SyntaxTree
2069
1899
  2
2070
1900
  end
2071
1901
 
2072
- def pops
2073
- 0
2074
- end
2075
-
2076
1902
  def pushes
2077
1903
  1
2078
1904
  end
@@ -2096,7 +1922,7 @@ module SyntaxTree
2096
1922
  # 1 if (a == 1) .. (b == 2)
2097
1923
  # ~~~
2098
1924
  #
2099
- class GetSpecial
1925
+ class GetSpecial < Instruction
2100
1926
  SVAR_LASTLINE = 0 # $_
2101
1927
  SVAR_BACKREF = 1 # $~
2102
1928
  SVAR_FLIPFLOP_START = 2 # flipflop
@@ -2128,18 +1954,10 @@ module SyntaxTree
2128
1954
  3
2129
1955
  end
2130
1956
 
2131
- def pops
2132
- 0
2133
- end
2134
-
2135
1957
  def pushes
2136
1958
  1
2137
1959
  end
2138
1960
 
2139
- def canonical
2140
- self
2141
- end
2142
-
2143
1961
  def call(vm)
2144
1962
  case key
2145
1963
  when SVAR_LASTLINE
@@ -2163,7 +1981,7 @@ module SyntaxTree
2163
1981
  # :"#{"foo"}"
2164
1982
  # ~~~
2165
1983
  #
2166
- class Intern
1984
+ class Intern < Instruction
2167
1985
  def disasm(fmt)
2168
1986
  fmt.instruction("intern")
2169
1987
  end
@@ -2180,10 +1998,6 @@ module SyntaxTree
2180
1998
  other.is_a?(Intern)
2181
1999
  end
2182
2000
 
2183
- def length
2184
- 1
2185
- end
2186
-
2187
2001
  def pops
2188
2002
  1
2189
2003
  end
@@ -2192,10 +2006,6 @@ module SyntaxTree
2192
2006
  1
2193
2007
  end
2194
2008
 
2195
- def canonical
2196
- self
2197
- end
2198
-
2199
2009
  def call(vm)
2200
2010
  vm.push(vm.pop.to_sym)
2201
2011
  end
@@ -2215,7 +2025,7 @@ module SyntaxTree
2215
2025
  # end
2216
2026
  # ~~~
2217
2027
  #
2218
- class InvokeBlock
2028
+ class InvokeBlock < Instruction
2219
2029
  attr_reader :calldata
2220
2030
 
2221
2031
  def initialize(calldata)
@@ -2250,10 +2060,6 @@ module SyntaxTree
2250
2060
  1
2251
2061
  end
2252
2062
 
2253
- def canonical
2254
- self
2255
- end
2256
-
2257
2063
  def call(vm)
2258
2064
  vm.push(vm.frame_yield.block.call(*vm.pop(calldata.argc)))
2259
2065
  end
@@ -2273,7 +2079,7 @@ module SyntaxTree
2273
2079
  # end
2274
2080
  # ~~~
2275
2081
  #
2276
- class InvokeSuper
2082
+ class InvokeSuper < Instruction
2277
2083
  attr_reader :calldata, :block_iseq
2278
2084
 
2279
2085
  def initialize(calldata, block_iseq)
@@ -2302,10 +2108,6 @@ module SyntaxTree
2302
2108
  other.block_iseq == block_iseq
2303
2109
  end
2304
2110
 
2305
- def length
2306
- 1
2307
- end
2308
-
2309
2111
  def pops
2310
2112
  argb = (calldata.flag?(CallData::CALL_ARGS_BLOCKARG) ? 1 : 0)
2311
2113
  argb + calldata.argc + 1
@@ -2315,10 +2117,6 @@ module SyntaxTree
2315
2117
  1
2316
2118
  end
2317
2119
 
2318
- def canonical
2319
- self
2320
- end
2321
-
2322
2120
  def call(vm)
2323
2121
  block =
2324
2122
  if (iseq = block_iseq)
@@ -2358,7 +2156,7 @@ module SyntaxTree
2358
2156
  # end
2359
2157
  # ~~~
2360
2158
  #
2361
- class Jump
2159
+ class Jump < Instruction
2362
2160
  attr_reader :label
2363
2161
 
2364
2162
  def initialize(label)
@@ -2385,21 +2183,13 @@ module SyntaxTree
2385
2183
  2
2386
2184
  end
2387
2185
 
2388
- def pops
2389
- 0
2390
- end
2391
-
2392
- def pushes
2393
- 0
2394
- end
2395
-
2396
- def canonical
2397
- self
2398
- end
2399
-
2400
2186
  def call(vm)
2401
2187
  vm.jump(label)
2402
2188
  end
2189
+
2190
+ def branch_targets
2191
+ [label]
2192
+ end
2403
2193
  end
2404
2194
 
2405
2195
  # ### Summary
@@ -2412,7 +2202,7 @@ module SyntaxTree
2412
2202
  # ;;
2413
2203
  # ~~~
2414
2204
  #
2415
- class Leave
2205
+ class Leave < Instruction
2416
2206
  def disasm(fmt)
2417
2207
  fmt.instruction("leave")
2418
2208
  end
@@ -2429,10 +2219,6 @@ module SyntaxTree
2429
2219
  other.is_a?(Leave)
2430
2220
  end
2431
2221
 
2432
- def length
2433
- 1
2434
- end
2435
-
2436
2222
  def pops
2437
2223
  1
2438
2224
  end
@@ -2443,13 +2229,13 @@ module SyntaxTree
2443
2229
  0
2444
2230
  end
2445
2231
 
2446
- def canonical
2447
- self
2448
- end
2449
-
2450
2232
  def call(vm)
2451
2233
  vm.leave
2452
2234
  end
2235
+
2236
+ def leaves?
2237
+ true
2238
+ end
2453
2239
  end
2454
2240
 
2455
2241
  # ### Summary
@@ -2464,7 +2250,7 @@ module SyntaxTree
2464
2250
  # ["string"]
2465
2251
  # ~~~
2466
2252
  #
2467
- class NewArray
2253
+ class NewArray < Instruction
2468
2254
  attr_reader :number
2469
2255
 
2470
2256
  def initialize(number)
@@ -2499,10 +2285,6 @@ module SyntaxTree
2499
2285
  1
2500
2286
  end
2501
2287
 
2502
- def canonical
2503
- self
2504
- end
2505
-
2506
2288
  def call(vm)
2507
2289
  vm.push(vm.pop(number))
2508
2290
  end
@@ -2520,7 +2302,7 @@ module SyntaxTree
2520
2302
  # ["string", **{ foo: "bar" }]
2521
2303
  # ~~~
2522
2304
  #
2523
- class NewArrayKwSplat
2305
+ class NewArrayKwSplat < Instruction
2524
2306
  attr_reader :number
2525
2307
 
2526
2308
  def initialize(number)
@@ -2555,10 +2337,6 @@ module SyntaxTree
2555
2337
  1
2556
2338
  end
2557
2339
 
2558
- def canonical
2559
- self
2560
- end
2561
-
2562
2340
  def call(vm)
2563
2341
  vm.push(vm.pop(number))
2564
2342
  end
@@ -2578,7 +2356,7 @@ module SyntaxTree
2578
2356
  # end
2579
2357
  # ~~~
2580
2358
  #
2581
- class NewHash
2359
+ class NewHash < Instruction
2582
2360
  attr_reader :number
2583
2361
 
2584
2362
  def initialize(number)
@@ -2613,10 +2391,6 @@ module SyntaxTree
2613
2391
  1
2614
2392
  end
2615
2393
 
2616
- def canonical
2617
- self
2618
- end
2619
-
2620
2394
  def call(vm)
2621
2395
  vm.push(vm.pop(number).each_slice(2).to_h)
2622
2396
  end
@@ -2637,7 +2411,7 @@ module SyntaxTree
2637
2411
  # p (x..y), (x...y)
2638
2412
  # ~~~
2639
2413
  #
2640
- class NewRange
2414
+ class NewRange < Instruction
2641
2415
  attr_reader :exclude_end
2642
2416
 
2643
2417
  def initialize(exclude_end)
@@ -2672,10 +2446,6 @@ module SyntaxTree
2672
2446
  1
2673
2447
  end
2674
2448
 
2675
- def canonical
2676
- self
2677
- end
2678
-
2679
2449
  def call(vm)
2680
2450
  vm.push(Range.new(*vm.pop(2), exclude_end == 1))
2681
2451
  end
@@ -2692,7 +2462,7 @@ module SyntaxTree
2692
2462
  # raise rescue true
2693
2463
  # ~~~
2694
2464
  #
2695
- class Nop
2465
+ class Nop < Instruction
2696
2466
  def disasm(fmt)
2697
2467
  fmt.instruction("nop")
2698
2468
  end
@@ -2705,27 +2475,15 @@ module SyntaxTree
2705
2475
  {}
2706
2476
  end
2707
2477
 
2708
- def ==(other)
2709
- other.is_a?(Nop)
2710
- end
2711
-
2712
- def length
2713
- 1
2714
- end
2715
-
2716
- def pops
2717
- 0
2718
- end
2719
-
2720
- def pushes
2721
- 0
2478
+ def ==(other)
2479
+ other.is_a?(Nop)
2722
2480
  end
2723
2481
 
2724
- def canonical
2725
- self
2482
+ def call(vm)
2726
2483
  end
2727
2484
 
2728
- def call(vm)
2485
+ def side_effects?
2486
+ false
2729
2487
  end
2730
2488
  end
2731
2489
 
@@ -2743,7 +2501,7 @@ module SyntaxTree
2743
2501
  # "#{5}"
2744
2502
  # ~~~
2745
2503
  #
2746
- class ObjToString
2504
+ class ObjToString < Instruction
2747
2505
  attr_reader :calldata
2748
2506
 
2749
2507
  def initialize(calldata)
@@ -2778,10 +2536,6 @@ module SyntaxTree
2778
2536
  1
2779
2537
  end
2780
2538
 
2781
- def canonical
2782
- self
2783
- end
2784
-
2785
2539
  def call(vm)
2786
2540
  vm.push(vm.pop.to_s)
2787
2541
  end
@@ -2800,7 +2554,7 @@ module SyntaxTree
2800
2554
  # END { puts "END" }
2801
2555
  # ~~~
2802
2556
  #
2803
- class Once
2557
+ class Once < Instruction
2804
2558
  attr_reader :iseq, :cache
2805
2559
 
2806
2560
  def initialize(iseq, cache)
@@ -2829,18 +2583,10 @@ module SyntaxTree
2829
2583
  3
2830
2584
  end
2831
2585
 
2832
- def pops
2833
- 0
2834
- end
2835
-
2836
2586
  def pushes
2837
2587
  1
2838
2588
  end
2839
2589
 
2840
- def canonical
2841
- self
2842
- end
2843
-
2844
2590
  def call(vm)
2845
2591
  return if @executed
2846
2592
  vm.push(vm.run_block_frame(iseq, vm.frame))
@@ -2861,7 +2607,7 @@ module SyntaxTree
2861
2607
  # 2 & 3
2862
2608
  # ~~~
2863
2609
  #
2864
- class OptAnd
2610
+ class OptAnd < Instruction
2865
2611
  attr_reader :calldata
2866
2612
 
2867
2613
  def initialize(calldata)
@@ -2917,7 +2663,7 @@ module SyntaxTree
2917
2663
  # 7[2]
2918
2664
  # ~~~
2919
2665
  #
2920
- class OptAref
2666
+ class OptAref < Instruction
2921
2667
  attr_reader :calldata
2922
2668
 
2923
2669
  def initialize(calldata)
@@ -2974,7 +2720,7 @@ module SyntaxTree
2974
2720
  # { 'test' => true }['test']
2975
2721
  # ~~~
2976
2722
  #
2977
- class OptArefWith
2723
+ class OptArefWith < Instruction
2978
2724
  attr_reader :object, :calldata
2979
2725
 
2980
2726
  def initialize(object, calldata)
@@ -3014,10 +2760,6 @@ module SyntaxTree
3014
2760
  1
3015
2761
  end
3016
2762
 
3017
- def canonical
3018
- self
3019
- end
3020
-
3021
2763
  def call(vm)
3022
2764
  vm.push(vm.pop[object])
3023
2765
  end
@@ -3036,7 +2778,7 @@ module SyntaxTree
3036
2778
  # {}[:key] = value
3037
2779
  # ~~~
3038
2780
  #
3039
- class OptAset
2781
+ class OptAset < Instruction
3040
2782
  attr_reader :calldata
3041
2783
 
3042
2784
  def initialize(calldata)
@@ -3092,7 +2834,7 @@ module SyntaxTree
3092
2834
  # {}["key"] = value
3093
2835
  # ~~~
3094
2836
  #
3095
- class OptAsetWith
2837
+ class OptAsetWith < Instruction
3096
2838
  attr_reader :object, :calldata
3097
2839
 
3098
2840
  def initialize(object, calldata)
@@ -3132,10 +2874,6 @@ module SyntaxTree
3132
2874
  1
3133
2875
  end
3134
2876
 
3135
- def canonical
3136
- self
3137
- end
3138
-
3139
2877
  def call(vm)
3140
2878
  hash, value = vm.pop(2)
3141
2879
  vm.push(hash[object] = value)
@@ -3165,7 +2903,7 @@ module SyntaxTree
3165
2903
  # end
3166
2904
  # ~~~
3167
2905
  #
3168
- class OptCaseDispatch
2906
+ class OptCaseDispatch < Instruction
3169
2907
  attr_reader :case_dispatch_hash, :else_label
3170
2908
 
3171
2909
  def initialize(case_dispatch_hash, else_label)
@@ -3206,16 +2944,16 @@ module SyntaxTree
3206
2944
  1
3207
2945
  end
3208
2946
 
3209
- def pushes
3210
- 0
2947
+ def call(vm)
2948
+ vm.jump(case_dispatch_hash.fetch(vm.pop, else_label))
3211
2949
  end
3212
2950
 
3213
- def canonical
3214
- self
2951
+ def branch_targets
2952
+ case_dispatch_hash.values.push(else_label)
3215
2953
  end
3216
2954
 
3217
- def call(vm)
3218
- vm.jump(case_dispatch_hash.fetch(vm.pop, else_label))
2955
+ def falls_through?
2956
+ true
3219
2957
  end
3220
2958
  end
3221
2959
 
@@ -3232,7 +2970,7 @@ module SyntaxTree
3232
2970
  # 2 / 3
3233
2971
  # ~~~
3234
2972
  #
3235
- class OptDiv
2973
+ class OptDiv < Instruction
3236
2974
  attr_reader :calldata
3237
2975
 
3238
2976
  def initialize(calldata)
@@ -3288,7 +3026,7 @@ module SyntaxTree
3288
3026
  # "".empty?
3289
3027
  # ~~~
3290
3028
  #
3291
- class OptEmptyP
3029
+ class OptEmptyP < Instruction
3292
3030
  attr_reader :calldata
3293
3031
 
3294
3032
  def initialize(calldata)
@@ -3345,7 +3083,7 @@ module SyntaxTree
3345
3083
  # 2 == 2
3346
3084
  # ~~~
3347
3085
  #
3348
- class OptEq
3086
+ class OptEq < Instruction
3349
3087
  attr_reader :calldata
3350
3088
 
3351
3089
  def initialize(calldata)
@@ -3402,7 +3140,7 @@ module SyntaxTree
3402
3140
  # 4 >= 3
3403
3141
  # ~~~
3404
3142
  #
3405
- class OptGE
3143
+ class OptGE < Instruction
3406
3144
  attr_reader :calldata
3407
3145
 
3408
3146
  def initialize(calldata)
@@ -3458,7 +3196,7 @@ module SyntaxTree
3458
3196
  # ::Object
3459
3197
  # ~~~
3460
3198
  #
3461
- class OptGetConstantPath
3199
+ class OptGetConstantPath < Instruction
3462
3200
  attr_reader :names
3463
3201
 
3464
3202
  def initialize(names)
@@ -3486,18 +3224,10 @@ module SyntaxTree
3486
3224
  2
3487
3225
  end
3488
3226
 
3489
- def pops
3490
- 0
3491
- end
3492
-
3493
3227
  def pushes
3494
3228
  1
3495
3229
  end
3496
3230
 
3497
- def canonical
3498
- self
3499
- end
3500
-
3501
3231
  def call(vm)
3502
3232
  current = vm.frame._self
3503
3233
  current = current.class unless current.is_a?(Class)
@@ -3523,7 +3253,7 @@ module SyntaxTree
3523
3253
  # 4 > 3
3524
3254
  # ~~~
3525
3255
  #
3526
- class OptGT
3256
+ class OptGT < Instruction
3527
3257
  attr_reader :calldata
3528
3258
 
3529
3259
  def initialize(calldata)
@@ -3580,7 +3310,7 @@ module SyntaxTree
3580
3310
  # 3 <= 4
3581
3311
  # ~~~
3582
3312
  #
3583
- class OptLE
3313
+ class OptLE < Instruction
3584
3314
  attr_reader :calldata
3585
3315
 
3586
3316
  def initialize(calldata)
@@ -3637,7 +3367,7 @@ module SyntaxTree
3637
3367
  # "".length
3638
3368
  # ~~~
3639
3369
  #
3640
- class OptLength
3370
+ class OptLength < Instruction
3641
3371
  attr_reader :calldata
3642
3372
 
3643
3373
  def initialize(calldata)
@@ -3694,7 +3424,7 @@ module SyntaxTree
3694
3424
  # 3 < 4
3695
3425
  # ~~~
3696
3426
  #
3697
- class OptLT
3427
+ class OptLT < Instruction
3698
3428
  attr_reader :calldata
3699
3429
 
3700
3430
  def initialize(calldata)
@@ -3751,7 +3481,7 @@ module SyntaxTree
3751
3481
  # "" << 2
3752
3482
  # ~~~
3753
3483
  #
3754
- class OptLTLT
3484
+ class OptLTLT < Instruction
3755
3485
  attr_reader :calldata
3756
3486
 
3757
3487
  def initialize(calldata)
@@ -3809,7 +3539,7 @@ module SyntaxTree
3809
3539
  # 3 - 2
3810
3540
  # ~~~
3811
3541
  #
3812
- class OptMinus
3542
+ class OptMinus < Instruction
3813
3543
  attr_reader :calldata
3814
3544
 
3815
3545
  def initialize(calldata)
@@ -3866,7 +3596,7 @@ module SyntaxTree
3866
3596
  # 4 % 2
3867
3597
  # ~~~
3868
3598
  #
3869
- class OptMod
3599
+ class OptMod < Instruction
3870
3600
  attr_reader :calldata
3871
3601
 
3872
3602
  def initialize(calldata)
@@ -3923,7 +3653,7 @@ module SyntaxTree
3923
3653
  # 3 * 2
3924
3654
  # ~~~
3925
3655
  #
3926
- class OptMult
3656
+ class OptMult < Instruction
3927
3657
  attr_reader :calldata
3928
3658
 
3929
3659
  def initialize(calldata)
@@ -3982,7 +3712,7 @@ module SyntaxTree
3982
3712
  # 2 != 2
3983
3713
  # ~~~
3984
3714
  #
3985
- class OptNEq
3715
+ class OptNEq < Instruction
3986
3716
  attr_reader :eq_calldata, :neq_calldata
3987
3717
 
3988
3718
  def initialize(eq_calldata, neq_calldata)
@@ -4022,10 +3752,6 @@ module SyntaxTree
4022
3752
  1
4023
3753
  end
4024
3754
 
4025
- def canonical
4026
- self
4027
- end
4028
-
4029
3755
  def call(vm)
4030
3756
  receiver, argument = vm.pop(2)
4031
3757
  vm.push(receiver != argument)
@@ -4044,7 +3770,7 @@ module SyntaxTree
4044
3770
  # [a, b, c].max
4045
3771
  # ~~~
4046
3772
  #
4047
- class OptNewArrayMax
3773
+ class OptNewArrayMax < Instruction
4048
3774
  attr_reader :number
4049
3775
 
4050
3776
  def initialize(number)
@@ -4079,10 +3805,6 @@ module SyntaxTree
4079
3805
  1
4080
3806
  end
4081
3807
 
4082
- def canonical
4083
- self
4084
- end
4085
-
4086
3808
  def call(vm)
4087
3809
  vm.push(vm.pop(number).max)
4088
3810
  end
@@ -4100,7 +3822,7 @@ module SyntaxTree
4100
3822
  # [a, b, c].min
4101
3823
  # ~~~
4102
3824
  #
4103
- class OptNewArrayMin
3825
+ class OptNewArrayMin < Instruction
4104
3826
  attr_reader :number
4105
3827
 
4106
3828
  def initialize(number)
@@ -4135,10 +3857,6 @@ module SyntaxTree
4135
3857
  1
4136
3858
  end
4137
3859
 
4138
- def canonical
4139
- self
4140
- end
4141
-
4142
3860
  def call(vm)
4143
3861
  vm.push(vm.pop(number).min)
4144
3862
  end
@@ -4157,7 +3875,7 @@ module SyntaxTree
4157
3875
  # "".nil?
4158
3876
  # ~~~
4159
3877
  #
4160
- class OptNilP
3878
+ class OptNilP < Instruction
4161
3879
  attr_reader :calldata
4162
3880
 
4163
3881
  def initialize(calldata)
@@ -4212,7 +3930,7 @@ module SyntaxTree
4212
3930
  # !true
4213
3931
  # ~~~
4214
3932
  #
4215
- class OptNot
3933
+ class OptNot < Instruction
4216
3934
  attr_reader :calldata
4217
3935
 
4218
3936
  def initialize(calldata)
@@ -4269,7 +3987,7 @@ module SyntaxTree
4269
3987
  # 2 | 3
4270
3988
  # ~~~
4271
3989
  #
4272
- class OptOr
3990
+ class OptOr < Instruction
4273
3991
  attr_reader :calldata
4274
3992
 
4275
3993
  def initialize(calldata)
@@ -4326,7 +4044,7 @@ module SyntaxTree
4326
4044
  # 2 + 3
4327
4045
  # ~~~
4328
4046
  #
4329
- class OptPlus
4047
+ class OptPlus < Instruction
4330
4048
  attr_reader :calldata
4331
4049
 
4332
4050
  def initialize(calldata)
@@ -4382,7 +4100,7 @@ module SyntaxTree
4382
4100
  # /a/ =~ "a"
4383
4101
  # ~~~
4384
4102
  #
4385
- class OptRegExpMatch2
4103
+ class OptRegExpMatch2 < Instruction
4386
4104
  attr_reader :calldata
4387
4105
 
4388
4106
  def initialize(calldata)
@@ -4438,7 +4156,7 @@ module SyntaxTree
4438
4156
  # puts "Hello, world!"
4439
4157
  # ~~~
4440
4158
  #
4441
- class OptSendWithoutBlock
4159
+ class OptSendWithoutBlock < Instruction
4442
4160
  attr_reader :calldata
4443
4161
 
4444
4162
  def initialize(calldata)
@@ -4495,7 +4213,7 @@ module SyntaxTree
4495
4213
  # "".size
4496
4214
  # ~~~
4497
4215
  #
4498
- class OptSize
4216
+ class OptSize < Instruction
4499
4217
  attr_reader :calldata
4500
4218
 
4501
4219
  def initialize(calldata)
@@ -4551,7 +4269,7 @@ module SyntaxTree
4551
4269
  # "hello".freeze
4552
4270
  # ~~~
4553
4271
  #
4554
- class OptStrFreeze
4272
+ class OptStrFreeze < Instruction
4555
4273
  attr_reader :object, :calldata
4556
4274
 
4557
4275
  def initialize(object, calldata)
@@ -4583,18 +4301,10 @@ module SyntaxTree
4583
4301
  3
4584
4302
  end
4585
4303
 
4586
- def pops
4587
- 0
4588
- end
4589
-
4590
4304
  def pushes
4591
4305
  1
4592
4306
  end
4593
4307
 
4594
- def canonical
4595
- self
4596
- end
4597
-
4598
4308
  def call(vm)
4599
4309
  vm.push(object.freeze)
4600
4310
  end
@@ -4612,7 +4322,7 @@ module SyntaxTree
4612
4322
  # -"string"
4613
4323
  # ~~~
4614
4324
  #
4615
- class OptStrUMinus
4325
+ class OptStrUMinus < Instruction
4616
4326
  attr_reader :object, :calldata
4617
4327
 
4618
4328
  def initialize(object, calldata)
@@ -4644,18 +4354,10 @@ module SyntaxTree
4644
4354
  3
4645
4355
  end
4646
4356
 
4647
- def pops
4648
- 0
4649
- end
4650
-
4651
4357
  def pushes
4652
4358
  1
4653
4359
  end
4654
4360
 
4655
- def canonical
4656
- self
4657
- end
4658
-
4659
4361
  def call(vm)
4660
4362
  vm.push(-object)
4661
4363
  end
@@ -4674,7 +4376,7 @@ module SyntaxTree
4674
4376
  # "".succ
4675
4377
  # ~~~
4676
4378
  #
4677
- class OptSucc
4379
+ class OptSucc < Instruction
4678
4380
  attr_reader :calldata
4679
4381
 
4680
4382
  def initialize(calldata)
@@ -4728,7 +4430,7 @@ module SyntaxTree
4728
4430
  # a ||= 2
4729
4431
  # ~~~
4730
4432
  #
4731
- class Pop
4433
+ class Pop < Instruction
4732
4434
  def disasm(fmt)
4733
4435
  fmt.instruction("pop")
4734
4436
  end
@@ -4745,25 +4447,17 @@ module SyntaxTree
4745
4447
  other.is_a?(Pop)
4746
4448
  end
4747
4449
 
4748
- def length
4749
- 1
4750
- end
4751
-
4752
4450
  def pops
4753
4451
  1
4754
4452
  end
4755
4453
 
4756
- def pushes
4757
- 0
4758
- end
4759
-
4760
- def canonical
4761
- self
4762
- end
4763
-
4764
4454
  def call(vm)
4765
4455
  vm.pop
4766
4456
  end
4457
+
4458
+ def side_effects?
4459
+ false
4460
+ end
4767
4461
  end
4768
4462
 
4769
4463
  # ### Summary
@@ -4776,7 +4470,7 @@ module SyntaxTree
4776
4470
  # nil
4777
4471
  # ~~~
4778
4472
  #
4779
- class PutNil
4473
+ class PutNil < Instruction
4780
4474
  def disasm(fmt)
4781
4475
  fmt.instruction("putnil")
4782
4476
  end
@@ -4793,14 +4487,6 @@ module SyntaxTree
4793
4487
  other.is_a?(PutNil)
4794
4488
  end
4795
4489
 
4796
- def length
4797
- 1
4798
- end
4799
-
4800
- def pops
4801
- 0
4802
- end
4803
-
4804
4490
  def pushes
4805
4491
  1
4806
4492
  end
@@ -4812,6 +4498,10 @@ module SyntaxTree
4812
4498
  def call(vm)
4813
4499
  canonical.call(vm)
4814
4500
  end
4501
+
4502
+ def side_effects?
4503
+ false
4504
+ end
4815
4505
  end
4816
4506
 
4817
4507
  # ### Summary
@@ -4824,7 +4514,7 @@ module SyntaxTree
4824
4514
  # 5
4825
4515
  # ~~~
4826
4516
  #
4827
- class PutObject
4517
+ class PutObject < Instruction
4828
4518
  attr_reader :object
4829
4519
 
4830
4520
  def initialize(object)
@@ -4851,21 +4541,17 @@ module SyntaxTree
4851
4541
  2
4852
4542
  end
4853
4543
 
4854
- def pops
4855
- 0
4856
- end
4857
-
4858
4544
  def pushes
4859
4545
  1
4860
4546
  end
4861
4547
 
4862
- def canonical
4863
- self
4864
- end
4865
-
4866
4548
  def call(vm)
4867
4549
  vm.push(object)
4868
4550
  end
4551
+
4552
+ def side_effects?
4553
+ false
4554
+ end
4869
4555
  end
4870
4556
 
4871
4557
  # ### Summary
@@ -4880,7 +4566,7 @@ module SyntaxTree
4880
4566
  # 0
4881
4567
  # ~~~
4882
4568
  #
4883
- class PutObjectInt2Fix0
4569
+ class PutObjectInt2Fix0 < Instruction
4884
4570
  def disasm(fmt)
4885
4571
  fmt.instruction("putobject_INT2FIX_0_")
4886
4572
  end
@@ -4897,14 +4583,6 @@ module SyntaxTree
4897
4583
  other.is_a?(PutObjectInt2Fix0)
4898
4584
  end
4899
4585
 
4900
- def length
4901
- 1
4902
- end
4903
-
4904
- def pops
4905
- 0
4906
- end
4907
-
4908
4586
  def pushes
4909
4587
  1
4910
4588
  end
@@ -4916,6 +4594,10 @@ module SyntaxTree
4916
4594
  def call(vm)
4917
4595
  canonical.call(vm)
4918
4596
  end
4597
+
4598
+ def side_effects?
4599
+ false
4600
+ end
4919
4601
  end
4920
4602
 
4921
4603
  # ### Summary
@@ -4930,7 +4612,7 @@ module SyntaxTree
4930
4612
  # 1
4931
4613
  # ~~~
4932
4614
  #
4933
- class PutObjectInt2Fix1
4615
+ class PutObjectInt2Fix1 < Instruction
4934
4616
  def disasm(fmt)
4935
4617
  fmt.instruction("putobject_INT2FIX_1_")
4936
4618
  end
@@ -4947,14 +4629,6 @@ module SyntaxTree
4947
4629
  other.is_a?(PutObjectInt2Fix1)
4948
4630
  end
4949
4631
 
4950
- def length
4951
- 1
4952
- end
4953
-
4954
- def pops
4955
- 0
4956
- end
4957
-
4958
4632
  def pushes
4959
4633
  1
4960
4634
  end
@@ -4966,6 +4640,10 @@ module SyntaxTree
4966
4640
  def call(vm)
4967
4641
  canonical.call(vm)
4968
4642
  end
4643
+
4644
+ def side_effects?
4645
+ false
4646
+ end
4969
4647
  end
4970
4648
 
4971
4649
  # ### Summary
@@ -4978,7 +4656,7 @@ module SyntaxTree
4978
4656
  # puts "Hello, world!"
4979
4657
  # ~~~
4980
4658
  #
4981
- class PutSelf
4659
+ class PutSelf < Instruction
4982
4660
  def disasm(fmt)
4983
4661
  fmt.instruction("putself")
4984
4662
  end
@@ -4995,25 +4673,17 @@ module SyntaxTree
4995
4673
  other.is_a?(PutSelf)
4996
4674
  end
4997
4675
 
4998
- def length
4999
- 1
5000
- end
5001
-
5002
- def pops
5003
- 0
5004
- end
5005
-
5006
4676
  def pushes
5007
4677
  1
5008
4678
  end
5009
4679
 
5010
- def canonical
5011
- self
5012
- end
5013
-
5014
4680
  def call(vm)
5015
4681
  vm.push(vm.frame._self)
5016
4682
  end
4683
+
4684
+ def side_effects?
4685
+ false
4686
+ end
5017
4687
  end
5018
4688
 
5019
4689
  # ### Summary
@@ -5028,7 +4698,7 @@ module SyntaxTree
5028
4698
  # alias foo bar
5029
4699
  # ~~~
5030
4700
  #
5031
- class PutSpecialObject
4701
+ class PutSpecialObject < Instruction
5032
4702
  OBJECT_VMCORE = 1
5033
4703
  OBJECT_CBASE = 2
5034
4704
  OBJECT_CONST_BASE = 3
@@ -5059,18 +4729,10 @@ module SyntaxTree
5059
4729
  2
5060
4730
  end
5061
4731
 
5062
- def pops
5063
- 0
5064
- end
5065
-
5066
4732
  def pushes
5067
4733
  1
5068
4734
  end
5069
4735
 
5070
- def canonical
5071
- self
5072
- end
5073
-
5074
4736
  def call(vm)
5075
4737
  case object
5076
4738
  when OBJECT_VMCORE
@@ -5095,7 +4757,7 @@ module SyntaxTree
5095
4757
  # "foo"
5096
4758
  # ~~~
5097
4759
  #
5098
- class PutString
4760
+ class PutString < Instruction
5099
4761
  attr_reader :object
5100
4762
 
5101
4763
  def initialize(object)
@@ -5122,18 +4784,10 @@ module SyntaxTree
5122
4784
  2
5123
4785
  end
5124
4786
 
5125
- def pops
5126
- 0
5127
- end
5128
-
5129
4787
  def pushes
5130
4788
  1
5131
4789
  end
5132
4790
 
5133
- def canonical
5134
- self
5135
- end
5136
-
5137
4791
  def call(vm)
5138
4792
  vm.push(object.dup)
5139
4793
  end
@@ -5152,7 +4806,7 @@ module SyntaxTree
5152
4806
  # "hello".tap { |i| p i }
5153
4807
  # ~~~
5154
4808
  #
5155
- class Send
4809
+ class Send < Instruction
5156
4810
  attr_reader :calldata, :block_iseq
5157
4811
 
5158
4812
  def initialize(calldata, block_iseq)
@@ -5194,10 +4848,6 @@ module SyntaxTree
5194
4848
  1
5195
4849
  end
5196
4850
 
5197
- def canonical
5198
- self
5199
- end
5200
-
5201
4851
  def call(vm)
5202
4852
  block =
5203
4853
  if (iseq = block_iseq)
@@ -5240,7 +4890,7 @@ module SyntaxTree
5240
4890
  # end
5241
4891
  # ~~~
5242
4892
  #
5243
- class SetBlockParam
4893
+ class SetBlockParam < Instruction
5244
4894
  attr_reader :index, :level
5245
4895
 
5246
4896
  def initialize(index, level)
@@ -5275,14 +4925,6 @@ module SyntaxTree
5275
4925
  1
5276
4926
  end
5277
4927
 
5278
- def pushes
5279
- 0
5280
- end
5281
-
5282
- def canonical
5283
- self
5284
- end
5285
-
5286
4928
  def call(vm)
5287
4929
  vm.local_set(index, level, vm.pop)
5288
4930
  end
@@ -5301,7 +4943,7 @@ module SyntaxTree
5301
4943
  # @@class_variable = 1
5302
4944
  # ~~~
5303
4945
  #
5304
- class SetClassVariable
4946
+ class SetClassVariable < Instruction
5305
4947
  attr_reader :name, :cache
5306
4948
 
5307
4949
  def initialize(name, cache)
@@ -5337,14 +4979,6 @@ module SyntaxTree
5337
4979
  1
5338
4980
  end
5339
4981
 
5340
- def pushes
5341
- 0
5342
- end
5343
-
5344
- def canonical
5345
- self
5346
- end
5347
-
5348
4982
  def call(vm)
5349
4983
  clazz = vm.frame._self
5350
4984
  clazz = clazz.class unless clazz.is_a?(Class)
@@ -5363,7 +4997,7 @@ module SyntaxTree
5363
4997
  # Constant = 1
5364
4998
  # ~~~
5365
4999
  #
5366
- class SetConstant
5000
+ class SetConstant < Instruction
5367
5001
  attr_reader :name
5368
5002
 
5369
5003
  def initialize(name)
@@ -5394,14 +5028,6 @@ module SyntaxTree
5394
5028
  2
5395
5029
  end
5396
5030
 
5397
- def pushes
5398
- 0
5399
- end
5400
-
5401
- def canonical
5402
- self
5403
- end
5404
-
5405
5031
  def call(vm)
5406
5032
  value, parent = vm.pop(2)
5407
5033
  parent.const_set(name, value)
@@ -5419,7 +5045,7 @@ module SyntaxTree
5419
5045
  # $global = 5
5420
5046
  # ~~~
5421
5047
  #
5422
- class SetGlobal
5048
+ class SetGlobal < Instruction
5423
5049
  attr_reader :name
5424
5050
 
5425
5051
  def initialize(name)
@@ -5450,14 +5076,6 @@ module SyntaxTree
5450
5076
  1
5451
5077
  end
5452
5078
 
5453
- def pushes
5454
- 0
5455
- end
5456
-
5457
- def canonical
5458
- self
5459
- end
5460
-
5461
5079
  def call(vm)
5462
5080
  # Evaluating the name of the global variable because there isn't a
5463
5081
  # reflection API for global variables.
@@ -5481,7 +5099,7 @@ module SyntaxTree
5481
5099
  # @instance_variable = 1
5482
5100
  # ~~~
5483
5101
  #
5484
- class SetInstanceVariable
5102
+ class SetInstanceVariable < Instruction
5485
5103
  attr_reader :name, :cache
5486
5104
 
5487
5105
  def initialize(name, cache)
@@ -5517,14 +5135,6 @@ module SyntaxTree
5517
5135
  1
5518
5136
  end
5519
5137
 
5520
- def pushes
5521
- 0
5522
- end
5523
-
5524
- def canonical
5525
- self
5526
- end
5527
-
5528
5138
  def call(vm)
5529
5139
  method = Object.instance_method(:instance_variable_set)
5530
5140
  method.bind(vm.frame._self).call(name, vm.pop)
@@ -5545,7 +5155,7 @@ module SyntaxTree
5545
5155
  # tap { tap { value = 10 } }
5546
5156
  # ~~~
5547
5157
  #
5548
- class SetLocal
5158
+ class SetLocal < Instruction
5549
5159
  attr_reader :index, :level
5550
5160
 
5551
5161
  def initialize(index, level)
@@ -5579,14 +5189,6 @@ module SyntaxTree
5579
5189
  1
5580
5190
  end
5581
5191
 
5582
- def pushes
5583
- 0
5584
- end
5585
-
5586
- def canonical
5587
- self
5588
- end
5589
-
5590
5192
  def call(vm)
5591
5193
  vm.local_set(index, level, vm.pop)
5592
5194
  end
@@ -5605,7 +5207,7 @@ module SyntaxTree
5605
5207
  # value = 5
5606
5208
  # ~~~
5607
5209
  #
5608
- class SetLocalWC0
5210
+ class SetLocalWC0 < Instruction
5609
5211
  attr_reader :index
5610
5212
 
5611
5213
  def initialize(index)
@@ -5636,10 +5238,6 @@ module SyntaxTree
5636
5238
  1
5637
5239
  end
5638
5240
 
5639
- def pushes
5640
- 0
5641
- end
5642
-
5643
5241
  def canonical
5644
5242
  SetLocal.new(index, 0)
5645
5243
  end
@@ -5662,7 +5260,7 @@ module SyntaxTree
5662
5260
  # self.then { value = 10 }
5663
5261
  # ~~~
5664
5262
  #
5665
- class SetLocalWC1
5263
+ class SetLocalWC1 < Instruction
5666
5264
  attr_reader :index
5667
5265
 
5668
5266
  def initialize(index)
@@ -5693,10 +5291,6 @@ module SyntaxTree
5693
5291
  1
5694
5292
  end
5695
5293
 
5696
- def pushes
5697
- 0
5698
- end
5699
-
5700
5294
  def canonical
5701
5295
  SetLocal.new(index, 1)
5702
5296
  end
@@ -5717,7 +5311,7 @@ module SyntaxTree
5717
5311
  # {}[:key] = 'val'
5718
5312
  # ~~~
5719
5313
  #
5720
- class SetN
5314
+ class SetN < Instruction
5721
5315
  attr_reader :number
5722
5316
 
5723
5317
  def initialize(number)
@@ -5752,10 +5346,6 @@ module SyntaxTree
5752
5346
  1
5753
5347
  end
5754
5348
 
5755
- def canonical
5756
- self
5757
- end
5758
-
5759
5349
  def call(vm)
5760
5350
  vm.stack[-number - 1] = vm.stack.last
5761
5351
  end
@@ -5773,7 +5363,7 @@ module SyntaxTree
5773
5363
  # baz if (foo == 1) .. (bar == 1)
5774
5364
  # ~~~
5775
5365
  #
5776
- class SetSpecial
5366
+ class SetSpecial < Instruction
5777
5367
  attr_reader :key
5778
5368
 
5779
5369
  def initialize(key)
@@ -5804,14 +5394,6 @@ module SyntaxTree
5804
5394
  1
5805
5395
  end
5806
5396
 
5807
- def pushes
5808
- 0
5809
- end
5810
-
5811
- def canonical
5812
- self
5813
- end
5814
-
5815
5397
  def call(vm)
5816
5398
  case key
5817
5399
  when GetSpecial::SVAR_LASTLINE
@@ -5836,7 +5418,7 @@ module SyntaxTree
5836
5418
  # x = *(5)
5837
5419
  # ~~~
5838
5420
  #
5839
- class SplatArray
5421
+ class SplatArray < Instruction
5840
5422
  attr_reader :flag
5841
5423
 
5842
5424
  def initialize(flag)
@@ -5871,10 +5453,6 @@ module SyntaxTree
5871
5453
  1
5872
5454
  end
5873
5455
 
5874
- def canonical
5875
- self
5876
- end
5877
-
5878
5456
  def call(vm)
5879
5457
  value = vm.pop
5880
5458
 
@@ -5914,7 +5492,7 @@ module SyntaxTree
5914
5492
  # !!defined?([[]])
5915
5493
  # ~~~
5916
5494
  #
5917
- class Swap
5495
+ class Swap < Instruction
5918
5496
  def disasm(fmt)
5919
5497
  fmt.instruction("swap")
5920
5498
  end
@@ -5931,10 +5509,6 @@ module SyntaxTree
5931
5509
  other.is_a?(Swap)
5932
5510
  end
5933
5511
 
5934
- def length
5935
- 1
5936
- end
5937
-
5938
5512
  def pops
5939
5513
  2
5940
5514
  end
@@ -5943,10 +5517,6 @@ module SyntaxTree
5943
5517
  2
5944
5518
  end
5945
5519
 
5946
- def canonical
5947
- self
5948
- end
5949
-
5950
5520
  def call(vm)
5951
5521
  left, right = vm.pop(2)
5952
5522
  vm.push(right, left)
@@ -5965,7 +5535,7 @@ module SyntaxTree
5965
5535
  # [1, 2, 3].map { break 2 }
5966
5536
  # ~~~
5967
5537
  #
5968
- class Throw
5538
+ class Throw < Instruction
5969
5539
  RUBY_TAG_NONE = 0x0
5970
5540
  RUBY_TAG_RETURN = 0x1
5971
5541
  RUBY_TAG_BREAK = 0x2
@@ -6013,10 +5583,6 @@ module SyntaxTree
6013
5583
  1
6014
5584
  end
6015
5585
 
6016
- def canonical
6017
- self
6018
- end
6019
-
6020
5586
  def call(vm)
6021
5587
  state = type & VM_THROW_STATE_MASK
6022
5588
  value = vm.pop
@@ -6072,7 +5638,7 @@ module SyntaxTree
6072
5638
  # end
6073
5639
  # ~~~
6074
5640
  #
6075
- class TopN
5641
+ class TopN < Instruction
6076
5642
  attr_reader :number
6077
5643
 
6078
5644
  def initialize(number)
@@ -6099,18 +5665,10 @@ module SyntaxTree
6099
5665
  2
6100
5666
  end
6101
5667
 
6102
- def pops
6103
- 0
6104
- end
6105
-
6106
5668
  def pushes
6107
5669
  1
6108
5670
  end
6109
5671
 
6110
- def canonical
6111
- self
6112
- end
6113
-
6114
5672
  def call(vm)
6115
5673
  vm.push(vm.stack[-number - 1])
6116
5674
  end
@@ -6127,7 +5685,7 @@ module SyntaxTree
6127
5685
  # /foo #{bar}/
6128
5686
  # ~~~
6129
5687
  #
6130
- class ToRegExp
5688
+ class ToRegExp < Instruction
6131
5689
  attr_reader :options, :length
6132
5690
 
6133
5691
  def initialize(options, length)
@@ -6160,10 +5718,6 @@ module SyntaxTree
6160
5718
  1
6161
5719
  end
6162
5720
 
6163
- def canonical
6164
- self
6165
- end
6166
-
6167
5721
  def call(vm)
6168
5722
  vm.push(Regexp.new(vm.pop(length).join, options))
6169
5723
  end