furnace-avm2 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/Gemfile.lock +2 -2
  2. data/bin/furnace-avm2 +5 -1
  3. data/bin/furnace-avm2-decompiler +80 -13
  4. data/bin/furnace-avm2-shell +32 -0
  5. data/furnace-avm2.gemspec +1 -1
  6. data/lib/furnace-avm2/abc.rb +1 -7
  7. data/lib/furnace-avm2/abc/metadata/file.rb +65 -0
  8. data/lib/furnace-avm2/abc/metadata/instance_info.rb +17 -11
  9. data/lib/furnace-avm2/abc/metadata/metadata_info.rb +14 -4
  10. data/lib/furnace-avm2/abc/metadata/method_body_info.rb +11 -3
  11. data/lib/furnace-avm2/abc/metadata/method_info.rb +3 -4
  12. data/lib/furnace-avm2/abc/metadata/multiname_kind_genericname.rb +3 -2
  13. data/lib/furnace-avm2/abc/metadata/multiname_kind_multiname.rb +11 -2
  14. data/lib/furnace-avm2/abc/metadata/multiname_kind_multinamel.rb +4 -0
  15. data/lib/furnace-avm2/abc/metadata/multiname_kind_qname.rb +10 -2
  16. data/lib/furnace-avm2/abc/metadata/multiname_kind_rtqname.rb +4 -0
  17. data/lib/furnace-avm2/abc/metadata/multiname_kind_rtqnamel.rb +4 -0
  18. data/lib/furnace-avm2/abc/metadata/script_info.rb +11 -7
  19. data/lib/furnace-avm2/abc/metadata/trait_class.rb +2 -2
  20. data/lib/furnace-avm2/abc/metadata/trait_info.rb +1 -1
  21. data/lib/furnace-avm2/abc/metadata/trait_method.rb +4 -3
  22. data/lib/furnace-avm2/abc/metadata/trait_slot.rb +2 -2
  23. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_extend_1.rb +8 -0
  24. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_extend_16.rb +8 -0
  25. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_extend_8.rb +8 -0
  26. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_load_float32.rb +8 -0
  27. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_load_float64.rb +8 -0
  28. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_load_int16.rb +8 -0
  29. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_load_int32.rb +8 -0
  30. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_load_int8.rb +8 -0
  31. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_store_float32.rb +8 -0
  32. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_store_float64.rb +8 -0
  33. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_store_int16.rb +8 -0
  34. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_store_int32.rb +8 -0
  35. data/lib/furnace-avm2/abc/opcodes/alchemy/alchemy_store_int8.rb +8 -0
  36. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_add.rb +1 -1
  37. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_add_i.rb +1 -1
  38. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_declocal.rb +1 -1
  39. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_declocal_i.rb +1 -1
  40. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_decrement.rb +1 -1
  41. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_decrement_i.rb +1 -1
  42. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_divide.rb +1 -1
  43. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_equals.rb +1 -1
  44. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_greaterequals.rb +1 -1
  45. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_greaterthan.rb +1 -1
  46. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_inclocal.rb +1 -1
  47. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_inclocal_i.rb +1 -1
  48. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_increment.rb +1 -1
  49. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_increment_i.rb +1 -1
  50. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_lessequals.rb +1 -1
  51. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_lessthan.rb +1 -1
  52. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_modulo.rb +1 -1
  53. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_multiply.rb +1 -1
  54. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_multiply_i.rb +1 -1
  55. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_negate.rb +1 -1
  56. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_negate_i.rb +1 -1
  57. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_not.rb +1 -1
  58. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_strictequals.rb +1 -1
  59. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_subtract.rb +1 -1
  60. data/lib/furnace-avm2/abc/opcodes/arithmetic/as3_subtract_i.rb +1 -1
  61. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_bitand.rb +1 -1
  62. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_bitnot.rb +1 -1
  63. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_bitor.rb +1 -1
  64. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_bitxor.rb +1 -1
  65. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_lshift.rb +1 -1
  66. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_rshift.rb +1 -1
  67. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_urshift.rb +1 -1
  68. data/lib/furnace-avm2/abc/opcodes/control_transfer/as3_lookupswitch.rb +1 -1
  69. data/lib/furnace-avm2/abc/opcodes/control_transfer_opcode.rb +0 -4
  70. data/lib/furnace-avm2/abc/opcodes/exception/as3_newcatch.rb +1 -1
  71. data/lib/furnace-avm2/abc/opcodes/function_invocation/as3_callproplex.rb +4 -0
  72. data/lib/furnace-avm2/abc/opcodes/function_invocation_opcode.rb +4 -0
  73. data/lib/furnace-avm2/abc/opcodes/function_return/as3_returnvalue.rb +1 -1
  74. data/lib/furnace-avm2/abc/opcodes/function_return/as3_returnvoid.rb +1 -1
  75. data/lib/furnace-avm2/abc/opcodes/generic/as3_escxattr.rb +1 -1
  76. data/lib/furnace-avm2/abc/opcodes/generic/as3_escxelem.rb +8 -0
  77. data/lib/furnace-avm2/abc/opcodes/generic/as3_getlex.rb +4 -0
  78. data/lib/furnace-avm2/abc/opcodes/object_manipulation/as3_newfunction.rb +5 -1
  79. data/lib/furnace-avm2/abc/opcodes/property/as3_constructprop.rb +4 -0
  80. data/lib/furnace-avm2/abc/opcodes/property_opcode.rb +4 -0
  81. data/lib/furnace-avm2/abc/opcodes/push_literal/as3_pushuint.rb +11 -0
  82. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_applytype.rb +1 -1
  83. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_coerce.rb +5 -1
  84. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_coerce_a.rb +1 -1
  85. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_coerce_b.rb +1 -1
  86. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_coerce_s.rb +1 -1
  87. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_convert_d.rb +1 -1
  88. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_convert_i.rb +1 -1
  89. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_convert_o.rb +1 -1
  90. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_convert_s.rb +1 -1
  91. data/lib/furnace-avm2/abc/opcodes/type_conversion/as3_convert_u.rb +1 -1
  92. data/lib/furnace-avm2/abc/primitives/opcode_sequence.rb +35 -23
  93. data/lib/furnace-avm2/abc/primitives/record.rb +11 -0
  94. data/lib/furnace-avm2/binary/record.rb +9 -7
  95. data/lib/furnace-avm2/source/declaration_tokens/callee_token.rb +8 -5
  96. data/lib/furnace-avm2/source/declaration_tokens/class_implementations_token.rb +5 -1
  97. data/lib/furnace-avm2/source/declaration_tokens/class_specifiers_token.rb +2 -1
  98. data/lib/furnace-avm2/source/declaration_tokens/class_token.rb +5 -1
  99. data/lib/furnace-avm2/source/declaration_tokens/metadata_token.rb +25 -0
  100. data/lib/furnace-avm2/source/declaration_tokens/method_specifiers_token.rb +4 -3
  101. data/lib/furnace-avm2/source/declaration_tokens/method_token.rb +1 -0
  102. data/lib/furnace-avm2/source/declaration_tokens/multiname_token.rb +28 -13
  103. data/lib/furnace-avm2/source/declaration_tokens/package_token.rb +9 -8
  104. data/lib/furnace-avm2/source/declaration_tokens/scope_token.rb +2 -0
  105. data/lib/furnace-avm2/source/declaration_tokens/script_token.rb +4 -1
  106. data/lib/furnace-avm2/source/declaration_tokens/slot_token.rb +1 -0
  107. data/lib/furnace-avm2/source/declaration_tokens/specifiers_token.rb +11 -9
  108. data/lib/furnace-avm2/source/decompiler.rb +372 -101
  109. data/lib/furnace-avm2/source/implementation_tokens/closure_name_token.rb +7 -0
  110. data/lib/furnace-avm2/source/implementation_tokens/closure_token.rb +9 -0
  111. data/lib/furnace-avm2/source/implementation_tokens/instance_of_token.rb +9 -0
  112. data/lib/furnace-avm2/source/implementation_tokens/supplementary_comment_token.rb +16 -0
  113. data/lib/furnace-avm2/source/implementation_tokens/xml_literal_token.rb +14 -0
  114. data/lib/furnace-avm2/transform/ast_build.rb +3 -2
  115. data/lib/furnace-avm2/transform/ast_normalize.rb +39 -7
  116. data/lib/furnace-avm2/transform/cfg_build.rb +16 -6
  117. data/lib/furnace-avm2/transform/cfg_reduce.rb +4 -3
  118. data/lib/furnace-avm2/transform/nf_normalize.rb +15 -7
  119. data/lib/furnace-avm2/version.rb +1 -1
  120. data/test/basic.as +15 -0
  121. data/test/global.as +11 -0
  122. metadata +46 -29
  123. data/bin/furnace-avm2-benchmark +0 -38
  124. data/lib/furnace-avm2/abc/opcodes/arithmetic_opcode.rb +0 -4
  125. data/lib/furnace-avm2/abc/opcodes/bitwise_opcode.rb +0 -4
  126. data/lib/furnace-avm2/abc/opcodes/exception_opcode.rb +0 -4
  127. data/lib/furnace-avm2/abc/opcodes/function_return_opcode.rb +0 -4
  128. data/lib/furnace-avm2/abc/opcodes/object_manipulation_opcode.rb +0 -4
  129. data/lib/furnace-avm2/abc/opcodes/type_conversion_opcode.rb +0 -4
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3StrictEquals < ArithmeticOpcode
2
+ class AS3StrictEquals < Opcode
3
3
  instruction 0xac
4
4
  ast_type :===
5
5
 
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3Subtract < ArithmeticOpcode
2
+ class AS3Subtract < Opcode
3
3
  instruction 0xa1
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3SubtractI < ArithmeticOpcode
2
+ class AS3SubtractI < Opcode
3
3
  instruction 0xc6
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3BitAnd < BitwiseOpcode
2
+ class AS3BitAnd < Opcode
3
3
  instruction 0xa8
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3BitNot < BitwiseOpcode
2
+ class AS3BitNot < Opcode
3
3
  instruction 0x97
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3BitOr < BitwiseOpcode
2
+ class AS3BitOr < Opcode
3
3
  instruction 0xa9
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3BitXor < BitwiseOpcode
2
+ class AS3BitXor < Opcode
3
3
  instruction 0xaa
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3Lshift < BitwiseOpcode
2
+ class AS3Lshift < Opcode
3
3
  instruction 0xa5
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3Rshift < BitwiseOpcode
2
+ class AS3Rshift < Opcode
3
3
  instruction 0xa6
4
4
 
5
5
  consume 2
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3Urshift < BitwiseOpcode
2
+ class AS3Urshift < Opcode
3
3
  instruction 0xa7
4
4
 
5
5
  consume 2
@@ -14,7 +14,7 @@ module Furnace::AVM2::ABC
14
14
  attr_accessor :default_target, :case_targets
15
15
 
16
16
  def parameters
17
- [ body.default_offset ].concat(body.case_offsets)
17
+ [ @default_target.offset, @case_targets.map(&:offset) ]
18
18
  end
19
19
 
20
20
  def resolve!
@@ -16,10 +16,6 @@ module Furnace::AVM2::ABC
16
16
  body.jump_offset = new_offset - offset - byte_length
17
17
  end
18
18
 
19
- def target_offsets
20
- [ target_offset ]
21
- end
22
-
23
19
  def resolve!
24
20
  @target = @sequence.opcode_at(target_offset)
25
21
 
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3NewCatch < ExceptionOpcode
2
+ class AS3NewCatch < Opcode
3
3
  instruction 0x5a
4
4
 
5
5
  body do
@@ -17,5 +17,9 @@ module Furnace::AVM2::ABC
17
17
  def disassemble_parameters
18
18
  "#{body.property.to_s}(#{body.arg_count})"
19
19
  end
20
+
21
+ def collect_ns(options)
22
+ body.property.collect_ns(options)
23
+ end
20
24
  end
21
25
  end
@@ -13,5 +13,9 @@ module Furnace::AVM2::ABC
13
13
  def disassemble_parameters
14
14
  "#{body.property} #{body.arg_count}"
15
15
  end
16
+
17
+ def collect_ns(options)
18
+ body.property.collect_ns(options)
19
+ end
16
20
  end
17
21
  end
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ReturnValue < FunctionReturnOpcode
2
+ class AS3ReturnValue < Opcode
3
3
  instruction 0x48
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ReturnVoid < FunctionReturnOpcode
2
+ class AS3ReturnVoid < Opcode
3
3
  instruction 0x47
4
4
 
5
5
  consume 0
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3EscXAttr < Opcode
2
+ class AS3EscXattr < Opcode
3
3
  instruction 0x72
4
4
 
5
5
  consume 1
@@ -0,0 +1,8 @@
1
+ module Furnace::AVM2::ABC
2
+ class AS3EscXelem < Opcode
3
+ instruction 0x71
4
+
5
+ consume 1
6
+ produce 1
7
+ end
8
+ end
@@ -12,5 +12,9 @@ module Furnace::AVM2::ABC
12
12
  def parameters
13
13
  [ body.property.to_astlet ]
14
14
  end
15
+
16
+ def collect_ns(options)
17
+ body.property.collect_ns(options)
18
+ end
15
19
  end
16
20
  end
@@ -3,10 +3,14 @@ module Furnace::AVM2::ABC
3
3
  instruction 0x40
4
4
 
5
5
  body do
6
- vuint30 :method_index
6
+ vuint30 :method_idx
7
7
  end
8
8
 
9
9
  consume 0
10
10
  produce 1
11
+
12
+ def parameters
13
+ [ body.method_idx ]
14
+ end
11
15
  end
12
16
  end
@@ -16,5 +16,9 @@ module Furnace::AVM2::ABC
16
16
  def disassemble_parameters
17
17
  "#{body.property} #{body.arg_count}"
18
18
  end
19
+
20
+ def collect_ns(options)
21
+ body.property.collect_ns(options)
22
+ end
19
23
  end
20
24
  end
@@ -9,5 +9,9 @@ module Furnace::AVM2::ABC
9
9
  def disassemble_parameters
10
10
  body.property.to_s
11
11
  end
12
+
13
+ def collect_ns(options)
14
+ body.property.collect_ns(options)
15
+ end
12
16
  end
13
17
  end
@@ -0,0 +1,11 @@
1
+ module Furnace::AVM2::ABC
2
+ class AS3PushUint < PushLiteralOpcode
3
+ instruction 0x2e
4
+
5
+ body do
6
+ const_ref :value, :uint
7
+ end
8
+
9
+ type :integer
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ApplyType < TypeConversionOpcode
2
+ class AS3ApplyType < Opcode
3
3
  instruction 0x53
4
4
 
5
5
  body do
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3Coerce < TypeConversionOpcode
2
+ class AS3Coerce < Opcode
3
3
  instruction 0x80
4
4
 
5
5
  body do
@@ -12,5 +12,9 @@ module Furnace::AVM2::ABC
12
12
  def parameters
13
13
  [ body.type.to_astlet ]
14
14
  end
15
+
16
+ def collect_ns(options)
17
+ body.type.collect_ns(options)
18
+ end
15
19
  end
16
20
  end
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3CoerceA < TypeConversionOpcode
2
+ class AS3CoerceA < Opcode
3
3
  instruction 0x82
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3CoerceB < TypeConversionOpcode
2
+ class AS3CoerceB < Opcode
3
3
  instruction 0x76
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3CoerceS < TypeConversionOpcode
2
+ class AS3CoerceS < Opcode
3
3
  instruction 0x85
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ConvertD < TypeConversionOpcode
2
+ class AS3ConvertD < Opcode
3
3
  instruction 0x75
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ConvertI < TypeConversionOpcode
2
+ class AS3ConvertI < Opcode
3
3
  instruction 0x73
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ConvertO < TypeConversionOpcode
2
+ class AS3ConvertO < Opcode
3
3
  instruction 0x77
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ConvertS < TypeConversionOpcode
2
+ class AS3ConvertS < Opcode
3
3
  instruction 0x70
4
4
 
5
5
  consume 1
@@ -1,5 +1,5 @@
1
1
  module Furnace::AVM2::ABC
2
- class AS3ConvertU < TypeConversionOpcode
2
+ class AS3ConvertU < Opcode
3
3
  instruction 0x74
4
4
 
5
5
  consume 1
@@ -1,3 +1,5 @@
1
+ require 'stringio'
2
+
1
3
  module Furnace::AVM2::ABC
2
4
  class OpcodeSequence < ::Array
3
5
  attr_reader :root, :parent
@@ -91,44 +93,47 @@ module Furnace::AVM2::ABC
91
93
  end
92
94
  end
93
95
 
94
- if exceptions.any?
95
- exception_node = CFG::Node.new(graph, :exception, [])
96
- graph.nodes.add exception_node
96
+ pending_label = nil
97
+ pending_queue = []
98
+
99
+ cutoff = lambda do |targets|
100
+ node = CFG::Node.new(graph, pending_label, pending_queue, nil, targets)
97
101
 
98
- exceptions.each do |exception|
99
- targets << exception.target_offset
102
+ if graph.nodes.empty?
103
+ graph.entry = node
100
104
  end
105
+
106
+ graph.nodes.add node
107
+
108
+ pending_label = nil
109
+ pending_queue = []
101
110
  end
102
111
 
103
112
  each do |opcode|
104
113
  if targets.include? opcode
105
- graph.transfer({ nil => opcode.offset })
114
+ cutoff.([ opcode.offset ])
106
115
  end
107
116
 
108
- graph.expand opcode.offset, opcode
117
+ pending_label = opcode.offset if pending_label.nil?
118
+ pending_queue << opcode
109
119
 
110
120
  if opcode.is_a? ControlTransferOpcode
111
121
  if opcode.conditional
112
- graph.transfer({ true => opcode.target.offset,
113
- false => opcode.offset + opcode.byte_length })
122
+ cutoff.([ opcode.target.offset, opcode.offset + opcode.byte_length ])
114
123
  else
115
- graph.transfer({ nil => opcode.target.offset })
124
+ cutoff.([ opcode.target.offset ])
116
125
  end
117
126
  elsif opcode.is_a? AS3LookupSwitch
118
- map = { nil => opcode.default_target.offset }
119
-
120
- opcode.case_targets.each_with_index do |target, index|
121
- map[index] = target.offset
122
- end
123
-
124
- graph.transfer map
127
+ cutoff.(opcode.parameters.flatten)
125
128
  end
126
129
  end
127
130
 
128
- graph.transfer({ })
131
+ cutoff.([])
129
132
 
130
- exceptions.each do |exception|
131
- graph.edges.add CFG::Edge.new(graph, nil, :exception, exception.target_offset)
133
+ if exceptions.any?
134
+ exception_node = CFG::Node.new(graph, :exception, [], nil,
135
+ exceptions.map(&:target_offset))
136
+ graph.nodes.add exception_node
132
137
  end
133
138
 
134
139
  graph
@@ -138,9 +143,16 @@ module Furnace::AVM2::ABC
138
143
  cfg = build_cfg
139
144
  dead_opcodes = []
140
145
 
141
- cfg.nodes.each do |node|
142
- if node.label != 0 && node.entering_edges.count == 0
143
- dead_opcodes.concat node.operations
146
+ worklist = cfg.nodes.dup
147
+ while worklist.any?
148
+ node = worklist.first
149
+ worklist.delete node
150
+
151
+ next if node == cfg.entry
152
+
153
+ if node.sources.count == 0 ||
154
+ node.sources == [node]
155
+ dead_opcodes.concat node.insns
144
156
  end
145
157
  end
146
158
 
@@ -29,6 +29,17 @@ module Furnace::AVM2::ABC
29
29
  root.constant_pool.send(array)[index - 1]
30
30
  end
31
31
  end
32
+
33
+ define_method(:"#{name}=") do |value|
34
+ pool = root.constant_pool.send(array)
35
+ if value.nil?
36
+ send(:"#{field}=", 0)
37
+ elsif index = pool.index(value)
38
+ send(:"#{field}=", index + 1)
39
+ else
40
+ raise "cpool setter: no such object in cpool"
41
+ end
42
+ end
32
43
  end
33
44
  end
34
45
 
@@ -161,7 +161,7 @@ module Furnace::AVM2::Binary
161
161
  end
162
162
 
163
163
  def inspect
164
- to_hash.inspect
164
+ "AVM2Record(#{self.class.name.split("::").last})"
165
165
  end
166
166
 
167
167
  def byte_length
@@ -260,7 +260,7 @@ module Furnace::AVM2::Binary
260
260
  end
261
261
 
262
262
  def length_vint32(value, options)
263
- length_vint(value)
263
+ length_vint(value, true)
264
264
  end
265
265
 
266
266
  # vuint32
@@ -270,11 +270,11 @@ module Furnace::AVM2::Binary
270
270
  end
271
271
 
272
272
  def write_vuint32(io, value, options)
273
- write_vint(io, value, true)
273
+ write_vint(io, value, false)
274
274
  end
275
275
 
276
276
  def length_vuint32(value, options)
277
- length_vint(value)
277
+ length_vint(value, false)
278
278
  end
279
279
 
280
280
  # vuint30
@@ -284,11 +284,11 @@ module Furnace::AVM2::Binary
284
284
  end
285
285
 
286
286
  def write_vuint30(io, value, options)
287
- write_vint(io, value, true)
287
+ write_vint(io, value, false)
288
288
  end
289
289
 
290
290
  def length_vuint30(value, options)
291
- length_vint(value)
291
+ length_vint(value, false)
292
292
  end
293
293
 
294
294
  # vstring
@@ -468,7 +468,9 @@ module Furnace::AVM2::Binary
468
468
  io.write bytes.pack("C*")
469
469
  end
470
470
 
471
- def length_vint(value)
471
+ def length_vint(value, signed)
472
+ value = value & 0xffffffff
473
+
472
474
  length = 0
473
475
 
474
476
  begin