furnace-avm2 0.0.9 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +4 -3
  3. data/LICENSE +20 -0
  4. data/bin/furnace-avm2 +36 -6
  5. data/bin/furnace-avm2-decompiler +141 -0
  6. data/furnace-avm2.gemspec +2 -2
  7. data/lib/furnace-avm2.rb +1 -0
  8. data/lib/furnace-avm2/abc.rb +24 -7
  9. data/lib/furnace-avm2/abc/metadata/{option_detail.rb → default_value.rb} +5 -1
  10. data/lib/furnace-avm2/abc/metadata/initializer_body.rb +8 -0
  11. data/lib/furnace-avm2/abc/metadata/instance_info.rb +19 -4
  12. data/lib/furnace-avm2/abc/metadata/klass_info.rb +1 -4
  13. data/lib/furnace-avm2/abc/metadata/method_body_info.rb +27 -10
  14. data/lib/furnace-avm2/abc/metadata/method_info.rb +20 -13
  15. data/lib/furnace-avm2/abc/metadata/multiname_info.rb +6 -0
  16. data/lib/furnace-avm2/abc/metadata/multiname_kind_genericname.rb +8 -5
  17. data/lib/furnace-avm2/abc/metadata/multiname_kind_multiname.rb +4 -0
  18. data/lib/furnace-avm2/abc/metadata/multiname_kind_qname.rb +5 -1
  19. data/lib/furnace-avm2/abc/metadata/record_with_value.rb +90 -0
  20. data/lib/furnace-avm2/abc/metadata/script_info.rb +25 -1
  21. data/lib/furnace-avm2/abc/metadata/trait_class.rb +7 -3
  22. data/lib/furnace-avm2/abc/metadata/trait_info.rb +8 -4
  23. data/lib/furnace-avm2/abc/metadata/trait_method.rb +4 -0
  24. data/lib/furnace-avm2/abc/metadata/trait_slot.rb +5 -51
  25. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_lshift.rb +1 -1
  26. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_rshift.rb +1 -1
  27. data/lib/furnace-avm2/abc/opcodes/bitwise/as3_urshift.rb +1 -1
  28. data/lib/furnace-avm2/abc/opcodes/debug/as3_debug.rb +15 -0
  29. data/lib/furnace-avm2/abc/opcodes/debug/as3_debugfile.rb +12 -0
  30. data/lib/furnace-avm2/abc/opcodes/debug/as3_debugline.rb +12 -0
  31. data/lib/furnace-avm2/abc/opcodes/function_invocation/as3_callproplex.rb +21 -0
  32. data/lib/furnace-avm2/abc/opcodes/push_literal/as3_pushbyte.rb +1 -1
  33. data/lib/furnace-avm2/abc/opcodes/push_literal/as3_pushshort.rb +1 -1
  34. data/lib/furnace-avm2/binary/record.rb +21 -1
  35. data/lib/furnace-avm2/source/declaration_tokens/argument_declaration_token.rb +4 -0
  36. data/lib/furnace-avm2/source/declaration_tokens/arguments_token.rb +15 -0
  37. data/lib/furnace-avm2/source/declaration_tokens/callee_token.rb +72 -0
  38. data/lib/furnace-avm2/source/declaration_tokens/class_implementations_token.rb +21 -0
  39. data/lib/furnace-avm2/source/declaration_tokens/class_inheritance_token.rb +17 -0
  40. data/lib/furnace-avm2/source/declaration_tokens/class_name_token.rb +21 -0
  41. data/lib/furnace-avm2/source/declaration_tokens/class_specifiers_token.rb +12 -0
  42. data/lib/furnace-avm2/source/declaration_tokens/class_token.rb +21 -0
  43. data/lib/furnace-avm2/source/declaration_tokens/comment_token.rb +22 -0
  44. data/lib/furnace-avm2/source/declaration_tokens/constructor_specifiers_token.rb +12 -0
  45. data/lib/furnace-avm2/source/declaration_tokens/constructor_token.rb +15 -0
  46. data/lib/furnace-avm2/source/declaration_tokens/function_name_token.rb +14 -0
  47. data/lib/furnace-avm2/source/declaration_tokens/import_token.rb +17 -0
  48. data/lib/furnace-avm2/source/declaration_tokens/initialization_token.rb +7 -0
  49. data/lib/furnace-avm2/source/declaration_tokens/method_specifiers_token.rb +13 -0
  50. data/lib/furnace-avm2/source/declaration_tokens/method_token.rb +15 -0
  51. data/lib/furnace-avm2/source/declaration_tokens/multiname_token.rb +41 -0
  52. data/lib/furnace-avm2/source/declaration_tokens/namespace_name_token.rb +16 -0
  53. data/lib/furnace-avm2/source/declaration_tokens/package_name_token.rb +17 -0
  54. data/lib/furnace-avm2/source/declaration_tokens/package_token.rb +29 -0
  55. data/lib/furnace-avm2/source/declaration_tokens/rest_argument_token.rb +12 -0
  56. data/lib/furnace-avm2/source/declaration_tokens/scope_token.rb +23 -0
  57. data/lib/furnace-avm2/source/declaration_tokens/script_token.rb +14 -0
  58. data/lib/furnace-avm2/source/declaration_tokens/slot_name_token.rb +17 -0
  59. data/lib/furnace-avm2/source/declaration_tokens/slot_token.rb +23 -0
  60. data/lib/furnace-avm2/source/declaration_tokens/specifiers_token.rb +32 -0
  61. data/lib/furnace-avm2/source/declaration_tokens/token_with_traits.rb +51 -0
  62. data/lib/furnace-avm2/source/declaration_tokens/type_token.rb +7 -0
  63. data/lib/furnace-avm2/source/decompiler.rb +669 -0
  64. data/lib/furnace-avm2/source/implementation_tokens/access_token.rb +9 -0
  65. data/lib/furnace-avm2/source/implementation_tokens/array_token.rb +17 -0
  66. data/lib/furnace-avm2/source/implementation_tokens/as_token.rb +9 -0
  67. data/lib/furnace-avm2/source/implementation_tokens/assignment_token.rb +9 -0
  68. data/lib/furnace-avm2/source/implementation_tokens/binary_operator_token.rb +14 -0
  69. data/lib/furnace-avm2/source/implementation_tokens/break_token.rb +9 -0
  70. data/lib/furnace-avm2/source/implementation_tokens/call_token.rb +5 -0
  71. data/lib/furnace-avm2/source/implementation_tokens/continue_token.rb +9 -0
  72. data/lib/furnace-avm2/source/implementation_tokens/control_flow_token.rb +26 -0
  73. data/lib/furnace-avm2/source/implementation_tokens/control_transfer_token.rb +20 -0
  74. data/lib/furnace-avm2/source/implementation_tokens/delete_token.rb +9 -0
  75. data/lib/furnace-avm2/source/implementation_tokens/do_token.rb +9 -0
  76. data/lib/furnace-avm2/source/implementation_tokens/else_if_token.rb +9 -0
  77. data/lib/furnace-avm2/source/implementation_tokens/else_token.rb +22 -0
  78. data/lib/furnace-avm2/source/implementation_tokens/for_each_token.rb +9 -0
  79. data/lib/furnace-avm2/source/implementation_tokens/for_token.rb +9 -0
  80. data/lib/furnace-avm2/source/implementation_tokens/generic_specializers_token.rb +17 -0
  81. data/lib/furnace-avm2/source/implementation_tokens/generic_type_token.rb +9 -0
  82. data/lib/furnace-avm2/source/implementation_tokens/if_token.rb +9 -0
  83. data/lib/furnace-avm2/source/implementation_tokens/immediate_token.rb +14 -0
  84. data/lib/furnace-avm2/source/implementation_tokens/immediate_typename_token.rb +14 -0
  85. data/lib/furnace-avm2/source/implementation_tokens/in_token.rb +9 -0
  86. data/lib/furnace-avm2/source/implementation_tokens/index_token.rb +9 -0
  87. data/lib/furnace-avm2/source/implementation_tokens/is_complex.rb +7 -0
  88. data/lib/furnace-avm2/source/implementation_tokens/is_simple.rb +7 -0
  89. data/lib/furnace-avm2/source/implementation_tokens/is_token.rb +9 -0
  90. data/lib/furnace-avm2/source/implementation_tokens/label_declaration_token.rb +12 -0
  91. data/lib/furnace-avm2/source/implementation_tokens/label_token.rb +12 -0
  92. data/lib/furnace-avm2/source/implementation_tokens/local_variable_token.rb +7 -0
  93. data/lib/furnace-avm2/source/implementation_tokens/new_token.rb +9 -0
  94. data/lib/furnace-avm2/source/implementation_tokens/object_pair_token.rb +9 -0
  95. data/lib/furnace-avm2/source/implementation_tokens/object_token.rb +17 -0
  96. data/lib/furnace-avm2/source/implementation_tokens/parentheses_token.rb +11 -0
  97. data/lib/furnace-avm2/source/implementation_tokens/property_name_token.rb +14 -0
  98. data/lib/furnace-avm2/source/implementation_tokens/return_token.rb +16 -0
  99. data/lib/furnace-avm2/source/implementation_tokens/rtname_token.rb +9 -0
  100. data/lib/furnace-avm2/source/implementation_tokens/statement_token.rb +8 -0
  101. data/lib/furnace-avm2/source/implementation_tokens/super_token.rb +9 -0
  102. data/lib/furnace-avm2/source/implementation_tokens/switch_token.rb +9 -0
  103. data/lib/furnace-avm2/source/implementation_tokens/ternary_operator_token.rb +13 -0
  104. data/lib/furnace-avm2/source/implementation_tokens/throw_token.rb +12 -0
  105. data/lib/furnace-avm2/source/implementation_tokens/typeof_token.rb +13 -0
  106. data/lib/furnace-avm2/source/implementation_tokens/unary_operator_token.rb +14 -0
  107. data/lib/furnace-avm2/source/implementation_tokens/unary_post_operator_token.rb +14 -0
  108. data/lib/furnace-avm2/source/implementation_tokens/variable_name_token.rb +14 -0
  109. data/lib/furnace-avm2/source/implementation_tokens/while_token.rb +9 -0
  110. data/lib/furnace-avm2/transform.rb +5 -1
  111. data/lib/furnace-avm2/transform/ast_build.rb +22 -7
  112. data/lib/furnace-avm2/transform/ast_normalize.rb +61 -20
  113. data/lib/furnace-avm2/transform/cfg_build.rb +86 -0
  114. data/lib/furnace-avm2/transform/cfg_reduce.rb +249 -0
  115. data/lib/furnace-avm2/transform/nf_normalize.rb +130 -0
  116. data/lib/furnace-avm2/version.rb +4 -2
  117. data/test/basic.as +239 -0
  118. metadata +110 -38
  119. data/lib/furnace-avm2/abc/metadata/option_info.rb +0 -5
  120. data/test/exception.as +0 -29
  121. data/test/literal.as +0 -5
  122. data/test/logic.as +0 -23
  123. data/test/loops.as +0 -30
  124. data/test/number.as +0 -14
  125. data/test/switch.as +0 -38
  126. data/test/ternary.as +0 -22
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class AccessToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_between
6
+ "."
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ArrayToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_before
6
+ "[ "
7
+ end
8
+
9
+ def text_between
10
+ ", "
11
+ end
12
+
13
+ def text_after
14
+ " ]"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class AsToken < Furnace::Code::SeparatedToken
3
+ include IsComplex
4
+
5
+ def text_between
6
+ " as "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class AssignmentToken < Furnace::Code::SeparatedToken
3
+ include IsComplex
4
+
5
+ def text_between
6
+ " = "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Furnace::AVM2::Tokens
2
+ class BinaryOperatorToken < Furnace::Code::SeparatedToken
3
+ include IsComplex
4
+
5
+ def initialize(origin, children, operator, options={})
6
+ super(origin, children, options)
7
+ @operator = operator
8
+ end
9
+
10
+ def text_between
11
+ " #{@operator} "
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_transfer_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class BreakToken < ControlTransferToken
5
+ def keyword
6
+ 'break'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module Furnace::AVM2::Tokens
2
+ class CallToken < Furnace::Code::NonterminalToken
3
+ include IsSimple
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_transfer_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class ContinueToken < ControlTransferToken
5
+ def keyword
6
+ 'continue'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ControlFlowToken < Furnace::Code::NonterminalToken
3
+
4
+ def initialize(origin, condition, body, options={})
5
+ super(origin, [condition, body], options)
6
+ @condition, @body = condition, body
7
+ end
8
+
9
+ def keyword
10
+ raise "reimplement ControlFlowToken#keyword in a subclass"
11
+ end
12
+
13
+ def to_text
14
+ header = "#{keyword}(#{@condition.to_text})"
15
+ if @body.is_a? ScopeToken
16
+ "#{header} #{@body.to_text}"
17
+ else
18
+ "#{header}\n#{indent @body.to_text}"
19
+ end
20
+ end
21
+
22
+ def to_structure(options={})
23
+ structurize "#{keyword}(...) ...", options
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ControlTransferToken < Furnace::Code::SurroundedToken
3
+
4
+ def keyword
5
+ raise "reimplement ControlTransferToken#keyword in a subclass"
6
+ end
7
+
8
+ def text_before
9
+ if @children.any?
10
+ "#{keyword} "
11
+ else
12
+ "#{keyword}"
13
+ end
14
+ end
15
+
16
+ def text_after
17
+ ";\n"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class DeleteToken < Furnace::Code::SurroundedToken
3
+ include IsComplex
4
+
5
+ def text_before
6
+ "delete "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_flow_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class DoToken < ControlFlowToken
5
+ def keyword
6
+ 'do'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_flow_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class ElseIfToken < ControlFlowToken
5
+ def keyword
6
+ 'else if'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ElseToken < Furnace::Code::NonterminalToken
3
+
4
+ def initialize(origin, body, options={})
5
+ super(origin, [body], options)
6
+ @body = body
7
+ end
8
+
9
+ def to_text
10
+ header = "else"
11
+ if @body.is_a? ScopeToken
12
+ "#{header} #{@body.to_text}"
13
+ else
14
+ "#{header}\n#{indent @body.to_text}"
15
+ end
16
+ end
17
+
18
+ def to_structure(options={})
19
+ structurize "else ...", options
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_flow_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class ForEachToken < ControlFlowToken
5
+ def keyword
6
+ 'for each'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_flow_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class ForToken < ControlFlowToken
5
+ def keyword
6
+ 'for'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Furnace::AVM2::Tokens
2
+ class GenericSpecializersToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_before
6
+ "<"
7
+ end
8
+
9
+ def text_between
10
+ ", "
11
+ end
12
+
13
+ def text_after
14
+ ">"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class GenericTypeToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_between
6
+ "."
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative 'control_flow_token'
2
+
3
+ module Furnace::AVM2::Tokens
4
+ class IfToken < ControlFlowToken
5
+ def keyword
6
+ 'if'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ImmediateToken < Furnace::Code::TerminalToken
3
+ include IsSimple
4
+
5
+ def initialize(origin, value, options={})
6
+ super(origin, options)
7
+ @value = value
8
+ end
9
+
10
+ def to_text
11
+ @value.to_s
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ImmediateTypenameToken < Furnace::Code::TerminalToken
3
+ include IsSimple
4
+
5
+ def initialize(origin, value, options={})
6
+ super(origin, options)
7
+ @value = value
8
+ end
9
+
10
+ def to_text
11
+ @value
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class InToken < Furnace::Code::SeparatedToken
3
+ include IsComplex
4
+
5
+ def text_between
6
+ " in "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class IndexToken < Furnace::Code::NonterminalToken
3
+ include IsSimple
4
+
5
+ def to_text
6
+ "#{@children[0].to_text}[#{@children[1].to_text}]"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Furnace::AVM2::Tokens
2
+ module IsComplex
3
+ def complex?
4
+ true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Furnace::AVM2::Tokens
2
+ module IsSimple
3
+ def complex?
4
+ false
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class IsToken < Furnace::Code::SeparatedToken
3
+ include IsComplex
4
+
5
+ def text_between
6
+ " is "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Furnace::AVM2::Tokens
2
+ class LabelDeclarationToken < Furnace::Code::TerminalToken
3
+ def initialize(origin, value, options={})
4
+ super(origin, options)
5
+ @value = value
6
+ end
7
+
8
+ def to_text
9
+ "#{@value}: "
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Furnace::AVM2::Tokens
2
+ class LabelToken < Furnace::Code::TerminalToken
3
+ def initialize(origin, value, options={})
4
+ super(origin, options)
5
+ @value = value
6
+ end
7
+
8
+ def to_text
9
+ "#{@value}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module Furnace::AVM2::Tokens
2
+ class LocalVariableToken < Furnace::Code::SurroundedToken
3
+ def text_before
4
+ "var "
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class NewToken < Furnace::Code::SurroundedToken
3
+ include IsSimple
4
+
5
+ def text_before
6
+ "new "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ObjectPairToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_between
6
+ ": "
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ObjectToken < Furnace::Code::SeparatedToken
3
+ include IsSimple
4
+
5
+ def text_before
6
+ "{ "
7
+ end
8
+
9
+ def text_between
10
+ ", "
11
+ end
12
+
13
+ def text_after
14
+ " }"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Furnace::AVM2::Tokens
2
+ class ParenthesesToken < Furnace::Code::SurroundedToken
3
+ def text_before
4
+ "("
5
+ end
6
+
7
+ def text_after
8
+ ")"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module Furnace::AVM2::Tokens
2
+ class PropertyNameToken < Furnace::Code::TerminalToken
3
+ include IsSimple
4
+
5
+ def initialize(origin, value, options={})
6
+ super(origin, options)
7
+ @value = value
8
+ end
9
+
10
+ def to_text
11
+ @value
12
+ end
13
+ end
14
+ end