laser 0.7.0.pre1

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 (319) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +158 -0
  6. data/Rakefile +104 -0
  7. data/VERSION +1 -0
  8. data/bin/laser +7 -0
  9. data/design_docs/goals.md +57 -0
  10. data/design_docs/object_regex.md +426 -0
  11. data/design_docs/type_annotations.md +80 -0
  12. data/ext/laser/BasicBlock.cpp +572 -0
  13. data/ext/laser/BasicBlock.h +118 -0
  14. data/ext/laser/extconf.rb +3 -0
  15. data/features/laser.feature +25 -0
  16. data/features/step_definitions/laser_steps.rb +39 -0
  17. data/features/support/env.rb +14 -0
  18. data/features/support/testdata/1_input +1 -0
  19. data/features/support/testdata/1_output +1 -0
  20. data/features/support/testdata/2_input +4 -0
  21. data/features/support/testdata/2_output +4 -0
  22. data/features/support/testdata/3_input +8 -0
  23. data/features/support/testdata/3_output +11 -0
  24. data/features/support/testdata/4_input +5 -0
  25. data/features/support/testdata/4_output +5 -0
  26. data/features/support/testdata/5_input +13 -0
  27. data/laser.gemspec +382 -0
  28. data/lib/laser.rb +98 -0
  29. data/lib/laser/analysis/annotations.rb +95 -0
  30. data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
  31. data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
  32. data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
  33. data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
  34. data/lib/laser/analysis/argument_expansion.rb +132 -0
  35. data/lib/laser/analysis/arity.rb +34 -0
  36. data/lib/laser/analysis/bindings.rb +144 -0
  37. data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
  38. data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
  39. data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
  40. data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
  41. data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
  42. data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
  43. data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
  44. data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
  45. data/lib/laser/analysis/comments.rb +35 -0
  46. data/lib/laser/analysis/control_flow.rb +28 -0
  47. data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
  48. data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
  49. data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
  50. data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
  51. data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
  52. data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
  53. data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
  54. data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
  55. data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
  56. data/lib/laser/analysis/control_flow/simulation.rb +385 -0
  57. data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
  58. data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
  59. data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
  60. data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
  61. data/lib/laser/analysis/errors.rb +131 -0
  62. data/lib/laser/analysis/laser_utils.rb +18 -0
  63. data/lib/laser/analysis/lexical_analysis.rb +172 -0
  64. data/lib/laser/analysis/method_call.rb +68 -0
  65. data/lib/laser/analysis/protocol_registry.rb +30 -0
  66. data/lib/laser/analysis/scope.rb +118 -0
  67. data/lib/laser/analysis/sexp.rb +159 -0
  68. data/lib/laser/analysis/sexp_analysis.rb +40 -0
  69. data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
  70. data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
  71. data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
  72. data/lib/laser/analysis/signature.rb +76 -0
  73. data/lib/laser/analysis/special_methods/send.rb +67 -0
  74. data/lib/laser/analysis/unused_methods.rb +21 -0
  75. data/lib/laser/analysis/visitor.rb +141 -0
  76. data/lib/laser/annotation_parser/annotations.treetop +126 -0
  77. data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
  78. data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
  79. data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
  80. data/lib/laser/annotation_parser/overload.treetop +24 -0
  81. data/lib/laser/annotation_parser/overload_parser.rb +167 -0
  82. data/lib/laser/annotation_parser/parsers.rb +6 -0
  83. data/lib/laser/annotation_parser/structural.treetop +37 -0
  84. data/lib/laser/annotation_parser/structural_parser.rb +406 -0
  85. data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
  86. data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
  87. data/lib/laser/rake/task.rb +46 -0
  88. data/lib/laser/runner.rb +189 -0
  89. data/lib/laser/scanner.rb +169 -0
  90. data/lib/laser/standard_library/_thread.rb +110 -0
  91. data/lib/laser/standard_library/abbrev.rb +103 -0
  92. data/lib/laser/standard_library/array.rb +418 -0
  93. data/lib/laser/standard_library/base64.rb +91 -0
  94. data/lib/laser/standard_library/basic_object.rb +55 -0
  95. data/lib/laser/standard_library/benchmark.rb +556 -0
  96. data/lib/laser/standard_library/bignum.rb +185 -0
  97. data/lib/laser/standard_library/cgi.rb +275 -0
  98. data/lib/laser/standard_library/cgi/cookie.rb +147 -0
  99. data/lib/laser/standard_library/cgi/core.rb +791 -0
  100. data/lib/laser/standard_library/cgi/html.rb +1021 -0
  101. data/lib/laser/standard_library/cgi/session.rb +537 -0
  102. data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
  103. data/lib/laser/standard_library/cgi/util.rb +188 -0
  104. data/lib/laser/standard_library/class_definitions.rb +333 -0
  105. data/lib/laser/standard_library/comparable.rb +125 -0
  106. data/lib/laser/standard_library/complex.rb +162 -0
  107. data/lib/laser/standard_library/enumerable.rb +178 -0
  108. data/lib/laser/standard_library/exceptions.rb +135 -0
  109. data/lib/laser/standard_library/fixnum.rb +188 -0
  110. data/lib/laser/standard_library/float.rb +180 -0
  111. data/lib/laser/standard_library/hash.rb +237 -0
  112. data/lib/laser/standard_library/integer.rb +123 -0
  113. data/lib/laser/standard_library/laser_magic.rb +7 -0
  114. data/lib/laser/standard_library/nil_false_true.rb +113 -0
  115. data/lib/laser/standard_library/numbers.rb +192 -0
  116. data/lib/laser/standard_library/proc.rb +31 -0
  117. data/lib/laser/standard_library/set.rb +1348 -0
  118. data/lib/laser/standard_library/string.rb +666 -0
  119. data/lib/laser/standard_library/stringio.rb +2 -0
  120. data/lib/laser/standard_library/symbol.rb +125 -0
  121. data/lib/laser/standard_library/tsort.rb +242 -0
  122. data/lib/laser/support/acts_as_struct.rb +66 -0
  123. data/lib/laser/support/frequency.rb +55 -0
  124. data/lib/laser/support/inheritable_attributes.rb +145 -0
  125. data/lib/laser/support/module_extensions.rb +94 -0
  126. data/lib/laser/support/placeholder_object.rb +13 -0
  127. data/lib/laser/third_party/rgl/adjacency.rb +221 -0
  128. data/lib/laser/third_party/rgl/base.rb +228 -0
  129. data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
  130. data/lib/laser/third_party/rgl/condensation.rb +47 -0
  131. data/lib/laser/third_party/rgl/connected_components.rb +138 -0
  132. data/lib/laser/third_party/rgl/control_flow.rb +170 -0
  133. data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
  134. data/lib/laser/third_party/rgl/dominators.rb +124 -0
  135. data/lib/laser/third_party/rgl/dot.rb +93 -0
  136. data/lib/laser/third_party/rgl/graphxml.rb +51 -0
  137. data/lib/laser/third_party/rgl/implicit.rb +174 -0
  138. data/lib/laser/third_party/rgl/mutable.rb +117 -0
  139. data/lib/laser/third_party/rgl/rdot.rb +445 -0
  140. data/lib/laser/third_party/rgl/topsort.rb +72 -0
  141. data/lib/laser/third_party/rgl/transitivity.rb +180 -0
  142. data/lib/laser/third_party/rgl/traversal.rb +348 -0
  143. data/lib/laser/types/types.rb +433 -0
  144. data/lib/laser/version.rb +14 -0
  145. data/lib/laser/warning.rb +149 -0
  146. data/lib/laser/warning_sets/default.yml +13 -0
  147. data/lib/laser/warnings/assignment_in_condition.rb +20 -0
  148. data/lib/laser/warnings/comment_spacing.rb +31 -0
  149. data/lib/laser/warnings/extra_blank_lines.rb +30 -0
  150. data/lib/laser/warnings/extra_whitespace.rb +16 -0
  151. data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
  152. data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
  153. data/lib/laser/warnings/line_length.rb +115 -0
  154. data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
  155. data/lib/laser/warnings/operator_spacing.rb +68 -0
  156. data/lib/laser/warnings/parens_on_declaration.rb +30 -0
  157. data/lib/laser/warnings/rescue_exception.rb +42 -0
  158. data/lib/laser/warnings/semicolon.rb +25 -0
  159. data/lib/laser/warnings/sexp_errors.rb +24 -0
  160. data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
  161. data/lib/laser/warnings/useless_double_quotes.rb +38 -0
  162. data/spec/analysis_specs/annotations_spec.rb +47 -0
  163. data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
  164. data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
  165. data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
  166. data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
  167. data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
  168. data/spec/analysis_specs/bindings_spec.rb +36 -0
  169. data/spec/analysis_specs/comment_spec.rb +93 -0
  170. data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
  171. data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
  172. data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
  173. data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
  174. data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
  175. data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
  176. data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
  177. data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
  178. data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
  179. data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
  180. data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
  181. data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
  182. data/spec/analysis_specs/error_spec.rb +30 -0
  183. data/spec/analysis_specs/laser_class_spec.rb +322 -0
  184. data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
  185. data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
  186. data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
  187. data/spec/analysis_specs/scope_spec.rb +126 -0
  188. data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
  189. data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
  190. data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
  191. data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
  192. data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
  193. data/spec/analysis_specs/sexp_spec.rb +167 -0
  194. data/spec/analysis_specs/spec_helper.rb +27 -0
  195. data/spec/analysis_specs/unused_methods_spec.rb +65 -0
  196. data/spec/analysis_specs/visitor_spec.rb +64 -0
  197. data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
  198. data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
  199. data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
  200. data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
  201. data/spec/annotation_parser_specs/spec_helper.rb +1 -0
  202. data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
  203. data/spec/laser_spec.rb +14 -0
  204. data/spec/rake_specs/spec_helper.rb +1 -0
  205. data/spec/rake_specs/task_spec.rb +67 -0
  206. data/spec/runner_spec.rb +207 -0
  207. data/spec/scanner_spec.rb +75 -0
  208. data/spec/spec_helper.rb +121 -0
  209. data/spec/standard_library/exceptions_spec.rb +19 -0
  210. data/spec/standard_library/globals_spec.rb +14 -0
  211. data/spec/standard_library/set_spec.rb +31 -0
  212. data/spec/standard_library/spec_helper.rb +1 -0
  213. data/spec/standard_library/standard_library_spec.rb +302 -0
  214. data/spec/support_specs/acts_as_struct_spec.rb +94 -0
  215. data/spec/support_specs/frequency_spec.rb +23 -0
  216. data/spec/support_specs/module_extensions_spec.rb +117 -0
  217. data/spec/support_specs/spec_helper.rb +1 -0
  218. data/spec/type_specs/spec_helper.rb +1 -0
  219. data/spec/type_specs/types_spec.rb +133 -0
  220. data/spec/warning_spec.rb +95 -0
  221. data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
  222. data/spec/warning_specs/comment_spacing_spec.rb +65 -0
  223. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  224. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  225. data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
  226. data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
  227. data/spec/warning_specs/line_length_spec.rb +173 -0
  228. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  229. data/spec/warning_specs/operator_spacing_spec.rb +104 -0
  230. data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
  231. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  232. data/spec/warning_specs/semicolon_spec.rb +58 -0
  233. data/spec/warning_specs/spec_helper.rb +1 -0
  234. data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
  235. data/status_reports/2010/12/2010-12-14.md +163 -0
  236. data/status_reports/2010/12/2010-12-23.md +298 -0
  237. data/status_reports/2010/12/2010-12-24.md +6 -0
  238. data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
  239. data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
  240. data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
  241. data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
  242. data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
  243. data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
  244. data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
  245. data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
  246. data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
  247. data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
  248. data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
  249. data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
  250. data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
  251. data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
  252. data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
  253. data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
  254. data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
  255. data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
  256. data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
  257. data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
  258. data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
  259. data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
  260. data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
  261. data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
  262. data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
  263. data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
  264. data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
  265. data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
  266. data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
  267. data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
  268. data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
  269. data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
  270. data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
  271. data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
  272. data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
  273. data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
  274. data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
  275. data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
  276. data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
  277. data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
  278. data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
  279. data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
  280. data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
  281. data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
  282. data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
  283. data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
  284. data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
  285. data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
  286. data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
  287. data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
  288. data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
  289. data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
  290. data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
  291. data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
  292. data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
  293. data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
  294. data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
  295. data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
  296. data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
  297. data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
  298. data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
  299. data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
  300. data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
  301. data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
  302. data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
  303. data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
  304. data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
  305. data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
  306. data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
  307. data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
  308. data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
  309. data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
  310. data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
  311. data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
  312. data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
  313. data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
  314. data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
  315. data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
  316. data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
  317. data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
  318. data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
  319. metadata +470 -0
@@ -0,0 +1,80 @@
1
+ # The Annotation Syntax
2
+
3
+ I'll describe this first as a grammar, and then as a list of examples. The value of
4
+ each node in the parse tree is a Type. A Type, in my type system, is a set of values
5
+ that satisfy the set of constraints placed upon it. Many of these constraints are related
6
+ to the Ruby class hierarchy, but not all are. So typically, a nonterminal in this grammar
7
+ will represent the creation of a new constraint on the resulting type. Since I do not know
8
+ all possible values yet, I will have to represent this type not as the actual set of values,
9
+ but as the set of constraints themselves. I will attempt to describe the constraints in english
10
+ as comments when they are not typical constraints.
11
+
12
+ I'll be using a pseudo-flex/bison syntax.
13
+
14
+ Tokens:
15
+ /((::)?[A-Z][A-Za-z_]*)+/ -> CONSTANT
16
+ /::/ -> GLOBAL_SCOPE
17
+ /[_a-z][A-Za-z0-9_]*/ -> LOCAL_VAR_ID
18
+ /[_a-z][A-Za-z0-9_]*[?!]?/ -> METHOD_NAME
19
+
20
+ Productions:
21
+ top : "Top" { return [] } ; # empty set
22
+ self : "self" { return [SelfType.new] } ;
23
+ unknown : "_" { return [UnknownTypeConstraint.new] }
24
+ | "_" : type_expression { [UnknownTypeConstraint.new(type_expression)] }
25
+ ;
26
+
27
+ possibly_mutable_class_constraint : class_constraint '!' {
28
+ return (class_constraint << CustomAnnotationConstraint.new(:mutable, true)) }
29
+ | class_constraint
30
+ ;
31
+
32
+ class_constraint : CONSTANT {
33
+ return [ClassType.new(LookupConstant(constant.text), :covariant)] }
34
+ ;
35
+
36
+ variance_constraint : class_constraint
37
+ | class_constraint '-' {
38
+ class_constraint[0].variance = :contravariant; return class_constraint }
39
+ | class_constraint '=' {
40
+ class_constraint[0].variance = :invariant; return class_constraint }
41
+ ;
42
+
43
+ generic_class_constraint : possibly_mutable_class_constraint
44
+ | possibly_mutable_class_constraint "<" generic_type_list ">" {
45
+ class_constraint[0] = GenericType.new(
46
+ class_constraint[0].specified_class, *generic_type_list) }
47
+ ;
48
+
49
+ # no mutability in these – doesn't make sense... or does it? C++ didn't do it, but could I?
50
+ # it would mean deduplication....
51
+ generic_type_list : generic_class_constraint
52
+ | generic_type_list "," generic_class_constraint { generic_type_list << generic_class_constraint; }
53
+ ;
54
+
55
+ hash_constraint : class_constraint
56
+ | class_constraint "=>" class_constraint {
57
+ return [GenericType.new(LookupConstant("Hash"), $1[0].specified_class, $3[0].specified_class)] }
58
+ ;
59
+
60
+ union_constraint : hash_constraint { return UnionConstraint.new(hash_constraint) }
61
+ | union_constraint "|" hash_constraint {
62
+ return union_constraint | hash_constraint } # overloaded operator
63
+ | union_constraint "U" hash_constraint {
64
+ return union_constraint | hash_constraint } # overloaded operator
65
+ | union_constraint "or" hash_constraint {
66
+ return union_constraint | hash_constraint } # overloaded operator
67
+ ;
68
+
69
+
70
+ structural_constraint : "#" METHOD_NAME '(' generic_type_list ')' return_type
71
+
72
+ return_type : { return [] } # empty
73
+ | parenthesized_type_expr
74
+ | "->" parenthesized_type_expr { return parenthesized_type_expr; }
75
+
76
+ parenthesized_type_expr : nonparenthesized_type_expr
77
+ | "(" nonparenthesized_type_expr ")" { return nonparenthesized_type_expr; }
78
+ ;
79
+
80
+ type_expression : parenthesized_type_expr ;
@@ -0,0 +1,572 @@
1
+ #include "BasicBlock.h"
2
+ #include "ruby.h"
3
+
4
+ VALUE rb_mLaser;
5
+ VALUE rb_mAnalysis;
6
+ VALUE rb_mControlFlow;
7
+ VALUE rb_cBasicBlock;
8
+
9
+ using namespace Laser;
10
+
11
+ BasicBlock::BasicBlock(BasicBlock& other) {
12
+ _name = other.name();
13
+ _instructions = other.instructions();
14
+ _incoming = other.predecessors();
15
+ _outgoing = other.successors();
16
+ _cache_flags = 0;
17
+ }
18
+
19
+ void BasicBlock::join(BasicBlock *other) {
20
+ clear_cache();
21
+ other->clear_cache();
22
+ Edge *new_edge = new Edge(this, other);
23
+ _outgoing.push_back(new_edge);
24
+ other->_incoming.push_back(new_edge);
25
+ }
26
+
27
+ // Disconnects the block as the source in an edge
28
+ void BasicBlock::disconnect(BasicBlock *other) {
29
+ using namespace std;
30
+
31
+ vector<Edge*>::iterator it, it2;
32
+ for (it = _outgoing.begin(); it < _outgoing.end(); ++it) {
33
+ if ((*it)->to == other) {
34
+ for (it2 = other->_incoming.begin(); it2 < other->_incoming.end(); ++it2) {
35
+ if ((*it2)->from == this) {
36
+ Edge* ptr = *it;
37
+ _outgoing.erase(it);
38
+ other->_incoming.erase(it2);
39
+ delete ptr;
40
+
41
+ clear_cache();
42
+ other->clear_cache();
43
+ return;
44
+ }
45
+ }
46
+ break;
47
+ }
48
+ }
49
+ throw NoSuchEdgeException();
50
+ }
51
+
52
+ void BasicBlock::insert_block_on_edge(BasicBlock* successor, BasicBlock* inserted) {
53
+ using namespace std;
54
+ vector<Edge*>::iterator it, it2;
55
+ for (it = _outgoing.begin(); it < _outgoing.end(); ++it) {
56
+ if ((*it)->to == successor) {
57
+ for (it2 = successor->_incoming.begin(); it2 < successor->_incoming.end(); ++it2) {
58
+ if ((*it2)->from == this) {
59
+ Edge* old_edge = *it;
60
+ *it = new Edge(this, inserted);
61
+ *it2 = new Edge(inserted, successor);
62
+ // we should place the flags of the replaced edge on just the
63
+ // first new edge
64
+ (*it)->flags = old_edge->flags;
65
+ inserted->predecessors().push_back(*it);
66
+ inserted->successors().push_back(*it2);
67
+ delete old_edge;
68
+
69
+ clear_cache();
70
+ inserted->clear_cache();
71
+ successor->clear_cache();
72
+ return;
73
+ }
74
+ }
75
+ break;
76
+ }
77
+ }
78
+ throw NoSuchEdgeException();
79
+ }
80
+
81
+ void BasicBlock::clear_edges() {
82
+ while (!_outgoing.empty()) {
83
+ BasicBlock::Edge* edge = _outgoing.back();
84
+ disconnect(edge->to);
85
+ }
86
+ while (!_incoming.empty()) {
87
+ BasicBlock::Edge* edge = _incoming.back();
88
+ edge->from->disconnect(this);
89
+ }
90
+ }
91
+
92
+ uint8_t BasicBlock::get_flags(BasicBlock *dest) {
93
+ return edge_to(dest).flags;
94
+ }
95
+ bool BasicBlock::has_flag(BasicBlock* dest, uint8_t flag) {
96
+ return ((edge_to(dest).flags & flag) != 0);
97
+ }
98
+ void BasicBlock::add_flag(BasicBlock* dest, uint8_t flag) {
99
+ clear_cache();
100
+ dest->clear_cache();
101
+ edge_to(dest).flags |= flag;
102
+ }
103
+ void BasicBlock::set_flag(BasicBlock* dest, uint8_t flag) {
104
+ clear_cache();
105
+ dest->clear_cache();
106
+ edge_to(dest).flags = flag;
107
+ }
108
+ void BasicBlock::remove_flag(BasicBlock* dest, uint8_t flag) {
109
+ clear_cache();
110
+ dest->clear_cache();
111
+ edge_to(dest).flags &= ~flag;
112
+ }
113
+
114
+ BasicBlock::Edge& BasicBlock::edge_to(BasicBlock* dest) {
115
+ using namespace std;
116
+ for (vector<Edge*>::iterator it = _outgoing.begin(); it < _outgoing.end(); ++it) {
117
+ if ((*it)->to == dest) {
118
+ return **it;
119
+ }
120
+ }
121
+ throw NoSuchEdgeException();
122
+ }
123
+
124
+ void BasicBlock::mark() {
125
+ using namespace std;
126
+ rb_gc_mark(_instructions);
127
+ rb_gc_mark(_name);
128
+ rb_gc_mark(_post_order_number);
129
+ rb_gc_mark(_representation);
130
+ for (vector<Edge*>::iterator it = _outgoing.begin(); it < _outgoing.end(); ++it) {
131
+ BasicBlock *other = (*it)->to;
132
+ rb_gc_mark(other->representation());
133
+ }
134
+ for (vector<Edge*>::iterator it = _incoming.begin(); it < _incoming.end(); ++it) {
135
+ BasicBlock *other = (*it)->from;
136
+ rb_gc_mark(other->representation());
137
+ }
138
+ if (_cache_flags & EDGE_ALL_SUCC) {
139
+ rb_gc_mark(_cached_successors);
140
+ }
141
+ if (_cache_flags & EDGE_REAL_SUCC) {
142
+ rb_gc_mark(_cached_real_successors);
143
+ }
144
+ if (_cache_flags & EDGE_ALL_PRED) {
145
+ rb_gc_mark(_cached_predecessors);
146
+ }
147
+ if (_cache_flags & EDGE_REAL_PRED) {
148
+ rb_gc_mark(_cached_real_predecessors);
149
+ }
150
+ }
151
+
152
+ extern "C" {
153
+ #define NO_EDGE_MESSAGE "The given edge does not exist."
154
+ static void bb_mark(void* p) {
155
+ BasicBlock *block = (BasicBlock*)p;
156
+ block->mark();
157
+ }
158
+
159
+ static void bb_free(void* p) {
160
+ BasicBlock *block = (BasicBlock*)p;
161
+ block->clear_edges();
162
+ delete block;
163
+ }
164
+
165
+ static VALUE bb_alloc(VALUE klass) {
166
+ BasicBlock *block = new BasicBlock;
167
+ VALUE result = Data_Wrap_Struct(klass, bb_mark, bb_free, block);
168
+ block->set_representation(result);
169
+ return result;
170
+ }
171
+
172
+ static VALUE bb_dup(VALUE self) {
173
+ BasicBlock *block;
174
+ Data_Get_Struct(self, BasicBlock, block);
175
+ BasicBlock *result_block = new BasicBlock(*block);
176
+ VALUE result = Data_Wrap_Struct(rb_cBasicBlock, bb_mark, bb_free, result_block);
177
+ block->set_representation(result);
178
+ return result;
179
+ }
180
+
181
+ static VALUE bb_initialize(VALUE self, VALUE name) {
182
+ BasicBlock *block;
183
+ Data_Get_Struct(self, BasicBlock, block);
184
+ block->set_name(name);
185
+ return Qnil;
186
+ }
187
+
188
+ static VALUE bb_equal(VALUE self, VALUE other) {
189
+ BasicBlock *block, *other_block;
190
+ Data_Get_Struct(self, BasicBlock, block);
191
+ Data_Get_Struct(other, BasicBlock, other_block);
192
+ return (block == other_block) ? Qtrue : Qfalse;
193
+ }
194
+
195
+ static VALUE bb_eql(VALUE self, VALUE other) {
196
+ BasicBlock *block, *other_block;
197
+ Data_Get_Struct(self, BasicBlock, block);
198
+ Data_Get_Struct(other, BasicBlock, other_block);
199
+ return (block == other_block ||
200
+ (rb_str_cmp(block->name(), other_block->name()) == 0)) ? Qtrue : Qfalse;
201
+ }
202
+
203
+ static VALUE bb_neq(VALUE self, VALUE other) {
204
+ return (bb_eql(self, other)) ? Qfalse : Qtrue;
205
+ }
206
+
207
+ static VALUE bb_hash(VALUE self) {
208
+ BasicBlock *block;
209
+ Data_Get_Struct(self, BasicBlock, block);
210
+ return INT2FIX((unsigned long int)block);
211
+ }
212
+
213
+ static VALUE bb_clear_edges(VALUE self) {
214
+ BasicBlock *block;
215
+ Data_Get_Struct(self, BasicBlock, block);
216
+ try {
217
+ block->clear_edges();
218
+ } catch (BasicBlock::NoSuchEdgeException e) {
219
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
220
+ }
221
+ return self;
222
+ }
223
+
224
+ static VALUE bb_get_name(VALUE self) {
225
+ BasicBlock *block;
226
+ Data_Get_Struct(self, BasicBlock, block);
227
+ return block->name();
228
+ }
229
+
230
+ static VALUE bb_get_instructions(VALUE self) {
231
+ BasicBlock *block;
232
+ Data_Get_Struct(self, BasicBlock, block);
233
+ return block->instructions();
234
+ }
235
+
236
+ static VALUE bb_set_instructions(VALUE self, VALUE new_insns) {
237
+ BasicBlock *block;
238
+ Data_Get_Struct(self, BasicBlock, block);
239
+ block->set_instructions(new_insns);
240
+ return Qnil;
241
+ }
242
+
243
+ static VALUE bb_get_post_order_number(VALUE self) {
244
+ BasicBlock *block;
245
+ Data_Get_Struct(self, BasicBlock, block);
246
+ return block->post_order_number();
247
+ }
248
+
249
+ static VALUE bb_set_post_order_number(VALUE self, VALUE new_num) {
250
+ BasicBlock *block;
251
+ Data_Get_Struct(self, BasicBlock, block);
252
+ block->set_post_order_number(new_num);
253
+ return Qnil;
254
+ }
255
+
256
+ static VALUE bb_get_flags(VALUE self, VALUE dest) {
257
+ BasicBlock *block, *dest_block;
258
+ Data_Get_Struct(self, BasicBlock, block);
259
+ Data_Get_Struct(dest, BasicBlock, dest_block);
260
+ try {
261
+ return INT2FIX(block->get_flags(dest_block));
262
+ } catch (BasicBlock::NoSuchEdgeException e) {
263
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
264
+ }
265
+ }
266
+
267
+ static VALUE bb_has_flag(VALUE self, VALUE dest, VALUE flag) {
268
+ BasicBlock *block, *dest_block;
269
+ Data_Get_Struct(self, BasicBlock, block);
270
+ Data_Get_Struct(dest, BasicBlock, dest_block);
271
+ try {
272
+ return (block->has_flag(dest_block, FIX2INT(flag)) ? Qtrue : Qfalse);
273
+ } catch (BasicBlock::NoSuchEdgeException e) {
274
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
275
+ }
276
+ }
277
+
278
+ static VALUE bb_add_flag(VALUE self, VALUE dest, VALUE flag) {
279
+ BasicBlock *block, *dest_block;
280
+ Data_Get_Struct(self, BasicBlock, block);
281
+ Data_Get_Struct(dest, BasicBlock, dest_block);
282
+ try {
283
+ block->add_flag(dest_block, FIX2INT(flag));
284
+ } catch (BasicBlock::NoSuchEdgeException e) {
285
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
286
+ }
287
+ return Qnil;
288
+ }
289
+
290
+ static VALUE bb_set_flag(VALUE self, VALUE dest, VALUE flag) {
291
+ BasicBlock *block, *dest_block;
292
+ Data_Get_Struct(self, BasicBlock, block);
293
+ Data_Get_Struct(dest, BasicBlock, dest_block);
294
+ try {
295
+ block->set_flag(dest_block, FIX2INT(flag));
296
+ } catch (BasicBlock::NoSuchEdgeException e) {
297
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
298
+ }
299
+ return Qnil;
300
+ }
301
+
302
+ static VALUE bb_remove_flag(VALUE self, VALUE dest, VALUE flag) {
303
+ BasicBlock *block, *dest_block;
304
+ Data_Get_Struct(self, BasicBlock, block);
305
+ Data_Get_Struct(dest, BasicBlock, dest_block);
306
+ try {
307
+ block->remove_flag(dest_block, FIX2INT(flag));
308
+ } catch (BasicBlock::NoSuchEdgeException e) {
309
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
310
+ }
311
+ return Qnil;
312
+ }
313
+
314
+ static VALUE bb_join(VALUE self, VALUE dest) {
315
+ BasicBlock *block, *dest_block;
316
+ Data_Get_Struct(self, BasicBlock, block);
317
+ Data_Get_Struct(dest, BasicBlock, dest_block);
318
+ block->join(dest_block);
319
+ return Qnil;
320
+ }
321
+
322
+ static VALUE bb_disconnect(VALUE self, VALUE dest) {
323
+ BasicBlock *block, *dest_block;
324
+ Data_Get_Struct(self, BasicBlock, block);
325
+ Data_Get_Struct(dest, BasicBlock, dest_block);
326
+ try {
327
+ block->disconnect(dest_block);
328
+ } catch (BasicBlock::NoSuchEdgeException e) {
329
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
330
+ }
331
+ return Qnil;
332
+ }
333
+
334
+ static VALUE bb_insert_block_on_edge(VALUE self, VALUE succ, VALUE inserted) {
335
+ BasicBlock *block, *succ_block, *inserted_block;
336
+ Data_Get_Struct(self, BasicBlock, block);
337
+ Data_Get_Struct(succ, BasicBlock, succ_block);
338
+ Data_Get_Struct(inserted, BasicBlock, inserted_block);
339
+ try {
340
+ block->insert_block_on_edge(succ_block, inserted_block);
341
+ } catch (BasicBlock::NoSuchEdgeException e) {
342
+ rb_raise(rb_eArgError, NO_EDGE_MESSAGE);
343
+ }
344
+ return Qnil;
345
+ }
346
+
347
+ static VALUE bb_successors(VALUE self) {
348
+ BasicBlock *block;
349
+ Data_Get_Struct(self, BasicBlock, block);
350
+ VALUE result;
351
+ if ((result = block->cached_successors()) && result != Qnil) {
352
+ return result;
353
+ }
354
+ std::vector<BasicBlock::Edge*>& list = block->successors();
355
+
356
+ result = rb_ary_new();
357
+ for (std::vector<BasicBlock::Edge*>::iterator it = list.begin();
358
+ it < list.end();
359
+ ++it) {
360
+ rb_ary_push(result, (*it)->to->representation());
361
+ }
362
+ block->set_cached_successors(result);
363
+ return result;
364
+ }
365
+
366
+ static VALUE bb_predecessors(VALUE self) {
367
+ BasicBlock *block;
368
+ Data_Get_Struct(self, BasicBlock, block);
369
+ VALUE result;
370
+ if ((result = block->cached_predecessors()) && result != Qnil) {
371
+ return result;
372
+ }
373
+ std::vector<BasicBlock::Edge*>& list = block->predecessors();
374
+
375
+ result = rb_ary_new();
376
+ for (std::vector<BasicBlock::Edge*>::iterator it = list.begin();
377
+ it < list.end();
378
+ ++it) {
379
+ rb_ary_push(result, (*it)->from->representation());
380
+ }
381
+ block->set_cached_predecessors(result);
382
+ return result;
383
+ }
384
+
385
+ /* FILTERED PREDECESSORS */
386
+
387
+ static VALUE bb_filtered_predecessors(VALUE self, uint8_t flag, uint8_t expectation) {
388
+ BasicBlock *block;
389
+ Data_Get_Struct(self, BasicBlock, block);
390
+ std::vector<BasicBlock::Edge*>& list = block->predecessors();
391
+
392
+ VALUE result = rb_ary_new();
393
+ for (std::vector<BasicBlock::Edge*>::iterator it = list.begin();
394
+ it < list.end();
395
+ ++it) {
396
+ if (((*it)->flags & flag) == expectation) {
397
+ rb_ary_push(result, (*it)->from->representation());
398
+ }
399
+ }
400
+ return result;
401
+ }
402
+
403
+ static VALUE bb_real_predecessors(VALUE self) {
404
+ BasicBlock *block;
405
+ Data_Get_Struct(self, BasicBlock, block);
406
+ VALUE result;
407
+ if ((result = block->cached_real_predecessors()) && result != Qnil) {
408
+ return result;
409
+ }
410
+ result = bb_filtered_predecessors(self, EDGE_FAKE, 0);
411
+ block->set_cached_real_predecessors(result);
412
+ return result;
413
+ }
414
+
415
+ static VALUE bb_normal_predecessors(VALUE self) {
416
+ return bb_filtered_predecessors(self, EDGE_ABNORMAL, 0);
417
+ }
418
+
419
+ static VALUE bb_abnormal_predecessors(VALUE self) {
420
+ return bb_filtered_predecessors(self, EDGE_ABNORMAL, EDGE_ABNORMAL);
421
+ }
422
+
423
+ static VALUE bb_block_taken_predecessors(VALUE self) {
424
+ return bb_filtered_predecessors(self, EDGE_BLOCK_TAKEN, EDGE_BLOCK_TAKEN);
425
+ }
426
+
427
+ static VALUE bb_exception_predecessors(VALUE self) {
428
+ return bb_filtered_predecessors(self, EDGE_ABNORMAL | EDGE_BLOCK_TAKEN, EDGE_ABNORMAL);
429
+ }
430
+
431
+ static VALUE bb_executed_predecessors(VALUE self) {
432
+ return bb_filtered_predecessors(self, EDGE_EXECUTABLE, EDGE_EXECUTABLE);
433
+ }
434
+
435
+ static VALUE bb_unexecuted_predecessors(VALUE self) {
436
+ return bb_filtered_predecessors(self, EDGE_EXECUTABLE, 0);
437
+ }
438
+
439
+ /* FILTERED SUCCESSORS */
440
+
441
+ static VALUE bb_filtered_successors(VALUE self, uint8_t flag, uint8_t expectation) {
442
+ BasicBlock *block;
443
+ Data_Get_Struct(self, BasicBlock, block);
444
+ std::vector<BasicBlock::Edge*>& list = block->successors();
445
+
446
+ VALUE result = rb_ary_new();
447
+ for (std::vector<BasicBlock::Edge*>::iterator it = list.begin();
448
+ it < list.end();
449
+ ++it) {
450
+ if (((*it)->flags & flag) == expectation) {
451
+ rb_ary_push(result, (*it)->to->representation());
452
+ }
453
+ }
454
+ return result;
455
+ }
456
+
457
+ static VALUE bb_real_successors(VALUE self) {
458
+ VALUE result;
459
+ BasicBlock *block;
460
+ Data_Get_Struct(self, BasicBlock, block);
461
+ if ((result = block->cached_real_successors()) && result != Qnil) {
462
+ return result;
463
+ }
464
+ result = bb_filtered_successors(self, EDGE_FAKE, 0);
465
+ block->set_cached_real_successors(result);
466
+ return result;
467
+ }
468
+
469
+ static VALUE bb_normal_successors(VALUE self) {
470
+ return bb_filtered_successors(self, EDGE_ABNORMAL, 0);
471
+ }
472
+
473
+ static VALUE bb_abnormal_successors(VALUE self) {
474
+ return bb_filtered_successors(self, EDGE_ABNORMAL, EDGE_ABNORMAL);
475
+ }
476
+
477
+ static VALUE bb_block_taken_successors(VALUE self) {
478
+ return bb_filtered_successors(self, EDGE_BLOCK_TAKEN, EDGE_BLOCK_TAKEN);
479
+ }
480
+
481
+ static VALUE bb_exception_successors(VALUE self) {
482
+ return bb_filtered_successors(self, EDGE_ABNORMAL | EDGE_BLOCK_TAKEN, EDGE_ABNORMAL);
483
+ }
484
+
485
+ static VALUE bb_executed_successors(VALUE self) {
486
+ return bb_filtered_successors(self, EDGE_EXECUTABLE, EDGE_EXECUTABLE);
487
+ }
488
+
489
+ static VALUE bb_unexecuted_successors(VALUE self) {
490
+ return bb_filtered_successors(self, EDGE_EXECUTABLE, 0);
491
+ }
492
+
493
+ /* Optimized enumerator form */
494
+
495
+ static VALUE bb_each_real_predecessors(VALUE self) {
496
+ RETURN_ENUMERATOR(self, 0, 0);
497
+ BasicBlock *block;
498
+ Data_Get_Struct(self, BasicBlock, block);
499
+ VALUE result;
500
+ if ((result = block->cached_real_predecessors()) && result != Qnil) {
501
+ return rb_ary_each(result);
502
+ }
503
+ std::vector<BasicBlock::Edge*>& list = block->predecessors();
504
+
505
+ for (std::vector<BasicBlock::Edge*>::iterator it = list.begin();
506
+ it < list.end();
507
+ ++it) {
508
+ if (((*it)->flags & EDGE_FAKE) == 0) {
509
+ rb_yield((*it)->from->representation());
510
+ }
511
+ }
512
+ return Qnil;
513
+ }
514
+
515
+ #undef NO_EDGE_MESSAGE
516
+
517
+ VALUE Init_BasicBlock()
518
+ {
519
+ rb_mLaser = rb_define_module("Laser");
520
+ rb_mAnalysis = rb_define_module_under(rb_mLaser, "Analysis");
521
+ rb_mControlFlow = rb_define_module_under(rb_mAnalysis, "ControlFlow");
522
+ rb_cBasicBlock = rb_define_class_under(rb_mControlFlow, "BasicBlock", rb_cObject);
523
+
524
+ rb_define_alloc_func(rb_cBasicBlock, bb_alloc);
525
+ rb_define_method(rb_cBasicBlock, "initialize", RUBY_METHOD_FUNC(bb_initialize), 1);
526
+ rb_define_method(rb_cBasicBlock, "dup", RUBY_METHOD_FUNC(bb_dup), 0);
527
+ rb_define_method(rb_cBasicBlock, "eql?", RUBY_METHOD_FUNC(bb_eql), 1);
528
+ rb_define_method(rb_cBasicBlock, "===", RUBY_METHOD_FUNC(bb_eql), 1);
529
+ rb_define_method(rb_cBasicBlock, "==", RUBY_METHOD_FUNC(bb_eql), 1);
530
+ rb_define_method(rb_cBasicBlock, "!=", RUBY_METHOD_FUNC(bb_neq), 1);
531
+ rb_define_method(rb_cBasicBlock, "equal?", RUBY_METHOD_FUNC(bb_equal), 1);
532
+ rb_define_method(rb_cBasicBlock, "hash", RUBY_METHOD_FUNC(bb_hash), 0);
533
+ rb_define_method(rb_cBasicBlock, "clear_edges", RUBY_METHOD_FUNC(bb_clear_edges), 0);
534
+ rb_define_method(rb_cBasicBlock, "name=", RUBY_METHOD_FUNC(bb_initialize), 1);
535
+ rb_define_method(rb_cBasicBlock, "name", RUBY_METHOD_FUNC(bb_get_name), 0);
536
+ rb_define_method(rb_cBasicBlock, "instructions=", RUBY_METHOD_FUNC(bb_set_instructions), 1);
537
+ rb_define_method(rb_cBasicBlock, "instructions", RUBY_METHOD_FUNC(bb_get_instructions), 0);
538
+ rb_define_method(rb_cBasicBlock, "post_order_number=", RUBY_METHOD_FUNC(bb_set_post_order_number), 1);
539
+ rb_define_method(rb_cBasicBlock, "post_order_number", RUBY_METHOD_FUNC(bb_get_post_order_number), 0);
540
+
541
+ rb_define_method(rb_cBasicBlock, "get_flags", RUBY_METHOD_FUNC(bb_get_flags), 1);
542
+ rb_define_method(rb_cBasicBlock, "has_flag?", RUBY_METHOD_FUNC(bb_has_flag), 2);
543
+ rb_define_method(rb_cBasicBlock, "add_flag", RUBY_METHOD_FUNC(bb_add_flag), 2);
544
+ rb_define_method(rb_cBasicBlock, "set_flag", RUBY_METHOD_FUNC(bb_set_flag), 2);
545
+ rb_define_method(rb_cBasicBlock, "remove_flag", RUBY_METHOD_FUNC(bb_remove_flag), 2);
546
+
547
+ rb_define_method(rb_cBasicBlock, "join", RUBY_METHOD_FUNC(bb_join), 1);
548
+ rb_define_method(rb_cBasicBlock, "disconnect", RUBY_METHOD_FUNC(bb_disconnect), 1);
549
+ rb_define_method(rb_cBasicBlock, "insert_block_on_edge", RUBY_METHOD_FUNC(bb_insert_block_on_edge), 2);
550
+
551
+ rb_define_method(rb_cBasicBlock, "successors", RUBY_METHOD_FUNC(bb_successors), 0);
552
+ rb_define_method(rb_cBasicBlock, "predecessors", RUBY_METHOD_FUNC(bb_predecessors), 0);
553
+ rb_define_method(rb_cBasicBlock, "each_real_predecessors", RUBY_METHOD_FUNC(bb_each_real_predecessors), 0);
554
+
555
+ rb_define_method(rb_cBasicBlock, "real_predecessors", RUBY_METHOD_FUNC(bb_real_predecessors), 0);
556
+ rb_define_method(rb_cBasicBlock, "normal_predecessors", RUBY_METHOD_FUNC(bb_normal_predecessors), 0);
557
+ rb_define_method(rb_cBasicBlock, "abnormal_predecessors", RUBY_METHOD_FUNC(bb_abnormal_predecessors), 0);
558
+ rb_define_method(rb_cBasicBlock, "block_taken_predecessors", RUBY_METHOD_FUNC(bb_block_taken_predecessors), 0);
559
+ rb_define_method(rb_cBasicBlock, "exception_predecessors", RUBY_METHOD_FUNC(bb_exception_predecessors), 0);
560
+ rb_define_method(rb_cBasicBlock, "executed_predecessors", RUBY_METHOD_FUNC(bb_executed_predecessors), 0);
561
+ rb_define_method(rb_cBasicBlock, "unexecuted_predecessors", RUBY_METHOD_FUNC(bb_unexecuted_predecessors), 0);
562
+
563
+ rb_define_method(rb_cBasicBlock, "real_successors", RUBY_METHOD_FUNC(bb_real_successors), 0);
564
+ rb_define_method(rb_cBasicBlock, "normal_successors", RUBY_METHOD_FUNC(bb_normal_successors), 0);
565
+ rb_define_method(rb_cBasicBlock, "abnormal_successors", RUBY_METHOD_FUNC(bb_abnormal_successors), 0);
566
+ rb_define_method(rb_cBasicBlock, "block_taken_successors", RUBY_METHOD_FUNC(bb_block_taken_successors), 0);
567
+ rb_define_method(rb_cBasicBlock, "exception_successors", RUBY_METHOD_FUNC(bb_exception_successors), 0);
568
+ rb_define_method(rb_cBasicBlock, "executed_successors", RUBY_METHOD_FUNC(bb_executed_successors), 0);
569
+ rb_define_method(rb_cBasicBlock, "unexecuted_successors", RUBY_METHOD_FUNC(bb_unexecuted_successors), 0);
570
+ return Qnil;
571
+ }
572
+ }