laser 0.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }