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.
- checksums.yaml +7 -0
- data/lib/ast/builder.rb +100 -0
- data/lib/ast/lexical_variables_enumerator.rb +34 -0
- data/lib/ast/method_definition.rb +37 -0
- data/lib/ast/nodes.rb +208 -0
- data/lib/ast/printer.rb +99 -0
- data/lib/ast/translator.rb +264 -0
- data/lib/ast/visitor.rb +173 -0
- data/lib/config/configuration.rb +18 -0
- data/lib/config/os_configuration.rb +56 -0
- data/lib/entity.rb +11 -0
- data/lib/ikra.rb +7 -0
- data/lib/parsing.rb +32 -0
- data/lib/resources/cuda/block_function_head.cpp +1 -0
- data/lib/resources/cuda/env_builder_copy_array.cpp +4 -0
- data/lib/resources/cuda/header.cpp +46 -0
- data/lib/resources/cuda/kernel.cpp +8 -0
- data/lib/resources/cuda/kernel_launcher.cpp +28 -0
- data/lib/resources/cuda/soa_header.cpp +4 -0
- data/lib/scope.rb +166 -0
- data/lib/sourcify/Gemfile +10 -0
- data/lib/sourcify/HISTORY.txt +88 -0
- data/lib/sourcify/LICENSE +20 -0
- data/lib/sourcify/README.rdoc +352 -0
- data/lib/sourcify/Rakefile +111 -0
- data/lib/sourcify/lib/sourcify.rb +44 -0
- data/lib/sourcify/lib/sourcify/common/parser/converter.rb +29 -0
- data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/comment.rb +23 -0
- data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/counter.rb +43 -0
- data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/dstring.rb +58 -0
- data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/extensions.rb +140 -0
- data/lib/sourcify/lib/sourcify/common/parser/raw_scanner/heredoc.rb +26 -0
- data/lib/sourcify/lib/sourcify/common/parser/source_code.rb +45 -0
- data/lib/sourcify/lib/sourcify/common/ragel/common.rl +5 -0
- data/lib/sourcify/lib/sourcify/common/ragel/expressions.rl +38 -0
- data/lib/sourcify/lib/sourcify/common/ragel/machines.rl +317 -0
- data/lib/sourcify/lib/sourcify/errors.rb +4 -0
- data/lib/sourcify/lib/sourcify/method.rb +138 -0
- data/lib/sourcify/lib/sourcify/method/methods.rb +3 -0
- data/lib/sourcify/lib/sourcify/method/methods/to_raw_source.rb +30 -0
- data/lib/sourcify/lib/sourcify/method/methods/to_sexp.rb +30 -0
- data/lib/sourcify/lib/sourcify/method/methods/to_source.rb +30 -0
- data/lib/sourcify/lib/sourcify/method/parser.rb +110 -0
- data/lib/sourcify/lib/sourcify/method/parser/converter.rb +8 -0
- data/lib/sourcify/lib/sourcify/method/parser/raw_scanner.rb +2494 -0
- data/lib/sourcify/lib/sourcify/method/parser/raw_scanner.rl +144 -0
- data/lib/sourcify/lib/sourcify/method/parser/raw_scanner_extensions.rb +68 -0
- data/lib/sourcify/lib/sourcify/method/parser/scanner.rb +52 -0
- data/lib/sourcify/lib/sourcify/method/parser/source_code.rb +8 -0
- data/lib/sourcify/lib/sourcify/patches.rb +63 -0
- data/lib/sourcify/lib/sourcify/proc.rb +183 -0
- data/lib/sourcify/lib/sourcify/proc/methods.rb +3 -0
- data/lib/sourcify/lib/sourcify/proc/methods/source_location.rb +61 -0
- data/lib/sourcify/lib/sourcify/proc/methods/to_raw_source.rb +20 -0
- data/lib/sourcify/lib/sourcify/proc/methods/to_sexp.rb +40 -0
- data/lib/sourcify/lib/sourcify/proc/methods/to_source.rb +48 -0
- data/lib/sourcify/lib/sourcify/proc/parser.rb +51 -0
- data/lib/sourcify/lib/sourcify/proc/parser/converter.rb +8 -0
- data/lib/sourcify/lib/sourcify/proc/parser/normalizer.rb +43 -0
- data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner.rb +2498 -0
- data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner.rl +149 -0
- data/lib/sourcify/lib/sourcify/proc/parser/raw_scanner_extensions.rb +74 -0
- data/lib/sourcify/lib/sourcify/proc/parser/scanner.rb +49 -0
- data/lib/sourcify/lib/sourcify/proc/parser/source_code.rb +8 -0
- data/lib/sourcify/lib/sourcify/version.rb +3 -0
- data/lib/sourcify/sourcify.gemspec +31 -0
- data/lib/sourcify/spec/dump_object_space_procs.rb +84 -0
- data/lib/sourcify/spec/method/encoding_from_def_end_block_spec.rb +33 -0
- data/lib/sourcify/spec/method/encoding_from_define_method_spec.rb +37 -0
- data/lib/sourcify/spec/method/others_from_def_end_block_spec.rb +49 -0
- data/lib/sourcify/spec/method/others_from_define_method_spec.rb +63 -0
- data/lib/sourcify/spec/method/raw_scanner/block_comment_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/double_colons_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/double_quote_str_w_interpolation_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/double_quote_str_wo_interpolation_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/heredoc_w_indent_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/heredoc_wo_indent_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/kw_block_start_alias1_spec.rb +20 -0
- data/lib/sourcify/spec/method/raw_scanner/kw_block_start_alias2_spec.rb +20 -0
- data/lib/sourcify/spec/method/raw_scanner/per_line_comment_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/single_quote_str_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/slash_operator_spec.rb +8 -0
- data/lib/sourcify/spec/method/raw_scanner/spec_helper.rb +80 -0
- data/lib/sourcify/spec/method/spec_helper.rb +1 -0
- data/lib/sourcify/spec/method/to_raw_source_spec.rb +31 -0
- data/lib/sourcify/spec/method/to_raw_source_w_specified_strip_enclosure_spec.rb +148 -0
- data/lib/sourcify/spec/method/to_sexp_from_def_end_block_w_variables_spec.rb +46 -0
- data/lib/sourcify/spec/method/to_sexp_from_def_end_block_within_irb_spec.rb +38 -0
- data/lib/sourcify/spec/method/to_sexp_from_def_end_block_within_pry_spec.rb +38 -0
- data/lib/sourcify/spec/method/to_sexp_from_define_method_w_multi_blocks_and_specified_attached_to_spec.rb +56 -0
- data/lib/sourcify/spec/method/to_sexp_from_define_method_w_variables_spec.rb +52 -0
- data/lib/sourcify/spec/method/to_sexp_from_define_method_within_irb_spec.rb +42 -0
- data/lib/sourcify/spec/method/to_sexp_from_define_method_within_pry_spec.rb +42 -0
- data/lib/sourcify/spec/method/to_sexp_w_specified_strip_enclosure_spec.rb +74 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_19_extras_spec.rb +23 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_begin_spec.rb +35 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_case_spec.rb +35 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_class_spec.rb +51 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_do_end_block_spec.rb +33 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_for_spec.rb +126 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_if_spec.rb +83 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_literal_keyword_spec.rb +141 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_method_spec.rb +33 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_module_spec.rb +59 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_unless_spec.rb +83 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_until_spec.rb +179 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_nested_while_spec.rb +179 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_w_singleton_method_spec.rb +19 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_within_irb_spec.rb +30 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_block_within_pry_spec.rb +45 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_w_multi_blocks_and_many_matches_spec.rb +30 -0
- data/lib/sourcify/spec/method/to_source_from_def_end_w_multi_blocks_and_single_match_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_braced_block_spec.rb +113 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_do_end_block_spec.rb +145 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_many_matches_spec.rb +56 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_single_match_spec.rb +73 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_many_matches_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_no_match_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_and_single_match_spec.rb +28 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_attached_to_spec.rb +103 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_many_matches_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_no_match_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_body_matcher_and_single_match_spec.rb +28 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_w_multi_blocks_and_specified_ignore_nested_spec.rb +36 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_within_irb_spec.rb +32 -0
- data/lib/sourcify/spec/method/to_source_from_define_method_within_pry_spec.rb +49 -0
- data/lib/sourcify/spec/method/to_source_magic_file_var_spec.rb +176 -0
- data/lib/sourcify/spec/method/to_source_magic_line_var_spec.rb +298 -0
- data/lib/sourcify/spec/method/to_source_w_specified_strip_enclosure_spec.rb +39 -0
- data/lib/sourcify/spec/no_method/unsupported_platform_spec.rb +26 -0
- data/lib/sourcify/spec/proc/19x_extras.rb +27 -0
- data/lib/sourcify/spec/proc/created_on_the_fly_proc_spec.rb +80 -0
- data/lib/sourcify/spec/proc/encoding_spec.rb +36 -0
- data/lib/sourcify/spec/proc/others_spec.rb +40 -0
- data/lib/sourcify/spec/proc/raw_scanner/block_comment_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/double_colons_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/double_quote_str_w_interpolation_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/double_quote_str_wo_interpolation_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/heredoc_w_indent_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/heredoc_wo_indent_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/kw_block_start_alias1_spec.rb +20 -0
- data/lib/sourcify/spec/proc/raw_scanner/kw_block_start_alias2_spec.rb +20 -0
- data/lib/sourcify/spec/proc/raw_scanner/per_line_comment_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/single_quote_str_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/slash_operator_spec.rb +8 -0
- data/lib/sourcify/spec/proc/raw_scanner/spec_helper.rb +63 -0
- data/lib/sourcify/spec/proc/readme +5 -0
- data/lib/sourcify/spec/proc/spec_helper.rb +1 -0
- data/lib/sourcify/spec/proc/to_raw_source_spec.rb +33 -0
- data/lib/sourcify/spec/proc/to_raw_source_w_specified_strip_enclosure_spec.rb +69 -0
- data/lib/sourcify/spec/proc/to_sexp_from_multi_blocks_w_specified_attached_to_spec.rb +46 -0
- data/lib/sourcify/spec/proc/to_sexp_variables_spec.rb +146 -0
- data/lib/sourcify/spec/proc/to_sexp_w_specified_strip_enclosure_spec.rb +60 -0
- data/lib/sourcify/spec/proc/to_sexp_within_irb_spec.rb +146 -0
- data/lib/sourcify/spec/proc/to_sexp_within_pry_spec.rb +149 -0
- data/lib/sourcify/spec/proc/to_source_from_braced_block_w_nested_braced_block_spec.rb +33 -0
- data/lib/sourcify/spec/proc/to_source_from_braced_block_w_nested_hash_spec.rb +82 -0
- data/lib/sourcify/spec/proc/to_source_from_braced_block_wo_nesting_complication_spec.rb +46 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_begin_spec.rb +35 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_case_spec.rb +35 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_class_spec.rb +89 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_do_end_block_spec.rb +33 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_for_spec.rb +132 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_if_spec.rb +87 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_literal_keyword_spec.rb +103 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_method_spec.rb +33 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_module_spec.rb +49 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_unless_spec.rb +87 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_until_spec.rb +189 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_w_nested_while_spec.rb +189 -0
- data/lib/sourcify/spec/proc/to_source_from_do_end_block_wo_nesting_complication_spec.rb +46 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_many_matches_spec.rb +43 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_single_match_spec.rb +20 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_many_matches_spec.rb +45 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_no_match_spec.rb +45 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_and_single_match_spec.rb +22 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_attached_to_spec.rb +84 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_many_matches_spec.rb +45 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_no_match_spec.rb +45 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_body_matcher_and_single_match_spec.rb +22 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_blocks_w_specified_ignore_nested_spec.rb +43 -0
- data/lib/sourcify/spec/proc/to_source_from_multi_do_end_blocks_w_single_match_spec.rb +31 -0
- data/lib/sourcify/spec/proc/to_source_magic_file_var_spec.rb +127 -0
- data/lib/sourcify/spec/proc/to_source_magic_line_var_spec.rb +127 -0
- data/lib/sourcify/spec/proc/to_source_variables_spec.rb +29 -0
- data/lib/sourcify/spec/proc/to_source_w_specified_strip_enclosure_spec.rb +33 -0
- data/lib/sourcify/spec/proc/to_source_within_irb_spec.rb +38 -0
- data/lib/sourcify/spec/proc/to_source_within_pry_spec.rb +61 -0
- data/lib/sourcify/spec/raw_scanner/block_comment_shared_spec.rb +57 -0
- data/lib/sourcify/spec/raw_scanner/double_colons_shared_spec.rb +11 -0
- data/lib/sourcify/spec/raw_scanner/double_quote_str_w_interpolation_shared_spec.rb +60 -0
- data/lib/sourcify/spec/raw_scanner/double_quote_str_wo_interpolation_shared_spec.rb +86 -0
- data/lib/sourcify/spec/raw_scanner/heredoc_w_indent_shared_spec.rb +69 -0
- data/lib/sourcify/spec/raw_scanner/heredoc_wo_indent_shared_spec.rb +70 -0
- data/lib/sourcify/spec/raw_scanner/kw_block_start_alias1_shared_spec.rb +73 -0
- data/lib/sourcify/spec/raw_scanner/kw_block_start_alias2_shared_spec.rb +73 -0
- data/lib/sourcify/spec/raw_scanner/per_line_comment_shared_spec.rb +32 -0
- data/lib/sourcify/spec/raw_scanner/shared_specs.rb +3 -0
- data/lib/sourcify/spec/raw_scanner/single_quote_str_shared_spec.rb +79 -0
- data/lib/sourcify/spec/raw_scanner/slash_operator_shared_spec.rb +71 -0
- data/lib/sourcify/spec/run_build.sh +25 -0
- data/lib/sourcify/spec/spec_helper.rb +130 -0
- data/lib/symbolic/symbolic.rb +248 -0
- data/lib/symbolic/visitor.rb +51 -0
- data/lib/translator/block_translator.rb +123 -0
- data/lib/translator/command_translator.rb +421 -0
- data/lib/translator/last_returns_visitor.rb +57 -0
- data/lib/translator/local_variables_enumerator.rb +35 -0
- data/lib/translator/method_translator.rb +24 -0
- data/lib/translator/translator.rb +49 -0
- data/lib/type_aware_array.rb +71 -0
- data/lib/types/array_type.rb +51 -0
- data/lib/types/class_type.rb +128 -0
- data/lib/types/object_tracer.rb +162 -0
- data/lib/types/primitive_type.rb +73 -0
- data/lib/types/ruby_extension.rb +67 -0
- data/lib/types/ruby_type.rb +45 -0
- data/lib/types/type_inference.rb +382 -0
- data/lib/types/union_type.rb +155 -0
- 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
|