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,249 @@
1
+ module Furnace::AVM2
2
+ module Transform
3
+ class CFGReduce
4
+ def transform(cfg)
5
+ @cfg = cfg
6
+
7
+ @dom = @cfg.dominators
8
+ @loops = @cfg.identify_loops
9
+
10
+ @visited = Set.new
11
+ @loop_tails = {}
12
+ @loop_nonlocal = Set.new
13
+
14
+ ast, = extended_block(@cfg.entry)
15
+
16
+ ast
17
+ end
18
+
19
+ def extended_block(block, stopgap=nil, loop_stack=[])
20
+ nodes = []
21
+
22
+ while block
23
+ if @loops.include?(block) && loop_stack.include?(block)
24
+ # We have just arrived to loop head. Insert `continue'
25
+ # and exit.
26
+ check_nonlocal_loop(loop_stack, block) do |params|
27
+ nodes << AST::Node.new(:continue, params)
28
+ end
29
+ break
30
+ elsif @loop_tails.include?(block) &&
31
+ loop_stack.include?(@loop_tails[block])
32
+ # We have just arrived to loop tail. Insert `break'
33
+ # and exit.
34
+ loop = @loop_tails[block]
35
+ check_nonlocal_loop(loop_stack, loop) do |params|
36
+ nodes << AST::Node.new(:break, params)
37
+ end
38
+ break
39
+ elsif block == stopgap
40
+ # We have just arrived to a merge point of `if'
41
+ # contidional. Exit.
42
+ break
43
+ end
44
+
45
+ if @visited.include? block
46
+ raise "failsafe: block #{block.label} already visited"
47
+ elsif block != @cfg.exit
48
+ @visited.add block
49
+ end
50
+
51
+ block.insns.each do |insn|
52
+ next if insn == block.cti
53
+ nodes << insn
54
+ end
55
+
56
+ if block.cti
57
+ if @loops.include?(block)
58
+ # we're trapped in a strange loop
59
+ reverse = !block.cti.children[0]
60
+ in_root, out_root = block.targets
61
+
62
+ # One of the branch targets should reside within
63
+ # the loop.
64
+ if !@loops[block].include?(in_root)
65
+ in_root, out_root = out_root, in_root
66
+ reverse = !reverse
67
+ end
68
+
69
+ # Mark the loop tail so we could detect `break' and
70
+ # `continue' statements.
71
+ @loop_tails[out_root] = block
72
+
73
+ # If we reversed the roots or it was a (jump-if false),
74
+ # then reverse the condition.
75
+ expr = normalize_cti_expr(block, reverse)
76
+
77
+ body = extended_block(in_root, nil, [ block, *loop_stack ])
78
+
79
+ # [(label name)]
80
+ # We first parse the body and then add the label before
81
+ # the loop body if anything in the body requires that label
82
+ # to be present.
83
+ if @loop_nonlocal.include?(block)
84
+ nodes << AST::Node.new(:label, [ loop_label(block) ])
85
+ end
86
+
87
+ # (while (condition)
88
+ # (body ...))
89
+ # (for-in '(var name) # to be done
90
+ # (body ...))
91
+ nodes << AST::Node.new(:while, [
92
+ expr,
93
+ body
94
+ ])
95
+
96
+ block = out_root
97
+ else
98
+ # this is an `if', `break' or `continue'
99
+ reverse = !block.cti.children[0]
100
+ left_root, right_root = block.targets
101
+
102
+ # (if (condition)
103
+ # (if-true ...)
104
+ # [(if-false ...)])
105
+ # Note that you cannot reach expression if-true nor
106
+ # expression if-false without evaluating condition.
107
+ # Thus, to go inside the if body, a root has to be
108
+ # completely dominated by this block--that is, does
109
+ # not have edges coming to it even from other blocks
110
+ # dominated by this block.
111
+
112
+ # If the left root isn't dominated by block,
113
+ # then it can't be `if' branch.
114
+ if !completely_dominated?(left_root, block)
115
+ left_root, right_root = right_root, left_root
116
+ reverse = !reverse
117
+ end
118
+
119
+ # If the left root still isn't dominated by block,
120
+ # then this is not a proper conditional.
121
+ unless completely_dominated?(left_root, block)
122
+ raise "not-well-formed if"
123
+ end
124
+
125
+ # If the right root is dominated by this block, which
126
+ # means that we have an `else' part, and if the condition
127
+ # is reversed, turn that back. This serves purely aesthetical
128
+ # purposes and depends on behavior of ASC code generator.
129
+ if completely_dominated?(right_root, block) && reverse
130
+ left_root, right_root = right_root, left_root
131
+ reverse = false
132
+ end
133
+
134
+ # If we reversed the roots or it was a (jump-if false),
135
+ # then reverse the condition.
136
+ expr = normalize_cti_expr(block, reverse)
137
+
138
+ # Does this conditional have an `else' block?
139
+ if completely_dominated?(right_root, block)
140
+ # Yes. Find a merge point.
141
+ merge = find_merge_point(block, left_root, right_root, loop_stack)
142
+
143
+ # If the merge search did not yield a valid node, use
144
+ # stopgap for the current block to avoid runaway code
145
+ # synthesis.
146
+ #
147
+ # The stopgap block is actually an innermost block from
148
+ # a stopgap block set implicitly represented by a set of
149
+ # objects contained in arguments of recursive calls. As
150
+ # the `if's are fully nested when well-formed, we can only
151
+ # check for collision with innermost stopgap block.
152
+ nodes << AST::Node.new(:if, [
153
+ expr,
154
+ extended_block(left_root, merge || stopgap, loop_stack),
155
+ extended_block(right_root, merge || stopgap, loop_stack)
156
+ ])
157
+
158
+ block = merge
159
+ else
160
+ # No. The "right root" is actually post-if code.
161
+ nodes << AST::Node.new(:if, [
162
+ expr,
163
+ extended_block(left_root, right_root, loop_stack)
164
+ ])
165
+
166
+ block = right_root
167
+ end
168
+ end
169
+ elsif block.targets.count == 1
170
+ block = block.targets.first
171
+ elsif block == @cfg.exit
172
+ break
173
+ else
174
+ raise "invalid target count (#{block.targets.count})"
175
+ end
176
+ end
177
+
178
+ AST::Node.new(:begin, nodes)
179
+ end
180
+
181
+ # Block B is completely dominated by another block D if
182
+ # it is dominated by D and no edges ever lead to block B
183
+ # from any other block, including those dominated by D,
184
+ # but excluding any back edges.
185
+ def completely_dominated?(block, dominator)
186
+ if @loops.include?(block)
187
+ (block.sources - @loops[block].to_a) == [dominator]
188
+ else
189
+ block.sources == [dominator]
190
+ end
191
+ end
192
+
193
+ # A merge point for blocks R (root), L (left) and D (right)
194
+ # is first block found with BFS starting at {L,D} so that
195
+ # it is dominated by R, but not L or D.
196
+ def find_merge_point(root, left, right, loop_stack)
197
+ worklist = Set[left, right]
198
+ visited = Set[root, left, right]
199
+
200
+ while worklist.any?
201
+ node = worklist.first
202
+ worklist.delete node
203
+
204
+ visited.add node
205
+
206
+ if (@dom[node].include?(root) &&
207
+ !(@dom[node].include?(left) ||
208
+ @dom[node].include?(right))) ||
209
+ loop_stack.include?(node)
210
+ return node
211
+ end
212
+
213
+ node.targets.each do |target|
214
+ next if visited.include? target
215
+ worklist.add target
216
+ end
217
+ end
218
+
219
+ # The paths have diverged.
220
+ nil
221
+ end
222
+
223
+ # Check if the control transfer is nonlocal according to the
224
+ # innermost loop and adjust @loop_nonlocal accordingly for labels
225
+ # to be inserted where appropriate.
226
+ def check_nonlocal_loop(loop_stack, block)
227
+ if loop_stack.first != block
228
+ @loop_nonlocal.add block
229
+
230
+ yield [loop_label(block)]
231
+ else
232
+ yield []
233
+ end
234
+ end
235
+
236
+ def loop_label(block)
237
+ "label#{block.label}"
238
+ end
239
+
240
+ def normalize_cti_expr(block, negate)
241
+ if negate
242
+ AST::Node.new(:!, [ block.cti.children[1] ])
243
+ else
244
+ block.cti.children[1]
245
+ end
246
+ end
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,130 @@
1
+ module Furnace::AVM2
2
+ module Transform
3
+ class NFNormalize
4
+ include AST::Visitor
5
+
6
+ def transform(nf)
7
+ @nf = nf.normalize_hierarchy!
8
+
9
+ remove_useless_return
10
+ visit @nf
11
+
12
+ @nf
13
+ end
14
+
15
+ def remove_useless_return
16
+ if @nf.children.last.type == :return_void
17
+ @nf.children.slice! -1
18
+ end
19
+ end
20
+
21
+ COERCE_MAP = {
22
+ :coerce_a => :any,
23
+ :coerce_b => :bool,
24
+ :coerce_s => :string,
25
+ }
26
+
27
+ def on_coerce_imm(node)
28
+ expr, = node.children
29
+ node.update(:coerce, [
30
+ COERCE_MAP[node.type],
31
+ expr
32
+ ])
33
+ end
34
+ alias :on_coerce_a :on_coerce_imm
35
+ alias :on_coerce_b :on_coerce_imm
36
+ alias :on_coerce_s :on_coerce_imm
37
+
38
+ CONVERT_MAP = {
39
+ :convert_i => :integer,
40
+ :convert_u => :unsigned,
41
+ :convert_d => :double,
42
+ :convert_s => :string,
43
+ :convert_o => :object,
44
+ }
45
+
46
+ def on_convert_imm(node)
47
+ expr, = node.children
48
+ node.update(:convert, [
49
+ CONVERT_MAP[node.type],
50
+ expr
51
+ ])
52
+ end
53
+ alias :on_convert_i :on_convert_imm
54
+ alias :on_convert_u :on_convert_imm
55
+ alias :on_convert_d :on_convert_imm
56
+ alias :on_convert_s :on_convert_imm
57
+ alias :on_convert_o :on_convert_imm
58
+
59
+ ForInMatcher = AST::Matcher.new do
60
+ [:while,
61
+ [:has_next2, capture(:object_reg), capture(:index_reg)],
62
+ [:begin,
63
+ [:set_local, capture(:value_reg),
64
+ [either[:coerce, :convert], capture(:value_type),
65
+ [capture(:iterator),
66
+ [:get_local, backref(:object_reg)],
67
+ [:get_local, backref(:index_reg)]]]],
68
+ capture_rest(:body)]]
69
+ end
70
+
71
+ ForInIndexMatcher = AST::Matcher.new do
72
+ [:set_local, backref(:index_reg), [:integer, 0]]
73
+ end
74
+
75
+ ForInObjectMatcher = AST::Matcher.new do
76
+ [:set_local, backref(:object_reg),
77
+ [:coerce, :any,
78
+ capture(:root)]]
79
+ end
80
+
81
+ SuperfluousContinueMatcher = AST::Matcher.new do
82
+ [:continue]
83
+ end
84
+
85
+ def on_while(node)
86
+ if captures = ForInMatcher.match(node)
87
+ parent = node.parent
88
+
89
+ case captures[:iterator]
90
+ when :next_name
91
+ type = :for_in
92
+ when :next_value
93
+ type = :for_each_in
94
+ else
95
+ return
96
+ end
97
+
98
+ index_node = object_node = nil
99
+
100
+ loop_index = parent.children.index(node)
101
+ parent.children[0..loop_index].reverse_each do |parent_node|
102
+ if ForInIndexMatcher.match(parent_node, captures)
103
+ index_node = parent_node
104
+ elsif ForInObjectMatcher.match(parent_node, captures)
105
+ object_node = parent_node
106
+ end
107
+
108
+ break if index_node && object_node
109
+ end
110
+
111
+ return unless index_node && object_node
112
+
113
+ index_node.update(:remove)
114
+ object_node.update(:remove)
115
+
116
+ if SuperfluousContinueMatcher.match captures[:body].last
117
+ captures[:body].slice! -1
118
+ end
119
+
120
+ node.update(type, [
121
+ captures[:value_reg],
122
+ captures[:value_type],
123
+ captures[:object_reg],
124
+ AST::Node.new(:begin, captures[:body])
125
+ ])
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,3 +1,5 @@
1
- module Furnace::AVM2
2
- VERSION = "0.0.9"
1
+ module Furnace
2
+ module AVM2
3
+ VERSION = "0.9.0"
4
+ end
3
5
  end
@@ -0,0 +1,239 @@
1
+ package test {
2
+ class Literal {
3
+ function test() {
4
+ call(1, 1, 200, 200, -1, -50, 32767, 32768, -32760, -500000);
5
+ }
6
+ }
7
+
8
+ class Arithmetics {
9
+ function b() {
10
+ var a:int = 0;
11
+ var b:int;
12
+ b = (a += 1);
13
+ return (b -= (a += 1));
14
+ }
15
+
16
+ function a() {
17
+ var a:int = 0;
18
+ var b:int = ++a;
19
+ var c:int = a++;
20
+ return a;
21
+ }
22
+ }
23
+
24
+ class Logic {
25
+ function P_a_or_b_p_and_P_c_and_d_p_or_e(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
26
+ var v:Boolean = (a || b) && (c && d) || e;
27
+ away();
28
+ return v;
29
+ }
30
+
31
+ function a_or_b(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
32
+ if(a || b) {
33
+ yes();
34
+ } else {
35
+ no();
36
+ }
37
+ }
38
+
39
+ function a_and_b_and_c(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
40
+ return a && (b && c);
41
+ }
42
+
43
+ function P_a_and_b_p_and_c(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
44
+ return (a && b) && c;
45
+ }
46
+
47
+ function a_and_b(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
48
+ return a && b;
49
+ }
50
+ }
51
+
52
+ class Ternary {
53
+ function hardcore(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
54
+ if(((a && b) ? (c || d) && e : b) && (a || b)) {
55
+ return pow();
56
+ } else {
57
+ weeee();
58
+ }
59
+ duh();
60
+ }
61
+ function q(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
62
+ return ((a ? b : c) ? (b ? c : d) : (c ? d : e));
63
+ }
64
+ function a_I_b_E_c_I_d_E_e(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
65
+ return a ? b : (c ? d : e);
66
+ }
67
+ function a_I_b_I_c_E_d_E_e(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
68
+ return a ? (b ? c : d) : e;
69
+ }
70
+ function a_I_b_E_c(a: Boolean, b:Boolean, c:Boolean, d:Boolean, e:Boolean) : Boolean {
71
+ return (1 > 2) ? b : c;
72
+ }
73
+ }
74
+
75
+ class Conditionals {
76
+ function els(param1:Object, param2:String, param3:String) : Boolean {
77
+ var _loc_4:Object = null;
78
+ if (param1 != null)
79
+ {
80
+ _loc_4 = param1[param2];
81
+ if (_loc_4 != null)
82
+ {
83
+ if (_loc_4[param3] != null)
84
+ {
85
+ return true;
86
+ }
87
+ a();
88
+ }
89
+ b();
90
+ }
91
+ heys();
92
+ return false;
93
+ }
94
+
95
+ function els2(param1:Object, param2:String, param3:String) : Boolean {
96
+ var _loc_4:Object = null;
97
+ if (param1 != null)
98
+ {
99
+ _loc_4 = param1[param2];
100
+ if (_loc_4 != null)
101
+ {
102
+ if (_loc_4[param3] != null)
103
+ {
104
+ return true;
105
+ }
106
+ }
107
+ }
108
+ heys();
109
+ return false;
110
+ }
111
+
112
+ function b(a:Boolean) {
113
+ if(a)
114
+ return foo();
115
+ else
116
+ return 1;
117
+ }
118
+
119
+ function q(a:Boolean, b:Boolean) {
120
+ if(b) {
121
+ if(a) {
122
+ foo();
123
+ }
124
+ }
125
+ baz();
126
+ }
127
+
128
+ function a(a:Boolean) {
129
+ baz();
130
+ if(a) {
131
+ foge();
132
+ } else {
133
+ huga();
134
+ }
135
+ piyo();
136
+ }
137
+
138
+ function nested(a:Boolean, b:Boolean) {
139
+ if(a) {
140
+ foo();
141
+ } else {
142
+ if(b) {
143
+ bar();
144
+ } else {
145
+ baz();
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ class Loops {
152
+ function e(f:Boolean) {
153
+ do { f = tttest();
154
+ } while(f);
155
+ }
156
+
157
+ function d() {
158
+ while(true) {
159
+ pow();
160
+ if(frak()) { a(); break; b(); }
161
+ weee();
162
+ }
163
+ }
164
+
165
+ function b() {
166
+ weee();
167
+ for(var q:int = 1; q > 0; q++) {
168
+ frak();
169
+ }
170
+ }
171
+ }
172
+
173
+ class Switch {
174
+ function proper_switch(q:int):Boolean {
175
+ switch(q) {
176
+ case 0x10:
177
+ hoge();
178
+ break;
179
+ case "test":
180
+ fuga();
181
+ break;
182
+ case 0x30:
183
+ piyo();
184
+ break;
185
+ case 0x40:
186
+ fuck();
187
+ break;
188
+ }
189
+ return false;
190
+ }
191
+
192
+ function improper_switch(q:int):Boolean {
193
+ switch(q) {
194
+ case 0x10:
195
+ hoge();
196
+ case 0x20:
197
+ fuga();
198
+ break;
199
+ case 0x30:
200
+ piyo();
201
+ break;
202
+ default:
203
+ baz();
204
+ break;
205
+ }
206
+ return false;
207
+ }
208
+ }
209
+
210
+ class Exceptions {
211
+ function c() {
212
+ try {
213
+ hoge();
214
+ } finally {
215
+ piyo();
216
+ }
217
+ }
218
+ function b() {
219
+ try {
220
+ hoge();
221
+ throw 1;
222
+ fuga();
223
+ } catch(e: SecurityError) {
224
+ piyo(e);
225
+ }
226
+ }
227
+ function a() {
228
+ try {
229
+ hoge();
230
+ throw 1;
231
+ fuga();
232
+ } catch(e: SecurityError) {
233
+ piyo(e);
234
+ } catch(e: Error) {
235
+ throw e;
236
+ }
237
+ }
238
+ }
239
+ }