ruby-libjit 0.1.0

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.
data/ext/extconf.rb ADDED
@@ -0,0 +1,100 @@
1
+ require 'mkmf'
2
+
3
+ if not have_library('jit', 'jit_init', ["jit/jit.h"]) then
4
+ $stderr.puts "libjit not found"
5
+ exit 1
6
+ end
7
+
8
+ if not have_macro("SIZEOF_VALUE", "ruby.h") then
9
+ check_sizeof("VALUE", "ruby.h")
10
+ end
11
+
12
+ if not have_macro("SIZEOF_ID", "ruby.h") then
13
+ check_sizeof("ID", "ruby.h")
14
+ end
15
+
16
+ if have_macro("_GNU_SOURCE", "ruby.h") then
17
+ $defs.push("-DRUBY_DEFINES_GNU_SOURCE")
18
+ end
19
+
20
+ have_func("rb_class_boot", "ruby.h")
21
+ have_func("rb_errinfo", "ruby.h")
22
+ have_func('fmemopen')
23
+ have_func("rb_ensure", "ruby.h")
24
+
25
+ if have_header('ruby/node.h') then
26
+ # ruby.h defines HAVE_RUBY_NODE_H, even though it is not there
27
+ $defs.push("-DREALLY_HAVE_RUBY_NODE_H")
28
+ elsif have_header('node.h') then
29
+ # okay
30
+ else
31
+ $defs.push("-DNEED_MINIMAL_NODE")
32
+ end
33
+
34
+ have_header('env.h')
35
+
36
+ checking_for("whether VALUE is a pointer") do
37
+ if not try_link(<<"SRC")
38
+ #include <ruby.h>
39
+ int main()
40
+ {
41
+ VALUE v;
42
+ v /= 5;
43
+ }
44
+ SRC
45
+ then
46
+ $defs.push("-DVALUE_IS_PTR");
47
+ end
48
+ end
49
+
50
+ if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'rbx' then
51
+ $defs.push("-DHAVE_RUBINIUS")
52
+ end
53
+
54
+ rb_files = Dir['*.rb']
55
+ rpp_files = Dir['*.rpp']
56
+ generated_files = rpp_files.map { |f| f.sub(/\.rpp$/, '') }
57
+
58
+ srcs = Dir['*.c']
59
+ generated_files.each do |f|
60
+ if f =~ /\.c$/ then
61
+ srcs << f
62
+ end
63
+ end
64
+ srcs.uniq!
65
+ $objs = srcs.map { |f| f.sub(/\.c$/, ".#{$OBJEXT}") }
66
+
67
+ if Config::CONFIG['CC'] == 'gcc' then
68
+ # $CFLAGS << ' -Wall -g -pedantic -Wno-long-long'
69
+ $CFLAGS << ' -Wall -g'
70
+ end
71
+
72
+ create_makefile("jit")
73
+
74
+ append_to_makefile = ''
75
+
76
+ rpp_files.each do |rpp_file|
77
+ dest_file = rpp_file.sub(/\.rpp$/, '')
78
+ append_to_makefile << <<END
79
+ #{dest_file}: #{rpp_file} #{rb_files.join(' ')}
80
+ $(RUBY) rubypp.rb #{rpp_file} #{dest_file}
81
+ END
82
+ end
83
+
84
+ generated_headers = generated_files.select { |x| x =~ /\.h$/ || x =~ /\.inc$/ }
85
+ append_to_makefile << <<END
86
+ $(OBJS): #{generated_headers.join(' ')}
87
+ clean: clean_generated_files
88
+ clean_generated_files:
89
+ @$(RM) #{generated_files.join(' ')}
90
+
91
+ install: $(includedir)/rubyjit.h
92
+
93
+ $(includedir)/rubyjit.h: rubyjit.h
94
+ $(INSTALL_PROG) rubyjit.h $(includedir)
95
+ END
96
+
97
+ File.open('Makefile', 'a') do |makefile|
98
+ makefile.puts(append_to_makefile)
99
+ end
100
+
data/ext/insns.inc.rpp ADDED
@@ -0,0 +1,204 @@
1
+ #ruby <<END
2
+
3
+ V = :value
4
+ L = :label_ptr
5
+ B = :label
6
+ N = :nint
7
+ T = :type_t
8
+ _ = :void
9
+
10
+ def incoming_args(arg_types)
11
+ num_args = arg_types.length
12
+ return (1..num_args).map { |n| ", VALUE arg#{n}" }.join
13
+ end
14
+
15
+ def declaration(name, type)
16
+ case type
17
+ when V then return "jit_value_t #{name};"
18
+ when L then return "jit_label_t * #{name};"
19
+ when B then return "jit_label_t * #{name};"
20
+ when N then return "jit_nint #{name};"
21
+ when T then return "jit_type_t #{name};"
22
+ when :void then nil
23
+ else raise "Invalid type #{type}"
24
+ end
25
+ end
26
+
27
+ def write_declaration(name, type, indent)
28
+ d = declaration(name, type)
29
+ if d then
30
+ puts "#{' '*indent}#{d}"
31
+ end
32
+ end
33
+
34
+ def ruby_type(type)
35
+ case type
36
+ when V then return "rb_cValue"
37
+ when L then return "rb_cLabel"
38
+ when B then return "rb_cLabel"
39
+ when N then return "rb_cFixnum"
40
+ when T then return "rb_cType"
41
+ else raise "Invalid type #{type}"
42
+ end
43
+ end
44
+
45
+ def jit_type(type)
46
+ case type
47
+ when V then return "struct _jit_value"
48
+ when L then return "jit_label_t"
49
+ when B then return "jit_label_t"
50
+ when T then return "struct _jit_type"
51
+ else raise "Invalid type #{type}"
52
+ end
53
+ end
54
+
55
+ def get_value(type, arg, j_arg)
56
+ case type
57
+ when N then
58
+ return "#{j_arg} = NUM2INT(#{arg})"
59
+ else
60
+ return "Data_Get_Struct(#{arg}, #{jit_type(type)}, #{j_arg})"
61
+ end
62
+ end
63
+
64
+ def jit_insn_args(arg_types)
65
+ num_args = arg_types.length
66
+ arg_list = (1..num_args).map do |n|
67
+ case arg_types[n-1]
68
+ when B then ", *j_arg#{n}"
69
+ else ", j_arg#{n}"
70
+ end
71
+ end
72
+ return arg_list.join
73
+ end
74
+
75
+ def write_insn(name, retval_type, arg_types)
76
+ num_args = arg_types.length
77
+ an = [?a, ?e, ?i, ?o, ?u].include?(name[0])
78
+ puts "/* Generate a#{an} #{name} instruction (see the libjit documentation for more"
79
+ puts " * details. */"
80
+ puts "static VALUE function_insn_#{name}(VALUE self#{incoming_args(arg_types)})"
81
+ puts "{"
82
+ puts " jit_function_t function;"
83
+ write_declaration('retval', retval_type, 2)
84
+ arg_types.each_with_index do |type, n|
85
+ write_declaration("j_arg#{n+1}", type, 2)
86
+ end
87
+ puts
88
+ arg_types.each_with_index do |type, n|
89
+ puts " check_type(\"arg#{n+1}\", #{ruby_type(type)}, arg#{n+1});"
90
+ end
91
+ puts
92
+ puts " Data_Get_Struct(self, struct _jit_function, function);"
93
+ arg_types.each_with_index do |type, n|
94
+ puts " " + get_value(type, "arg#{n+1}", "j_arg#{n+1}") + ";"
95
+ end
96
+ puts
97
+ if retval_type == V then
98
+ puts " retval = jit_insn_#{name}(function#{jit_insn_args(arg_types)});"
99
+ puts " return Data_Wrap_Struct(rb_cValue, 0, 0, retval);"
100
+ elsif retval_type == :void then
101
+ puts " jit_insn_#{name}(function#{jit_insn_args(arg_types)});"
102
+ puts " return Qnil;"
103
+ else
104
+ raise "Invalid retval type #{retval_type}"
105
+ end
106
+ puts "}"
107
+ end
108
+
109
+ insns = [
110
+ [ 'load' , V, V ] ,
111
+ [ 'store' , _, V, V ] ,
112
+ [ 'dup' , V, V ] ,
113
+ [ 'add' , V, V, V ] ,
114
+ [ 'add_ovf' , V, V, V ] ,
115
+ [ 'sub' , V, V, V ] ,
116
+ [ 'sub_ovf' , V, V, V ] ,
117
+ [ 'mul' , V, V, V ] ,
118
+ [ 'mul_ovf' , V, V, V ] ,
119
+ [ 'div' , V, V, V ] ,
120
+ [ 'rem' , V, V, V ] ,
121
+ [ 'rem_ieee' , V, V, V ] ,
122
+ [ 'neg' , V, V ] ,
123
+ [ 'and' , V, V, V ] ,
124
+ [ 'or' , V, V, V ] ,
125
+ [ 'xor' , V, V, V ] ,
126
+ [ 'not' , V, V ] ,
127
+ [ 'shl' , V, V, V ] ,
128
+ [ 'shr' , V, V, V ] ,
129
+ [ 'ushr' , V, V, V ] ,
130
+ [ 'sshr' , V, V, V ] ,
131
+ [ 'eq' , V, V, V ] ,
132
+ [ 'ne' , V, V, V ] ,
133
+ [ 'lt' , V, V, V ] ,
134
+ [ 'le' , V, V, V ] ,
135
+ [ 'gt' , V, V, V ] ,
136
+ [ 'ge' , V, V, V ] ,
137
+ [ 'cmpl' , V, V, V ] ,
138
+ [ 'cmpg' , V, V, V ] ,
139
+ [ 'to_bool' , V, V ] ,
140
+ [ 'to_not_bool' , V, V ] ,
141
+ [ 'acos' , V, V ] ,
142
+ [ 'asin' , V, V ] ,
143
+ [ 'atan' , V, V ] ,
144
+ [ 'atan2' , V, V, V ] ,
145
+ [ 'ceil' , V, V ] ,
146
+ [ 'cos' , V, V ] ,
147
+ [ 'cosh' , V, V ] ,
148
+ [ 'exp' , V, V ] ,
149
+ [ 'floor' , V, V ] ,
150
+ [ 'log' , V, V ] ,
151
+ [ 'log10' , V, V ] ,
152
+ [ 'pow' , V, V, V ] ,
153
+ [ 'rint' , V, V ] ,
154
+ [ 'round' , V, V ] ,
155
+ [ 'sin' , V, V ] ,
156
+ [ 'sinh' , V, V ] ,
157
+ [ 'sqrt' , V, V ] ,
158
+ [ 'tan' , V, V ] ,
159
+ [ 'tanh' , V, V ] ,
160
+ [ 'is_nan' , V, V ] ,
161
+ [ 'is_finite' , V, V ] ,
162
+ [ 'is_inf' , V, V ] ,
163
+ [ 'abs' , V, V ] ,
164
+ [ 'min' , V, V, V ] ,
165
+ [ 'max' , V, V, V ] ,
166
+ [ 'sign' , V, V ] ,
167
+ [ 'branch' , _, L ] ,
168
+ [ 'branch_if' , _, V, L ] ,
169
+ [ 'branch_if_not' , _, V, L ] ,
170
+ [ 'label' , _, L ] ,
171
+ [ 'address_of' , V, V ] ,
172
+ [ 'address_of_label' , V, L ] ,
173
+ [ 'store_relative' , _, V, N, V ] ,
174
+ [ 'load_relative' , V, V, N, T ] ,
175
+ [ 'add_relative' , V ,V, N ] ,
176
+ [ 'memcpy' , _, V, V, V ] ,
177
+ [ 'memmove' , _, V, V, V ] ,
178
+ [ 'memset' , _, V, V, V ] ,
179
+ [ 'alloca' , V, V ] ,
180
+ [ 'load_elem' , V, V, V, T ] ,
181
+ [ 'store_elem' , _, V, V, V ] ,
182
+ [ 'move_blocks_to_end' , _, B, B ] ,
183
+ [ 'move_blocks_to_start' , _, B, B ] ,
184
+ [ 'push' , _, V ] ,
185
+ [ 'push_ptr' , _, V, T ] ,
186
+ [ 'pop_stack' , _, N ] ,
187
+ [ 'stack_top' , V ] ,
188
+ ]
189
+
190
+ insns.each do |name, retval_type, *arg_types|
191
+ write_insn(name, retval_type, arg_types)
192
+ puts
193
+ end
194
+
195
+ puts "static void init_insns()"
196
+ puts "{"
197
+ insns.each do |name, retval_type, *arg_types|
198
+ num_args = arg_types.length
199
+ puts " rb_define_method(rb_cFunction, \"insn_#{name}\", function_insn_#{name}, #{num_args});"
200
+ end
201
+ puts "}"
202
+
203
+ END
204
+