ikra 0.0.1

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 (220) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ast/builder.rb +100 -0
  3. data/lib/ast/lexical_variables_enumerator.rb +34 -0
  4. data/lib/ast/method_definition.rb +37 -0
  5. data/lib/ast/nodes.rb +208 -0
  6. data/lib/ast/printer.rb +99 -0
  7. data/lib/ast/translator.rb +264 -0
  8. data/lib/ast/visitor.rb +173 -0
  9. data/lib/config/configuration.rb +18 -0
  10. data/lib/config/os_configuration.rb +56 -0
  11. data/lib/entity.rb +11 -0
  12. data/lib/ikra.rb +7 -0
  13. data/lib/parsing.rb +32 -0
  14. data/lib/resources/cuda/block_function_head.cpp +1 -0
  15. data/lib/resources/cuda/env_builder_copy_array.cpp +4 -0
  16. data/lib/resources/cuda/header.cpp +46 -0
  17. data/lib/resources/cuda/kernel.cpp +8 -0
  18. data/lib/resources/cuda/kernel_launcher.cpp +28 -0
  19. data/lib/resources/cuda/soa_header.cpp +4 -0
  20. data/lib/scope.rb +166 -0
  21. data/lib/sourcify/Gemfile +10 -0
  22. data/lib/sourcify/HISTORY.txt +88 -0
  23. data/lib/sourcify/LICENSE +20 -0
  24. data/lib/sourcify/README.rdoc +352 -0
  25. data/lib/sourcify/Rakefile +111 -0
  26. data/lib/sourcify/lib/sourcify.rb +44 -0
  27. data/lib/sourcify/lib/sourcify/common/parser/converter.rb +29 -0
  28. data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/comment.rb +23 -0
  29. data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/counter.rb +43 -0
  30. data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/dstring.rb +58 -0
  31. data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/extensions.rb +140 -0
  32. data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/heredoc.rb +26 -0
  33. data/lib/sourcify/lib/sourcify/common/parser/source_code.rb +45 -0
  34. data/lib/sourcify/lib/sourcify/common/ragel/common.rl +5 -0
  35. data/lib/sourcify/lib/sourcify/common/ragel/expressions.rl +38 -0
  36. data/lib/sourcify/lib/sourcify/common/ragel/machines.rl +317 -0
  37. data/lib/sourcify/lib/sourcify/errors.rb +4 -0
  38. data/lib/sourcify/lib/sourcify/method.rb +138 -0
  39. data/lib/sourcify/lib/sourcify/method/methods.rb +3 -0
  40. data/lib/sourcify/lib/sourcify/method/methods/to_raw_source.rb +30 -0
  41. data/lib/sourcify/lib/sourcify/method/methods/to_sexp.rb +30 -0
  42. data/lib/sourcify/lib/sourcify/method/methods/to_source.rb +30 -0
  43. data/lib/sourcify/lib/sourcify/method/parser.rb +110 -0
  44. data/lib/sourcify/lib/sourcify/method/parser/converter.rb +8 -0
  45. data/lib/sourcify/lib/sourcify/method/parser/raw_scanner.rb +2494 -0
  46. data/lib/sourcify/lib/sourcify/method/parser/raw_scanner.rl +144 -0
  47. data/lib/sourcify/lib/sourcify/method/parser/raw_scanner_extensions.rb +68 -0
  48. data/lib/sourcify/lib/sourcify/method/parser/scanner.rb +52 -0
  49. data/lib/sourcify/lib/sourcify/method/parser/source_code.rb +8 -0
  50. data/lib/sourcify/lib/sourcify/patches.rb +63 -0
  51. data/lib/sourcify/lib/sourcify/proc.rb +183 -0
  52. data/lib/sourcify/lib/sourcify/proc/methods.rb +3 -0
  53. data/lib/sourcify/lib/sourcify/proc/methods/source_location.rb +61 -0
  54. data/lib/sourcify/lib/sourcify/proc/methods/to_raw_source.rb +20 -0
  55. data/lib/sourcify/lib/sourcify/proc/methods/to_sexp.rb +40 -0
  56. data/lib/sourcify/lib/sourcify/proc/methods/to_source.rb +48 -0
  57. data/lib/sourcify/lib/sourcify/proc/parser.rb +51 -0
  58. data/lib/sourcify/lib/sourcify/proc/parser/converter.rb +8 -0
  59. data/lib/sourcify/lib/sourcify/proc/parser/normalizer.rb +43 -0
  60. data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner.rb +2498 -0
  61. data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner.rl +149 -0
  62. data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner_extensions.rb +74 -0
  63. data/lib/sourcify/lib/sourcify/proc/parser/scanner.rb +49 -0
  64. data/lib/sourcify/lib/sourcify/proc/parser/source_code.rb +8 -0
  65. data/lib/sourcify/lib/sourcify/version.rb +3 -0
  66. data/lib/sourcify/sourcify.gemspec +31 -0
  67. data/lib/sourcify/spec/dump_object_space_procs.rb +84 -0
  68. data/lib/sourcify/spec/method/encoding_from_def_end_block_spec.rb +33 -0
  69. data/lib/sourcify/spec/method/encoding_from_define_method_spec.rb +37 -0
  70. data/lib/sourcify/spec/method/others_from_def_end_block_spec.rb +49 -0
  71. data/lib/sourcify/spec/method/others_from_define_method_spec.rb +63 -0
  72. data/lib/sourcify/spec/method/raw_scanner/block_comment_spec.rb +8 -0
  73. data/lib/sourcify/spec/method/raw_scanner/double_colons_spec.rb +8 -0
  74. data/lib/sourcify/spec/method/raw_scanner/double_quote_str_w_interpolation_spec.rb +8 -0
  75. data/lib/sourcify/spec/method/raw_scanner/double_quote_str_wo_interpolation_spec.rb +8 -0
  76. data/lib/sourcify/spec/method/raw_scanner/heredoc_w_indent_spec.rb +8 -0
  77. data/lib/sourcify/spec/method/raw_scanner/heredoc_wo_indent_spec.rb +8 -0
  78. data/lib/sourcify/spec/method/raw_scanner/kw_block_start_alias1_spec.rb +20 -0
  79. data/lib/sourcify/spec/method/raw_scanner/kw_block_start_alias2_spec.rb +20 -0
  80. data/lib/sourcify/spec/method/raw_scanner/per_line_comment_spec.rb +8 -0
  81. data/lib/sourcify/spec/method/raw_scanner/single_quote_str_spec.rb +8 -0
  82. data/lib/sourcify/spec/method/raw_scanner/slash_operator_spec.rb +8 -0
  83. data/lib/sourcify/spec/method/raw_scanner/spec_helper.rb +80 -0
  84. data/lib/sourcify/spec/method/spec_helper.rb +1 -0
  85. data/lib/sourcify/spec/method/to_raw_source_spec.rb +31 -0
  86. data/lib/sourcify/spec/method/to_raw_source_w_specified_strip_enclosure_spec.rb +148 -0
  87. data/lib/sourcify/spec/method/to_sexp_from_def_end_block_w_variables_spec.rb +46 -0
  88. data/lib/sourcify/spec/method/to_sexp_from_def_end_block_within_irb_spec.rb +38 -0
  89. data/lib/sourcify/spec/method/to_sexp_from_def_end_block_within_pry_spec.rb +38 -0
  90. data/lib/sourcify/spec/method/to_sexp_from_define_method_w_multi_blocks_and_specified_attached_to_spec.rb +56 -0
  91. data/lib/sourcify/spec/method/to_sexp_from_define_method_w_variables_spec.rb +52 -0
  92. data/lib/sourcify/spec/method/to_sexp_from_define_method_within_irb_spec.rb +42 -0
  93. data/lib/sourcify/spec/method/to_sexp_from_define_method_within_pry_spec.rb +42 -0
  94. data/lib/sourcify/spec/method/to_sexp_w_specified_strip_enclosure_spec.rb +74 -0
  95. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_19_extras_spec.rb +23 -0
  96. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_begin_spec.rb +35 -0
  97. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_case_spec.rb +35 -0
  98. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_class_spec.rb +51 -0
  99. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_do_end_block_spec.rb +33 -0
  100. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_for_spec.rb +126 -0
  101. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_if_spec.rb +83 -0
  102. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_literal_keyword_spec.rb +141 -0
  103. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_method_spec.rb +33 -0
  104. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_module_spec.rb +59 -0
  105. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_unless_spec.rb +83 -0
  106. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_until_spec.rb +179 -0
  107. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_while_spec.rb +179 -0
  108. data/lib/sourcify/spec/method/to_source_from_def_end_block_w_singleton_method_spec.rb +19 -0
  109. data/lib/sourcify/spec/method/to_source_from_def_end_block_within_irb_spec.rb +30 -0
  110. data/lib/sourcify/spec/method/to_source_from_def_end_block_within_pry_spec.rb +45 -0
  111. data/lib/sourcify/spec/method/to_source_from_def_end_w_multi_blocks_and_many_matches_spec.rb +30 -0
  112. data/lib/sourcify/spec/method/to_source_from_def_end_w_multi_blocks_and_single_match_spec.rb +36 -0
  113. data/lib/sourcify/spec/method/to_source_from_define_method_w_braced_block_spec.rb +113 -0
  114. data/lib/sourcify/spec/method/to_source_from_define_method_w_do_end_block_spec.rb +145 -0
  115. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_many_matches_spec.rb +56 -0
  116. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_single_match_spec.rb +73 -0
  117. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_many_matches_spec.rb +36 -0
  118. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_no_match_spec.rb +36 -0
  119. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_single_match_spec.rb +28 -0
  120. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_spec.rb +103 -0
  121. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_many_matches_spec.rb +36 -0
  122. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_no_match_spec.rb +36 -0
  123. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_single_match_spec.rb +28 -0
  124. data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_ignore_nested_spec.rb +36 -0
  125. data/lib/sourcify/spec/method/to_source_from_define_method_within_irb_spec.rb +32 -0
  126. data/lib/sourcify/spec/method/to_source_from_define_method_within_pry_spec.rb +49 -0
  127. data/lib/sourcify/spec/method/to_source_magic_file_var_spec.rb +176 -0
  128. data/lib/sourcify/spec/method/to_source_magic_line_var_spec.rb +298 -0
  129. data/lib/sourcify/spec/method/to_source_w_specified_strip_enclosure_spec.rb +39 -0
  130. data/lib/sourcify/spec/no_method/unsupported_platform_spec.rb +26 -0
  131. data/lib/sourcify/spec/proc/19x_extras.rb +27 -0
  132. data/lib/sourcify/spec/proc/created_on_the_fly_proc_spec.rb +80 -0
  133. data/lib/sourcify/spec/proc/encoding_spec.rb +36 -0
  134. data/lib/sourcify/spec/proc/others_spec.rb +40 -0
  135. data/lib/sourcify/spec/proc/raw_scanner/block_comment_spec.rb +8 -0
  136. data/lib/sourcify/spec/proc/raw_scanner/double_colons_spec.rb +8 -0
  137. data/lib/sourcify/spec/proc/raw_scanner/double_quote_str_w_interpolation_spec.rb +8 -0
  138. data/lib/sourcify/spec/proc/raw_scanner/double_quote_str_wo_interpolation_spec.rb +8 -0
  139. data/lib/sourcify/spec/proc/raw_scanner/heredoc_w_indent_spec.rb +8 -0
  140. data/lib/sourcify/spec/proc/raw_scanner/heredoc_wo_indent_spec.rb +8 -0
  141. data/lib/sourcify/spec/proc/raw_scanner/kw_block_start_alias1_spec.rb +20 -0
  142. data/lib/sourcify/spec/proc/raw_scanner/kw_block_start_alias2_spec.rb +20 -0
  143. data/lib/sourcify/spec/proc/raw_scanner/per_line_comment_spec.rb +8 -0
  144. data/lib/sourcify/spec/proc/raw_scanner/single_quote_str_spec.rb +8 -0
  145. data/lib/sourcify/spec/proc/raw_scanner/slash_operator_spec.rb +8 -0
  146. data/lib/sourcify/spec/proc/raw_scanner/spec_helper.rb +63 -0
  147. data/lib/sourcify/spec/proc/readme +5 -0
  148. data/lib/sourcify/spec/proc/spec_helper.rb +1 -0
  149. data/lib/sourcify/spec/proc/to_raw_source_spec.rb +33 -0
  150. data/lib/sourcify/spec/proc/to_raw_source_w_specified_strip_enclosure_spec.rb +69 -0
  151. data/lib/sourcify/spec/proc/to_sexp_from_multi_blocks_w_specified_attached_to_spec.rb +46 -0
  152. data/lib/sourcify/spec/proc/to_sexp_variables_spec.rb +146 -0
  153. data/lib/sourcify/spec/proc/to_sexp_w_specified_strip_enclosure_spec.rb +60 -0
  154. data/lib/sourcify/spec/proc/to_sexp_within_irb_spec.rb +146 -0
  155. data/lib/sourcify/spec/proc/to_sexp_within_pry_spec.rb +149 -0
  156. data/lib/sourcify/spec/proc/to_source_from_braced_block_w_nested_braced_block_spec.rb +33 -0
  157. data/lib/sourcify/spec/proc/to_source_from_braced_block_w_nested_hash_spec.rb +82 -0
  158. data/lib/sourcify/spec/proc/to_source_from_braced_block_wo_nesting_complication_spec.rb +46 -0
  159. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_begin_spec.rb +35 -0
  160. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_case_spec.rb +35 -0
  161. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_class_spec.rb +89 -0
  162. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_do_end_block_spec.rb +33 -0
  163. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_for_spec.rb +132 -0
  164. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_if_spec.rb +87 -0
  165. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_literal_keyword_spec.rb +103 -0
  166. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_method_spec.rb +33 -0
  167. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_module_spec.rb +49 -0
  168. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_unless_spec.rb +87 -0
  169. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_until_spec.rb +189 -0
  170. data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_while_spec.rb +189 -0
  171. data/lib/sourcify/spec/proc/to_source_from_do_end_block_wo_nesting_complication_spec.rb +46 -0
  172. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_many_matches_spec.rb +43 -0
  173. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_single_match_spec.rb +20 -0
  174. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_many_matches_spec.rb +45 -0
  175. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_no_match_spec.rb +45 -0
  176. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_single_match_spec.rb +22 -0
  177. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_spec.rb +84 -0
  178. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_many_matches_spec.rb +45 -0
  179. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_no_match_spec.rb +45 -0
  180. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_single_match_spec.rb +22 -0
  181. data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_ignore_nested_spec.rb +43 -0
  182. data/lib/sourcify/spec/proc/to_source_from_multi_do_end_blocks_w_single_match_spec.rb +31 -0
  183. data/lib/sourcify/spec/proc/to_source_magic_file_var_spec.rb +127 -0
  184. data/lib/sourcify/spec/proc/to_source_magic_line_var_spec.rb +127 -0
  185. data/lib/sourcify/spec/proc/to_source_variables_spec.rb +29 -0
  186. data/lib/sourcify/spec/proc/to_source_w_specified_strip_enclosure_spec.rb +33 -0
  187. data/lib/sourcify/spec/proc/to_source_within_irb_spec.rb +38 -0
  188. data/lib/sourcify/spec/proc/to_source_within_pry_spec.rb +61 -0
  189. data/lib/sourcify/spec/raw_scanner/block_comment_shared_spec.rb +57 -0
  190. data/lib/sourcify/spec/raw_scanner/double_colons_shared_spec.rb +11 -0
  191. data/lib/sourcify/spec/raw_scanner/double_quote_str_w_interpolation_shared_spec.rb +60 -0
  192. data/lib/sourcify/spec/raw_scanner/double_quote_str_wo_interpolation_shared_spec.rb +86 -0
  193. data/lib/sourcify/spec/raw_scanner/heredoc_w_indent_shared_spec.rb +69 -0
  194. data/lib/sourcify/spec/raw_scanner/heredoc_wo_indent_shared_spec.rb +70 -0
  195. data/lib/sourcify/spec/raw_scanner/kw_block_start_alias1_shared_spec.rb +73 -0
  196. data/lib/sourcify/spec/raw_scanner/kw_block_start_alias2_shared_spec.rb +73 -0
  197. data/lib/sourcify/spec/raw_scanner/per_line_comment_shared_spec.rb +32 -0
  198. data/lib/sourcify/spec/raw_scanner/shared_specs.rb +3 -0
  199. data/lib/sourcify/spec/raw_scanner/single_quote_str_shared_spec.rb +79 -0
  200. data/lib/sourcify/spec/raw_scanner/slash_operator_shared_spec.rb +71 -0
  201. data/lib/sourcify/spec/run_build.sh +25 -0
  202. data/lib/sourcify/spec/spec_helper.rb +130 -0
  203. data/lib/symbolic/symbolic.rb +248 -0
  204. data/lib/symbolic/visitor.rb +51 -0
  205. data/lib/translator/block_translator.rb +123 -0
  206. data/lib/translator/command_translator.rb +421 -0
  207. data/lib/translator/last_returns_visitor.rb +57 -0
  208. data/lib/translator/local_variables_enumerator.rb +35 -0
  209. data/lib/translator/method_translator.rb +24 -0
  210. data/lib/translator/translator.rb +49 -0
  211. data/lib/type_aware_array.rb +71 -0
  212. data/lib/types/array_type.rb +51 -0
  213. data/lib/types/class_type.rb +128 -0
  214. data/lib/types/object_tracer.rb +162 -0
  215. data/lib/types/primitive_type.rb +73 -0
  216. data/lib/types/ruby_extension.rb +67 -0
  217. data/lib/types/ruby_type.rb +45 -0
  218. data/lib/types/type_inference.rb +382 -0
  219. data/lib/types/union_type.rb +155 -0
  220. metadata +321 -0
@@ -0,0 +1,57 @@
1
+ require_relative "../ast/nodes"
2
+ require_relative "../ast/visitor"
3
+
4
+ module Ikra
5
+ module Translator
6
+ class LastStatementReturnsVisitor < AST::Visitor
7
+ def visit_root_node(node)
8
+ node.child.accept(self)
9
+ end
10
+
11
+ def visit_lvar_read_node(node)
12
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
13
+ end
14
+
15
+ def visit_lvar_write_node(node)
16
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
17
+ end
18
+
19
+ def visit_int_node(node)
20
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
21
+ end
22
+
23
+ def visit_float_node(node)
24
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
25
+ end
26
+
27
+ def visit_bool_node(node)
28
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
29
+ end
30
+
31
+ def visit_for_node(node)
32
+ raise "Cannot handle for loop as return value"
33
+ end
34
+
35
+ def visit_break_node(node)
36
+ raise "Break must not be a return value"
37
+ end
38
+
39
+ def visit_if_node(node)
40
+ node.true_body_stmts.accept(self)
41
+ node.false_body_stmts.accept(self)
42
+ end
43
+
44
+ def visit_begin_node(node)
45
+ node.body_stmts.last.accept(self)
46
+ end
47
+
48
+ def visit_send_node(node)
49
+ node.parent.replace_child(node, AST::ReturnNode.new(value: node))
50
+ end
51
+
52
+ def visit_return_node(node)
53
+ raise "Function returns already"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../ast/nodes"
2
+ require_relative "../ast/visitor"
3
+ require_relative "../types/type_inference"
4
+
5
+ module Ikra
6
+ module Translator
7
+ class LocalVariablesEnumerator < AST::Visitor
8
+ def initialize
9
+ @vars = {}
10
+ end
11
+
12
+ def add_local_var(var, type)
13
+ @vars[var] = type
14
+ end
15
+
16
+ def local_variables
17
+ @vars
18
+ end
19
+
20
+ def visit_lvar_read_node(node)
21
+ add_local_var(node.identifier, node.get_type)
22
+ end
23
+
24
+ def visit_lvar_write_node(node)
25
+ add_local_var(node.identifier, node.get_type)
26
+ super(node)
27
+ end
28
+
29
+ def visit_for_node(node)
30
+ add_local_var(node.iterator_identifier, Types::UnionType.create_int)
31
+ super(node)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ module Ikra
2
+ module AST
3
+ class MethodDefinition
4
+ def to_c_source
5
+ # TODO: merge with BlockTranslator
6
+
7
+ method_params = (["environment_t * #{Translator::Constants::ENV_IDENTIFIER}", "#{type.to_c_type} #{Constants::SELF_IDENTIFIER}"] + parameter_variables.map do |name, type|
8
+ "#{name} #{type.singleton_type.to_c_type}"
9
+ end).join(", ")
10
+
11
+ # TODO: load environment variables
12
+
13
+ # Declare local variables
14
+ local_variables_def = ""
15
+ local_variables.each do |name, types|
16
+ local_variables_def += "#{types.singleton_type.to_c_type} #{name};\n"
17
+ end
18
+
19
+ signature = "__device__ #{return_type.singleton_type.to_c_type} #{type.mangled_method_name(selector)}(#{method_params})"
20
+ signature + "\n" + Translator.wrap_in_c_block(local_variables_def + ast.translate_statement)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ require_relative "block_translator"
2
+ require_relative "command_translator"
3
+ require_relative "last_returns_visitor"
4
+ require_relative "local_variables_enumerator"
5
+ require_relative "method_translator"
6
+ require_relative "../config/configuration"
7
+
8
+ module Ikra
9
+
10
+ # This module contains functionality for translating Ruby code to CUDA (C++) code.
11
+ module Translator
12
+ module Constants
13
+ ENV_IDENTIFIER = "_env_"
14
+ ENV_DEVICE_IDENTIFIER = "dev_env"
15
+ ENV_HOST_IDENTIFIER = "host_env"
16
+ end
17
+
18
+ class << self
19
+ def wrap_in_c_block(str)
20
+ "{\n" + str.split("\n").map do |line| " " + line end.join("\n") + "\n}\n"
21
+ end
22
+
23
+ # Reads a CUDA source code file and replaces identifiers by provided substitutes.
24
+ # @param [String] file_name name of source code file
25
+ # @param [Hash{String => String}] replacements replacements
26
+ def read_file(file_name:, replacements: {})
27
+ full_name = Ikra::Configuration.resource_file_name(file_name)
28
+ if !File.exist?(full_name)
29
+ raise "File does not exist: #{full_name}"
30
+ end
31
+
32
+ contents = File.open(full_name, "rb").read
33
+
34
+ replacements.each do |s1, s2|
35
+ replacement = "/*{#{s1}}*/"
36
+ contents = contents.gsub(replacement, s2)
37
+ end
38
+
39
+ contents
40
+ end
41
+ end
42
+ end
43
+
44
+ module AST
45
+ module Constants
46
+ SELF_IDENTIFIER = "_self_"
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,71 @@
1
+ class Array
2
+
3
+ # TODO: probably do not need this anymore
4
+ def common_superclass
5
+ class_counter = {}
6
+ class_counter.default = 0
7
+
8
+ index = 0
9
+ each do |cls|
10
+ while (cls != BasicObject) do
11
+ class_counter[cls] += 1
12
+ cls = cls.superclass
13
+ end
14
+ index += 1
15
+ end
16
+
17
+ smallest = Object
18
+ class_counter.each do |cls, counter|
19
+ if counter == size
20
+ if cls < smallest
21
+ smallest = cls
22
+ end
23
+ end
24
+ end
25
+
26
+ smallest
27
+ end
28
+
29
+ def all_types
30
+ type_counter.keys
31
+ end
32
+
33
+ alias :old_push :push
34
+
35
+ def push(*elements)
36
+ old_push(*elements)
37
+
38
+ for element in elements
39
+ type_counter[element.class] += 1
40
+ end
41
+
42
+ self
43
+ end
44
+
45
+ alias :old_set :[]=
46
+
47
+ def []=(index, element)
48
+ type_counter[self[index].class] -= 1
49
+ if type_counter[self[index].class] == 0
50
+ type_counter.delete(self[index].class)
51
+ end
52
+
53
+ old_set(index, element)
54
+ type_counter[element.class] += 1
55
+ end
56
+
57
+ private
58
+
59
+ def type_counter
60
+ if @type_counter == nil
61
+ @type_counter = {}
62
+ @type_counter.default = 0
63
+
64
+ each do |element|
65
+ @type_counter[element.class] += 1
66
+ end
67
+ end
68
+
69
+ @type_counter
70
+ end
71
+ end
@@ -0,0 +1,51 @@
1
+ require_relative "ruby_type"
2
+
3
+ module Ikra
4
+ module Types
5
+ class ArrayType
6
+ include RubyType
7
+
8
+ class << self
9
+ # Ensure singleton per class
10
+ def new(inner_type)
11
+ if @cache == nil
12
+ @cache = {}
13
+ @cache.default_proc = Proc.new do |hash, key|
14
+ hash[key] = super(key)
15
+ end
16
+ end
17
+
18
+ @cache[inner_type]
19
+ end
20
+ end
21
+
22
+ def initialize(inner_type)
23
+ if not inner_type.is_union_type?
24
+ raise "Union type expected"
25
+ end
26
+
27
+ @inner_type = inner_type
28
+ end
29
+
30
+ def to_c_type
31
+ "#{@inner_type.to_c_type} *"
32
+ end
33
+
34
+ def to_ffi_type
35
+ :pointer
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ class Array
42
+ def self.to_ikra_type_obj(object)
43
+ inner_type = Ikra::Types::UnionType.new
44
+
45
+ object.each do |element|
46
+ inner_type.expand_with_singleton_type(element.class.to_ikra_type)
47
+ end
48
+
49
+ Ikra::Types::ArrayType.new(inner_type)
50
+ end
51
+ end
@@ -0,0 +1,128 @@
1
+ require "set"
2
+ require_relative "ruby_type"
3
+ require_relative "union_type"
4
+ require_relative "../sourcify/lib/sourcify"
5
+ require_relative "../parsing"
6
+ require_relative "../ast/builder"
7
+
8
+ module Ikra
9
+ module Types
10
+ class ClassType
11
+ include RubyType
12
+
13
+ attr_reader :cls
14
+ attr_reader :inst_vars_types
15
+
16
+ class << self
17
+ # Ensure singleton per class
18
+ def new(cls)
19
+ if @cache == nil
20
+ @cache = {}
21
+ @cache.default_proc = Proc.new do |hash, key|
22
+ hash[key] = super(key)
23
+ end
24
+ end
25
+
26
+ @cache[cls]
27
+ end
28
+ end
29
+
30
+ def initialize(cls)
31
+ @cls = cls
32
+ @inst_vars_read = Set.new
33
+ @inst_vars_written = Set.new
34
+
35
+ @inst_vars_types = Hash.new
36
+ @inst_vars_types.default_proc = Proc.new do |hash, key|
37
+ hash[key] = UnionType.new
38
+ end
39
+ end
40
+
41
+ def inst_var_read!(inst_var_name)
42
+ @inst_vars_read.add(inst_var_name)
43
+ end
44
+
45
+ def inst_var_written!(inst_var_name)
46
+ @inst_var_written.add(inst_var_name)
47
+ end
48
+
49
+ def inst_var_read?(inst_var_name)
50
+ @inst_var_read.include?(inst_var_name)
51
+ end
52
+
53
+ def inst_var_written(inst_var_name)
54
+ @inst_var_written.include?(inst_var_name)
55
+ end
56
+
57
+ def accessed_inst_vars
58
+ @inst_vars_read + @inst_vars_written
59
+ end
60
+
61
+ def to_ruby_type
62
+ @cls
63
+ end
64
+
65
+ def ruby_name
66
+ @cls.to_s
67
+ end
68
+
69
+ def to_c_type
70
+ # TODO: sometimes this should be a union type struct
71
+ "obj_id_t"
72
+ end
73
+
74
+ def mangled_method_name(selector)
75
+ "_method_#{@cls.to_s}_#{selector}_"
76
+ end
77
+
78
+ def inst_var_array_name(inst_var_name)
79
+ if inst_var_name.to_s[0] != "@"
80
+ raise "Expected instance variable identifier"
81
+ end
82
+
83
+ "_iv_#{@cls.to_s}_#{inst_var_name.to_s[1..-1]}_"
84
+ end
85
+
86
+ def method_ast(selector)
87
+ source = Parsing.parse_method(cls.instance_method(selector))
88
+ ast = AST::Builder.from_parser_ast(source)
89
+ ast.class_owner = @cls
90
+ ast
91
+ end
92
+
93
+ def method_parameters(selector)
94
+ # returns names
95
+ # TODO: handle optional params, kwargs, etc.
96
+ to_ruby_type.instance_method(selector).parameters.map do |param|
97
+ param[1]
98
+ end
99
+ end
100
+
101
+ def should_generate_type?
102
+ to_ruby_type != Class
103
+ end
104
+
105
+ def to_s
106
+ "<class: #{@cls.to_s}>"
107
+ end
108
+
109
+ def c_size
110
+ # IDs are 4 byte integers
111
+ 4
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ class Object
118
+ def self.to_ikra_type
119
+ # TODO: should this method be defined on Class?
120
+ Ikra::Types::ClassType.new(self)
121
+ end
122
+
123
+ # Returns the [Ikra::Types::RubyType] for this class. This version of the method receives the actual object as a parameter. This is necessary for example to determine the exact type of an array (including inner type).
124
+ def self.to_ikra_type_obj(object)
125
+ to_ikra_type
126
+ end
127
+ end
128
+
@@ -0,0 +1,162 @@
1
+ require "set"
2
+ require "ffi"
3
+ require_relative "../entity"
4
+ require_relative "class_type"
5
+ require_relative "../symbolic/symbolic"
6
+ require_relative "../translator/command_translator"
7
+
8
+ module Ikra
9
+ module TypeInference
10
+
11
+ # The object tracer determines a set of objects that are relevant for the execution of a parallel section (grouped by class). Only instances of classes that have {Ikra::Entity} included are such relevant objects.
12
+ class ObjectTracer
13
+ def initialize(command)
14
+ # Hash map: Class -> Set[Object]
15
+ @roots = RootsFinder.process(command)
16
+ @num_traced_objects = 0
17
+
18
+ @objects = Hash.new
19
+ @objects.default_proc = Proc.new do |hash, key|
20
+ hash[key] = Hash.new
21
+ end
22
+
23
+ @top_object_id = Hash.new
24
+ @top_object_id.default = -1
25
+ end
26
+
27
+ def trace_all
28
+ @worklist = Set.new(@roots)
29
+
30
+ while @worklist.size > 0
31
+ current_obj = @worklist.first
32
+ @worklist.delete(current_obj)
33
+
34
+ trace_object(current_obj)
35
+ end
36
+
37
+ Log.info("Traced #{@num_traced_objects} objects with #{@objects.size} distinct types")
38
+
39
+ @objects
40
+ end
41
+
42
+ def trace_object(object)
43
+ if not object.class.to_ikra_type.is_primitive?
44
+ if not @objects[object.class].has_key?(object)
45
+ # object was not traced yet
46
+ @objects[object.class][object] = (@top_object_id[object.class] += 1)
47
+ @num_traced_objects += 1
48
+
49
+ object.instance_variables.each do |inst_var_name|
50
+ value = object.instance_variable_get(inst_var_name)
51
+ value_type = value.class.to_ikra_type
52
+
53
+ # Gather type information
54
+ object.class.to_ikra_type.inst_vars_types[inst_var_name].expand_with_singleton_type(value_type)
55
+
56
+ if value.class.include?(Entity)
57
+ # Keep tracing this object
58
+ @worklist.add(value)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ # Generates arrays for the Structure of Arrays (SoA) object layout
66
+ def register_soa_arrays(environment_builder)
67
+ # arrays: class x inst var name -> Array
68
+ arrays = Hash.new
69
+ arrays.default_proc = proc do |hash, cls|
70
+ inner_hash = Hash.new
71
+ inner_hash.default_proc = proc do |inner, inst_var|
72
+ inner[inst_var] = Array.new(@top_object_id[cls] + 1)
73
+ end
74
+ hash[cls] = inner_hash
75
+ end
76
+
77
+ @objects.each do |cls, objs|
78
+ cls.to_ikra_type.accessed_inst_vars.each do |inst_var|
79
+ objs.each do |obj, id|
80
+ inst_var_value = obj.instance_variable_get(inst_var)
81
+
82
+ if inst_var_value.class.to_ikra_type.is_primitive?
83
+ # Use object value directly
84
+ arrays[cls][inst_var][id] = inst_var_value
85
+ else
86
+ if !inst_var_value.class.include?(Entity)
87
+ Log.warn("Attempting to transfer an object of class #{inst_var_value.class} that is not an Ikra::Entity. Could be a false positive. Skipping.")
88
+ else
89
+ # Use object ID
90
+ arrays[cls][inst_var][id] = @objects[inst_var_value.class][inst_var_value]
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ arrays.each do |cls, inner_hash|
98
+ inner_hash.each do |inst_var, array|
99
+ environment_builder.add_soa_array(cls.to_ikra_type.inst_var_array_name(inst_var), array)
100
+ end
101
+ end
102
+ end
103
+
104
+ # Returns an array of IDs for the base array or the base array itself if all values are primitive.
105
+ # TODO: This should be done in the environment builder, but I want to avoid copying over arrays...
106
+ def convert_base_array(base_array, need_union_type)
107
+ if base_array.first.class.to_ikra_type.is_primitive? && !need_union_type
108
+ base_array
109
+ else
110
+ if !need_union_type
111
+ base_array.map do |obj|
112
+ @objects[obj.class][obj]
113
+ end
114
+ else
115
+ mem_block = FFI::MemoryPointer.new(Translator::EnvironmentBuilder::UnionTypeStruct, base_array.size)
116
+ array = base_array.size.times.collect do |index|
117
+ Translator::EnvironmentBuilder::UnionTypeStruct.new(mem_block + index * Translator::EnvironmentBuilder::UnionTypeStruct.size)
118
+ end
119
+
120
+ base_array.each_with_index do |obj, index|
121
+ obj_type = obj.class.to_ikra_type
122
+ array[index][:class_id] = obj_type.class_id
123
+
124
+ if obj_type.is_primitive?
125
+ # TODO: what if the primitive value is not an integer?
126
+ array[index][:object_id] = obj
127
+ else
128
+ array[index][:object_id] = @objects[obj.class][obj]
129
+ end
130
+ end
131
+
132
+ mem_block
133
+ end
134
+ end
135
+ end
136
+
137
+ # Finds all roots (including dependent commands) of a command.
138
+ class RootsFinder < Symbolic::Visitor
139
+ attr_reader :roots
140
+
141
+ def self.process(command)
142
+ instance = self.new
143
+ command.accept(instance)
144
+ instance.roots
145
+ end
146
+
147
+ def initialize
148
+ @roots = Set.new
149
+ end
150
+
151
+ def visit_array_command(command)
152
+ @roots.merge(command.lexical_externals.values)
153
+ end
154
+
155
+ def visit_array_identity_command(command)
156
+ super
157
+ @roots.merge(command.target)
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end