ruby-libjit 0.1.0

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