crystalizer 0.2.2
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/Changelog +27 -0
- data/README +79 -0
- data/Rakefile +24 -0
- data/TODO +14 -0
- data/VERSION +1 -0
- data/benchmarks/bench.rb +129 -0
- data/benchmarks/concretize_test.rb +26 -0
- data/benchmarks/extconf.rb +10 -0
- data/benchmarks/tak_rb.rb +7 -0
- data/benchmarks/tak_so.rb +7 -0
- data/benchmarks/tak_source.rb +16 -0
- data/bin/rb2cx +162 -0
- data/doc/eval2c.txt +246 -0
- data/doc/gen_html.rb +26 -0
- data/doc/html_template +10 -0
- data/doc/index.txt +169 -0
- data/doc/limitations.txt +529 -0
- data/doc/optimizations.txt +185 -0
- data/doc/rb2cx.txt +130 -0
- data/doc/style.css +27 -0
- data/lib/concretizer.rb +3 -0
- data/lib/ruby2cext/c_function.rb +617 -0
- data/lib/ruby2cext/common_node_comp.rb +1412 -0
- data/lib/ruby2cext/compiler.rb +311 -0
- data/lib/ruby2cext/concretize.rb +269 -0
- data/lib/ruby2cext/error.rb +15 -0
- data/lib/ruby2cext/eval2c.rb +126 -0
- data/lib/ruby2cext/parser.rb +36 -0
- data/lib/ruby2cext/plugin.rb +24 -0
- data/lib/ruby2cext/plugins/builtin_methods.rb +817 -0
- data/lib/ruby2cext/plugins/cache_call.rb +293 -0
- data/lib/ruby2cext/plugins/case_optimize.rb +102 -0
- data/lib/ruby2cext/plugins/const_cache.rb +36 -0
- data/lib/ruby2cext/plugins/direct_self_call.rb +70 -0
- data/lib/ruby2cext/plugins/inline_builtin.rb +797 -0
- data/lib/ruby2cext/plugins/inline_methods.rb +68 -0
- data/lib/ruby2cext/plugins/ivar_cache.rb +147 -0
- data/lib/ruby2cext/plugins/require_include.rb +69 -0
- data/lib/ruby2cext/plugins/util.rb +154 -0
- data/lib/ruby2cext/plugins/warnings.rb +121 -0
- data/lib/ruby2cext/scopes.rb +225 -0
- data/lib/ruby2cext/str_to_c_strlit.rb +12 -0
- data/lib/ruby2cext/tools.rb +80 -0
- data/lib/ruby2cext/version.rb +22 -0
- data/results +68 -0
- data/setup.rb +1585 -0
- data/stuff/builtin_methods.rb +69 -0
- data/stuff/builtin_methods_test.rb +37 -0
- data/test/bootstrap.rb +10 -0
- data/test/causes_crash_all_opts.rb +1165 -0
- data/test/eval2c/test_eval2c.rb +37 -0
- data/test/temp_17.rb +16 -0
- data/test/temp_18.rb +8 -0
- data/test/temp_19.rb +8 -0
- data/test/temp_2.rb +7 -0
- data/test/temp_20.rb +5 -0
- data/test/temp_21.rb +161 -0
- data/test/temp_22.rb +7 -0
- data/test/temp_23.rb +7 -0
- data/test/temp_24.rb +219 -0
- data/test/temp_25.rb +7 -0
- data/test/temp_26.rb +11 -0
- data/test/temp_27.rb +11 -0
- data/test/temp_28.rb +9 -0
- data/test/temp_29.rb +9 -0
- data/test/temp_3.rb +0 -0
- data/test/temp_30.rb +0 -0
- data/test/temp_31.rb +10 -0
- data/test/temp_32.rb +10 -0
- data/test/temp_33.rb +15 -0
- data/test/temp_34.rb +15 -0
- data/test/temp_35.rb +7 -0
- data/test/temp_36.rb +7 -0
- data/test/temp_37.rb +10 -0
- data/test/temp_38.rb +10 -0
- data/test/temp_39.rb +0 -0
- data/test/temp_4.rb +7 -0
- data/test/temp_40.rb +50 -0
- data/test/temp_41.rb +50 -0
- data/test/temp_42.rb +8 -0
- data/test/temp_43.rb +8 -0
- data/test/temp_44.rb +0 -0
- data/test/temp_48.rb +7 -0
- data/test/temp_49.rb +7 -0
- data/test/temp_5.rb +7 -0
- data/test/temp_59.rb +7 -0
- data/test/temp_6.rb +7 -0
- data/test/temp_60.rb +7 -0
- data/test/temp_68.rb +239 -0
- data/test/temp_7.rb +7 -0
- data/test/temp_70.rb +7 -0
- data/test/temp_71.rb +7 -0
- data/test/temp_72.rb +13 -0
- data/test/temp_73.rb +7 -0
- data/test/temp_74.rb +7 -0
- data/test/temp_76.rb +7 -0
- data/test/temp_77.rb +13 -0
- data/test/temp_79.rb +7 -0
- data/test/temp_8.rb +14 -0
- data/test/temp_81.rb +14 -0
- data/test/temp_83.rb +0 -0
- data/test/temp_84.rb +7 -0
- data/test/temp_85.rb +7 -0
- data/test/temp_86.rb +14 -0
- data/test/temp_87.rb +7 -0
- data/test/temp_88.rb +7 -0
- data/test/temp_89.rb +7 -0
- data/test/temp_9.rb +14 -0
- data/test/temp_90.rb +0 -0
- data/test/temp_91.rb +7 -0
- data/test/temp_92.rb +7 -0
- data/test/temp_93.rb +7 -0
- data/test/temp_94.rb +7 -0
- data/test/temp_95.rb +7 -0
- data/test/temp_96.rb +0 -0
- data/test/temp_97.rb +0 -0
- data/test/temp_98.rb +7 -0
- data/test/temp_99.rb +7 -0
- data/test/test_concretize.rb +132 -0
- data/test/test_concretize_all.rb +15 -0
- data/test/test_crystalize_block.rb +73 -0
- data/test/test_files/test.rb +615 -0
- data/test/test_files/vmode_test.rb +73 -0
- data/test/test_files/warn_test.rb +35 -0
- data/test/test_syntax.rb +25 -0
- metadata +268 -0
data/doc/eval2c.txt
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
|
2
|
+
h1. Eval2C
|
3
|
+
|
4
|
+
Eval2C is a class that allows the compilation of Ruby code to a C extension at
|
5
|
+
runtime. The compiled C extension will be <code>require</code>d automatically
|
6
|
+
and the compiled code will be available as a Proc.
|
7
|
+
|
8
|
+
It is easy to integrate Eval2C into existing scripts or libraries to improve
|
9
|
+
performance. It is also pretty simple to provide fallback code for when
|
10
|
+
Ruby2CExtension is not available.
|
11
|
+
|
12
|
+
|
13
|
+
h2. Basic Usage
|
14
|
+
|
15
|
+
Here is an example:
|
16
|
+
|
17
|
+
PRE
|
18
|
+
require "ruby2cext/eval2c"
|
19
|
+
|
20
|
+
$e2c = Ruby2CExtension::Eval2C.new
|
21
|
+
|
22
|
+
$e2c.toplevel_eval("puts 'hello'") # prints hello
|
23
|
+
PREEND
|
24
|
+
|
25
|
+
First you need to create an Eval2C instance, this instance basically stores
|
26
|
+
the options/configuration. In the above example no options were given, so the
|
27
|
+
defaults are used. The available options are explained below.
|
28
|
+
|
29
|
+
The last line of the example does what the method name suggests: the string of
|
30
|
+
Ruby code is evaluated at the toplevel (i.e. not inside any class scope). To
|
31
|
+
be more precise, that last line is equivalent to this Ruby code:
|
32
|
+
|
33
|
+
PRE
|
34
|
+
$some_global_var = proc { puts 'hello' }
|
35
|
+
$some_global_var.call
|
36
|
+
PREEND
|
37
|
+
|
38
|
+
The proc is compiled to a C extension, that C expension is then
|
39
|
+
<code>require</code>d and finally the proc is called.
|
40
|
+
|
41
|
+
The implementation of @toplevel_eval@ is actually pretty simple:
|
42
|
+
|
43
|
+
PRE
|
44
|
+
def toplevel_eval(code_str)
|
45
|
+
compile_to_proc(code_str).call
|
46
|
+
end
|
47
|
+
PREEND
|
48
|
+
|
49
|
+
So the main work is done by @compile_to_proc@, which can also be used
|
50
|
+
directly:
|
51
|
+
|
52
|
+
PRE
|
53
|
+
$e2c.compile_to_proc("|a,b| a+b").call(2, 3) # => 5
|
54
|
+
PREEND
|
55
|
+
|
56
|
+
There are some things to note: The proc won't have access to local variables
|
57
|
+
and it will be defined at toplevel, which is important for constant lookup:
|
58
|
+
|
59
|
+
PRE
|
60
|
+
SOME_CONST = :toplevel
|
61
|
+
|
62
|
+
class A
|
63
|
+
SOME_CONST = :A
|
64
|
+
$e2c.compile_to_proc("SOME_CONST").call # => :toplevel, not :A!
|
65
|
+
end
|
66
|
+
PREEND
|
67
|
+
|
68
|
+
Eval2C also offers equivalents to Ruby's @module_eval@/@class_eval@ and
|
69
|
+
@instance_eval@:
|
70
|
+
|
71
|
+
PRE
|
72
|
+
class A
|
73
|
+
$e2c.module_eval(self, %{
|
74
|
+
def initialize(x)
|
75
|
+
@x = x
|
76
|
+
end
|
77
|
+
def foo(y)
|
78
|
+
@x + y
|
79
|
+
end
|
80
|
+
})
|
81
|
+
end
|
82
|
+
|
83
|
+
A.new(5).foo(6) # => 11
|
84
|
+
|
85
|
+
$e2c.instance_eval("4321", "reverse") # => "1234"
|
86
|
+
PREEND
|
87
|
+
|
88
|
+
Their implementations also use @compile_to_proc@ and they are very similar to
|
89
|
+
the implementation of @toplevel_eval@:
|
90
|
+
|
91
|
+
PRE
|
92
|
+
def module_eval(mod, code_str)
|
93
|
+
mod.module_eval(&compile_to_proc(code_str))
|
94
|
+
end
|
95
|
+
alias :class_eval :module_eval
|
96
|
+
|
97
|
+
def instance_eval(object, code_str)
|
98
|
+
object.instance_eval(&compile_to_proc(code_str))
|
99
|
+
end
|
100
|
+
PREEND
|
101
|
+
|
102
|
+
With @module_eval@/@class_eval@ it is possible to selectively compile some
|
103
|
+
performance critical methods to C and leave the rest in Ruby.
|
104
|
+
|
105
|
+
But there is one more thing: @compile_methods@.
|
106
|
+
|
107
|
+
Defining the methods using @module_eval@ as in the last example, has at least
|
108
|
+
one downside: it won't play nice with syntax-highlighting text editors,
|
109
|
+
because the code of the methods is actually in a string. It would be much
|
110
|
+
nicer to @def@ the methods the normal way and then just compile them
|
111
|
+
afterwards.
|
112
|
+
|
113
|
+
Thanks to @compile_methods@ this is possible:
|
114
|
+
|
115
|
+
PRE
|
116
|
+
class A
|
117
|
+
def initialize(x)
|
118
|
+
@x = x
|
119
|
+
end
|
120
|
+
def foo(y)
|
121
|
+
@x + y
|
122
|
+
end
|
123
|
+
|
124
|
+
$e2c.compile_methods(self, :initialize, :foo)
|
125
|
+
end
|
126
|
+
|
127
|
+
A.new(5).foo(6) # => 11
|
128
|
+
PREEND
|
129
|
+
|
130
|
+
@compile_methods@ will grab the methods' node trees using RubyNode, compile
|
131
|
+
them to C and then replace the old methods with the C versions. The visibility
|
132
|
+
of the old methods will be preserved.
|
133
|
+
|
134
|
+
There are some limitations: @compile_methods@ only works with methods defined
|
135
|
+
using @def@ and the methods must not need a cref (for more informations on
|
136
|
+
what crefs are please see the respective section in
|
137
|
+
"limitations":limitations.html). This mainly means that constants must be
|
138
|
+
prefixed with a double colon: @Array@ needs a cref, while @::Array@ does not.
|
139
|
+
|
140
|
+
|
141
|
+
h2. Options
|
142
|
+
|
143
|
+
Eval2C is configured with an option hash, the available options are:
|
144
|
+
|
145
|
+
* @:path@: this is the path where the compiled extensions are stored, the
|
146
|
+
default is the directory @.ruby2cext@ in the current users home dir.
|
147
|
+
* @:prefix@: this is the prefix for the names of the generated extensions, the
|
148
|
+
names of the extensions are generated from this prefix and a SHA1 digest of
|
149
|
+
the code and options. The default is @"eval2c"@ and it is generally not
|
150
|
+
necessary to change it.
|
151
|
+
* @:plugins@: this is used to configure the options for the compilation
|
152
|
+
(compare "rb2cx":rb2cx.html) and it is another option hash. The default is
|
153
|
+
<code>{:optimizations => :all}</code>, but all of the following keys are
|
154
|
+
possible:
|
155
|
+
** @:warnings@: if set to @true@, then warnings about possible problems will
|
156
|
+
be sent to the logger (see below).
|
157
|
+
** @:require_include@: can be set to a single search path or an array of
|
158
|
+
search paths (equivalent to the @-I@ option of @rb2cx@).
|
159
|
+
** @:optimizations@: yet another option hash to configure the
|
160
|
+
"optimizations":optimizations.html. The valid keys are @:const_cache@,
|
161
|
+
@:builtin_methods@, @:inline_methods@ and @:case_optimize@, each with
|
162
|
+
@true@ or @false@ as value. To just use all optimizations it is also
|
163
|
+
possible to just use the symbol @:all@ instead of the hash.
|
164
|
+
* @:logger@: used for log messages, can be either @nil@ or an instance of
|
165
|
+
@Logger@ (<code>require "logger"</code>). The default is @nil@, which means
|
166
|
+
that no output is generated.
|
167
|
+
* @:force_recompile@: if this is set to @true@, then each generated extension
|
168
|
+
is (re)compiled, even if it is already available from a previous run. The
|
169
|
+
default is @false@.
|
170
|
+
|
171
|
+
Some examples:
|
172
|
+
|
173
|
+
PRE
|
174
|
+
Eval2C.new(:path => ".", :plugins => {})
|
175
|
+
Eval2C.new(:plugins => {:require_include=>[".", "../lib"], :optimizations=>:all})
|
176
|
+
Eval2C.new(:plugins => {:warnings=>true, :optimizations=>{:builtin_methods=>true}})
|
177
|
+
Eval2C.new(:prefix => "my_lib_name", :logger => Logger.new(STDOUT))
|
178
|
+
PREEND
|
179
|
+
|
180
|
+
|
181
|
+
h2. Implementation Details
|
182
|
+
|
183
|
+
The @compile_to_proc@ method works as follows:
|
184
|
+
|
185
|
+
# The name of the extension is determined from the given prefix combined with
|
186
|
+
the SHA1 digest of the Ruby code and some extra data (Ruby version,
|
187
|
+
Ruby2CExtension version and plugin options). So the code determines the
|
188
|
+
extension name and if the same code is compiled with the same version and
|
189
|
+
settings, the name will be the same. This allows very simple and efficient
|
190
|
+
caching of the compiled extensions.
|
191
|
+
# From the extension name a global variable name is constructed. The compiled
|
192
|
+
proc will be stored in that global variable by the generated C extension.
|
193
|
+
# If the extension with the generated name already exists, then we are
|
194
|
+
basically done and can skip this step. Otherwise the Ruby proc code is
|
195
|
+
translated to C and compiled to a C extension in the specified path.
|
196
|
+
# The generated or already existing C extension is <code>require</code>d.
|
197
|
+
# The global variable that now contains the compiled proc is read and the
|
198
|
+
result is returned.
|
199
|
+
|
200
|
+
The @compile_methods@ method works similar.
|
201
|
+
|
202
|
+
As mentioned above, this scheme allows very efficient caching of the C
|
203
|
+
extensions. Basically each extension is only compiled once when the
|
204
|
+
program/library is executed for the first time. In later runs the extension
|
205
|
+
will already exist and just be <code>require</code>d.
|
206
|
+
|
207
|
+
Adding the Ruby version and the Ruby2CExtension version to the digest avoids
|
208
|
+
problems if multiple versions of Ruby or Ruby2CExtension are installed and
|
209
|
+
used in parallel and it also guarantees that the extensions are automatically
|
210
|
+
recompiled if Ruby or Ruby2CExtension are updated.
|
211
|
+
|
212
|
+
|
213
|
+
h2. Using Eval2C Only When It Is Available
|
214
|
+
|
215
|
+
Having Ruby2CExtension as a hard dependency just for some speedup might not
|
216
|
+
be acceptable for many projects, in particular since Ruby2CExtension requires
|
217
|
+
that a C compiler is available at runtime.
|
218
|
+
|
219
|
+
An alternative that avoids the hard dependency is to use Ruby2CExtension only
|
220
|
+
if it is installed anyway and otherwise just execute the Ruby code as usual.
|
221
|
+
This works works very well if Eval2C and @compile_methods@ is used, for
|
222
|
+
example:
|
223
|
+
|
224
|
+
PRE
|
225
|
+
begin
|
226
|
+
require "ruby2cext/eval2c"
|
227
|
+
$e2c = Ruby2CExtension::Eval2C.new
|
228
|
+
rescue LoadError
|
229
|
+
$e2c = nil
|
230
|
+
end
|
231
|
+
|
232
|
+
class A
|
233
|
+
def initialize(x)
|
234
|
+
@x = x
|
235
|
+
end
|
236
|
+
def foo(y)
|
237
|
+
@x + y
|
238
|
+
end
|
239
|
+
|
240
|
+
$e2c && $e2c.compile_methods(self, :initialize, :foo)
|
241
|
+
end
|
242
|
+
PREEND
|
243
|
+
|
244
|
+
So if Ruby2CExtension is available, then the methods will be compiled and
|
245
|
+
fast, otherwise the Ruby code will just work as usual (but it might be a bit
|
246
|
+
slower of course).
|
data/doc/gen_html.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "redcloth"
|
2
|
+
|
3
|
+
Dir.chdir(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
template = File.read("html_template")
|
6
|
+
|
7
|
+
Dir["*.txt"].each { |fn|
|
8
|
+
txt = File.read(fn)
|
9
|
+
title = txt[/^h1. (.+?)$/, 1]
|
10
|
+
txt.gsub!(/^PRE\n/m, "<pre><code>")
|
11
|
+
txt.gsub!(/^PREEND$/, "</code></pre>")
|
12
|
+
cnt = 0
|
13
|
+
sections = []
|
14
|
+
txt.gsub!(/^h2\.\s(.+)$/) { sections << $1; "h2(#section#{cnt+=1}). #$1" }
|
15
|
+
unless sections.empty?
|
16
|
+
sect_list = "\nSections: "
|
17
|
+
cnt = 0
|
18
|
+
sect_list << sections.map { |s| "\"#{s}\":#section#{cnt+=1}" }.join(", ")
|
19
|
+
sect_list << ".\n\n"
|
20
|
+
txt.sub!(/\nh2\(/m, sect_list << "h2(")
|
21
|
+
end
|
22
|
+
html = RedCloth.new(txt).to_html
|
23
|
+
File.open("#{File.basename(fn, ".txt")}.html", "w") { |f|
|
24
|
+
f.puts(template % [title, html])
|
25
|
+
}
|
26
|
+
}
|
data/doc/html_template
ADDED
data/doc/index.txt
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
|
2
|
+
h1. Ruby2CExtension
|
3
|
+
|
4
|
+
Ruby2CExtension is a Ruby to C extension translator/compiler. It takes any
|
5
|
+
Ruby source file, parses it using Ruby's builtin parser and then translates
|
6
|
+
the abstract syntax tree into "equivalent" C extension code.
|
7
|
+
|
8
|
+
Let's say you have a Ruby file @foo.rb@. To translate it to a C extension and
|
9
|
+
then compile it, just run:
|
10
|
+
|
11
|
+
PRE
|
12
|
+
rb2cx foo.rb
|
13
|
+
PREEND
|
14
|
+
|
15
|
+
This will produce the files @foo.c@ and @foo.so@ (on Linux). @foo.c@ is the
|
16
|
+
generated C extension source code and @foo.so@ is the compiled C extension.
|
17
|
+
|
18
|
+
If @foo.rb@ is a library, you can just rename, move or delete @foo.rb@ (only
|
19
|
+
if you have a backup, of course) and your Ruby program will just use @foo.so@
|
20
|
+
instead.
|
21
|
+
|
22
|
+
If @foo.rb@ is a script, then it isn't possible to just run @foo.so@, because
|
23
|
+
Ruby does not support running C extensions directly, but you can do this:
|
24
|
+
|
25
|
+
PRE
|
26
|
+
ruby -r foo.so -e ""
|
27
|
+
PREEND
|
28
|
+
|
29
|
+
which should produce the same output as
|
30
|
+
|
31
|
+
PRE
|
32
|
+
ruby -r foo.rb -e ""
|
33
|
+
PREEND
|
34
|
+
|
35
|
+
|
36
|
+
h2. Why?
|
37
|
+
|
38
|
+
Well, like everybody else I wanted a faster Ruby and I also wanted to learn
|
39
|
+
about Ruby's internals, so I thought translating Ruby to C might be worth a
|
40
|
+
try...
|
41
|
+
|
42
|
+
The initial results were not as good as I had hoped, but they weren't bad
|
43
|
+
either: without optimizations the generated C extension is practically never
|
44
|
+
slower than the Ruby code and I found cases where it is more than twice as
|
45
|
+
fast, usually it is somewhere in between. But, starting from version 0.2.0,
|
46
|
+
Ruby2CExtension can use "optimizations":optimizations.html to *significantly
|
47
|
+
speedup* execution in many cases (*sometimes more than five times faster* than
|
48
|
+
normal Ruby).
|
49
|
+
|
50
|
+
Of course Ruby2CExtension can also be used as an obfuscator for Ruby code,
|
51
|
+
though this was not my main motivation.
|
52
|
+
|
53
|
+
|
54
|
+
h2. Requirements
|
55
|
+
|
56
|
+
Ruby2CExtension is developed for the Ruby 1.8 versions (only 1.8.4 and later).
|
57
|
+
It is currently tested with *Ruby 1.8.4, 1.8.5 and 1.8.6*. Only those versions
|
58
|
+
should be used, because Ruby2CExtension depends on Ruby internals that can
|
59
|
+
change between Ruby versions. If an untested Ruby version is used, then there
|
60
|
+
will be a warning. It might work for later 1.8 versions, but it definitely
|
61
|
+
won't work with Ruby 1.9.
|
62
|
+
|
63
|
+
Ruby2CExtension requires RubyNode to access Ruby's node trees (the AST).
|
64
|
+
RubyNode is available at
|
65
|
+
"http://rubynode.rubyforge.org/":http://rubynode.rubyforge.org/.
|
66
|
+
|
67
|
+
Ruby2CExtension is pure Ruby code, so it should work on all platforms that
|
68
|
+
Ruby supports, but it is currently only tested on Linux. There might be
|
69
|
+
problems with the automatic compilation of the generated C code on some
|
70
|
+
platforms (in particular on Windows).
|
71
|
+
|
72
|
+
|
73
|
+
h2. Download
|
74
|
+
|
75
|
+
* "Project page":http://rubyforge.org/projects/ruby2cext/
|
76
|
+
* "Download":http://rubyforge.org/frs/?group_id=1799
|
77
|
+
|
78
|
+
|
79
|
+
h2. Installation
|
80
|
+
|
81
|
+
Just run (as root):
|
82
|
+
|
83
|
+
PRE
|
84
|
+
gem install ruby2cext
|
85
|
+
PREEND
|
86
|
+
|
87
|
+
Or if you do not use the gem:
|
88
|
+
|
89
|
+
PRE
|
90
|
+
ruby setup.rb
|
91
|
+
PREEND
|
92
|
+
|
93
|
+
This will install Ruby2CExtension to the default locations. Optionally you
|
94
|
+
can supply some options to @setup.rb@ to customize the installation (see
|
95
|
+
@"ruby setup.rb --help"@).
|
96
|
+
|
97
|
+
|
98
|
+
h2. Features
|
99
|
+
|
100
|
+
Ruby2CExtension supports a very large subset of Ruby's features:
|
101
|
+
|
102
|
+
* all the basics (classes, methods, ...)
|
103
|
+
* blocks, closures
|
104
|
+
* @instance_eval@, @define_method@, ... (only when the block is given directly)
|
105
|
+
* correct constant and class variable lookup
|
106
|
+
* @raise@, @rescue@, @retry@, @ensure@
|
107
|
+
* ...
|
108
|
+
|
109
|
+
Things that (currently) don't work:
|
110
|
+
|
111
|
+
* @break@ with a value from inside a block
|
112
|
+
* @return@ from inside a block
|
113
|
+
* @return@, @break@, @next@, @redo@ inside @ensure@
|
114
|
+
* @defined?@ is not implemented for all cases
|
115
|
+
* block pass (passing a proc as block to a method) works, but only through a
|
116
|
+
hack and it doesn't work (correctly) for things like @instance_eval@
|
117
|
+
|
118
|
+
Some of the above things might be fixed in future versions.
|
119
|
+
|
120
|
+
Things that don't work as expected and probably never will:
|
121
|
+
|
122
|
+
* methods like @local_variables@, that depend on a Ruby SCOPE
|
123
|
+
* interoperability with @eval(str)@ and similar methods that parse a string and
|
124
|
+
eval it; these methods work, but they might not behave as expected (i.e.
|
125
|
+
access to local variables and similar things won't work, see above)
|
126
|
+
* @callcc@ works but might behave strangely (in particular local variables
|
127
|
+
might behave wrong)
|
128
|
+
* some more things, please see "limitations":limitations.html
|
129
|
+
|
130
|
+
Ruby2CExtension will translate and compile Ruby files using one or more of the
|
131
|
+
above functionalities without a warning (for some cases warnings can be
|
132
|
+
enabled, see "rb2cx":rb2cx.html), so if your Ruby code uses such
|
133
|
+
functionality, please verify that the compiled C extension works as expected.
|
134
|
+
|
135
|
+
For more details please see "limitations":limitations.html.
|
136
|
+
|
137
|
+
|
138
|
+
h2. Usage
|
139
|
+
|
140
|
+
There are two "interfaces" to use Ruby2CExtension:
|
141
|
+
|
142
|
+
* "rb2cx":rb2cx.html: the command line compiler.
|
143
|
+
* "Eval2C":eval2c.html: a class that allows dynamic compilation of Ruby code
|
144
|
+
at runtime.
|
145
|
+
|
146
|
+
Please see their respective documentations.
|
147
|
+
|
148
|
+
|
149
|
+
h2. Feedback
|
150
|
+
|
151
|
+
If you find a bug, think that something doesn't work as it should or have
|
152
|
+
other suggestions, then please don't hesitate to "contact
|
153
|
+
me":mailto:dbatml@remove_nospam.gmx.de and tell me about it.
|
154
|
+
|
155
|
+
I am also interested to know if Ruby2CExtension works under Windows (or other
|
156
|
+
non Linux platforms).
|
157
|
+
|
158
|
+
|
159
|
+
h2. Thanks
|
160
|
+
|
161
|
+
I would like to thank Eric Mahurin for various good ideas for
|
162
|
+
"optimizations":optimizations.html and for inspiring "Eval2C":eval2c.html.
|
163
|
+
|
164
|
+
|
165
|
+
h2. License
|
166
|
+
|
167
|
+
Copyright 2006-2007 "Dominik Bathon":mailto:dbatml@remove_nospam.gmx.de.
|
168
|
+
|
169
|
+
Ruby2CExtension is licensed under the same terms as Ruby.
|