RubyInline 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +120 -0
- data/Makefile +37 -0
- data/Manifest.txt +12 -0
- data/README.txt +118 -0
- data/example.rb +75 -0
- data/example2.rb +29 -0
- data/inline-compat.rb +44 -0
- data/inline.gemspec +33 -0
- data/inline.rb +427 -0
- data/test_inline.rb +481 -0
- data/tutorial/example1.rb +63 -0
- data/tutorial/example2.rb +96 -0
- metadata +52 -0
data/History.txt
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
*** 3.1.0 / 2004-09-24
|
2
|
+
|
3
|
+
+ 2 minor enhancement
|
4
|
+
Extended API of Inline::C with prefix(code).
|
5
|
+
+ Documented all public API.
|
6
|
+
+ 2 bug fixes
|
7
|
+
+ Cleaned a lot of code and tests.
|
8
|
+
+ Removed nearly all tags.
|
9
|
+
|
10
|
+
*** 3.0.1 / 2004-02-24
|
11
|
+
|
12
|
+
+ 2 bug fixes
|
13
|
+
+ I let references to ZenTestUnit slip through the release. Removed.
|
14
|
+
+ Converted History.txt to ZenWeb format.
|
15
|
+
|
16
|
+
*** 3.0.0 / 2003-12-23
|
17
|
+
|
18
|
+
+ 3 major enhancements
|
19
|
+
+ Complete rewrite with new design.
|
20
|
+
+ Multiple language support, works with C/C++ out of the box.
|
21
|
+
+ Multiple functions per compilation unit, now allowing entire classes to be defined and linked in one unit.
|
22
|
+
+ Notes:
|
23
|
+
+ I still need to write much better/complete documentation.
|
24
|
+
|
25
|
+
*** 2.2.0 / 2003-01-25
|
26
|
+
|
27
|
+
+ 1 minor enhancements
|
28
|
+
+ Touch all generated files to avoid unnecessary diffs.
|
29
|
+
+ 1 bug fixes
|
30
|
+
+ Added good profiling example in tutorial/*.
|
31
|
+
+ Added profiling strategy in README.txt.
|
32
|
+
+ Notes:
|
33
|
+
+ Paired with Doug Beaver <snarly@beaver.net>
|
34
|
+
|
35
|
+
*** 2.1.1 / 2002-12-27
|
36
|
+
|
37
|
+
+ 2 bug fixes
|
38
|
+
+ Fixed a bug in inline.rb where it was comparing against inline.rb, not the caller.
|
39
|
+
+ Tweaked example.rb to take the number of iterations as an option.
|
40
|
+
|
41
|
+
*** 2.1.0 / 2002-12-17
|
42
|
+
|
43
|
+
+ 2 minor enhancements
|
44
|
+
+ Added inline_c_raw to replace Inline.inline.
|
45
|
+
+ Removed module Inline as a whole. This gets rid of some
|
46
|
+
+ major version incompatibilities, tons of duplicate code, and
|
47
|
+
+ just seems to make things happier.
|
48
|
+
+ 4 bug fixes
|
49
|
+
+ Added a fix from Michael Scholz to fix the use of $0 for file test.
|
50
|
+
+ Added private and public declarations since we are invading
|
51
|
+
+ class Module.
|
52
|
+
+ Fixed tests... oops!
|
53
|
+
+ Lots of clean up...
|
54
|
+
+ Notes:
|
55
|
+
+ Reviewed by Doug Beaver <snarly@beaver.net>
|
56
|
+
|
57
|
+
*** 2.0.0 / 2002-12-12
|
58
|
+
|
59
|
+
+ 2 bug fixes
|
60
|
+
+ Minor fix to get working on MacOS X (.so vs .bundle).
|
61
|
+
+ Downgraded typemap to be compatible with 1.6.x.
|
62
|
+
+ Notes:
|
63
|
+
+ Paired w/ Doug Beaver <snarly@beaver.net>
|
64
|
+
|
65
|
+
*** 2.0.0 beta / 2002-11-22
|
66
|
+
|
67
|
+
+ 1 major enhancements
|
68
|
+
+ Added inline_c, a "compile-time" version of inline. Massively enhanced, this version has a limited form of C function parsing.
|
69
|
+
+ 2 minor enhancements
|
70
|
+
+ Deprecated Inline#inline for Module#inline_c. To be removed by 2.1.0.
|
71
|
+
+ Extended example.rb to include a fully written inlined C function.
|
72
|
+
+ 3 bug fixes
|
73
|
+
+ Updated README.txt and improved some of the documentation.
|
74
|
+
+ Added test and clean rules to Makefile.
|
75
|
+
+ Removed the copious warnings if running ruby < 1.7.2.
|
76
|
+
+ Notes:
|
77
|
+
+ Paired w/ Doug Beaver <snarly@beaver.net>
|
78
|
+
|
79
|
+
*** 1.1.0 / 2002-11-01
|
80
|
+
|
81
|
+
+ 2 minor enhancements
|
82
|
+
+ Aliased methods are now inlined as well. 250x faster.
|
83
|
+
+ ONLY on ruby 1.7+. Warns on ruby < 1.7.
|
84
|
+
+ Added a makefile to automate running of all different benchmarks.
|
85
|
+
+ 1 bug fixes
|
86
|
+
+ Improved example to include an aliased method testcase.
|
87
|
+
|
88
|
+
*** 1.0.7 / 2002-09-22
|
89
|
+
|
90
|
+
+ 1 minor enhancements
|
91
|
+
+ Only compiles the generated code if it was different from the previous version.
|
92
|
+
+ 1 bug fixes
|
93
|
+
+ Improved security: Checks group and global write on home directory.
|
94
|
+
|
95
|
+
*** 1.0.6 / 2002-09-18
|
96
|
+
|
97
|
+
+ 1 minor enhancements
|
98
|
+
+ Added a prelude argument for header and datatype declarations.
|
99
|
+
+ 3 bug fixes
|
100
|
+
+ Only output stuff if invoked verbose (ie 'ruby -v ./example.rb').
|
101
|
+
+ Added some compatibility code for windows.
|
102
|
+
+ Declared requirement on POSIX system.
|
103
|
+
|
104
|
+
*** 1.0.5 / 2002-09-11
|
105
|
+
|
106
|
+
+ 2 bug fixes
|
107
|
+
+ Improved security model for UNIX. Still not sure about windoze.
|
108
|
+
+ Fixed History.txt to be accurate, gave example in README.
|
109
|
+
|
110
|
+
*** 1.0.4 / 2002-09-10
|
111
|
+
|
112
|
+
+ 1 major enhancements
|
113
|
+
+ Released to sourceforge!
|
114
|
+
+ 1 bug fixes
|
115
|
+
+ A number of very minor bug fixes from IRC sessions w/ others.
|
116
|
+
|
117
|
+
*** 1.0.0 / 2002-09-05
|
118
|
+
|
119
|
+
+ 1 major enhancements
|
120
|
+
+ Birthday!
|
data/Makefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
RUBY?=/usr/local/bin/ruby
|
2
|
+
RDOC?=rdoc18
|
3
|
+
|
4
|
+
test:
|
5
|
+
$(RUBY) -I. -w ./test_inline.rb
|
6
|
+
|
7
|
+
examples:
|
8
|
+
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./example.rb
|
9
|
+
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./example2.rb
|
10
|
+
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./tutorial/example1.rb
|
11
|
+
rm -rf ~/.ruby_inline; $(RUBY) -I. -w ./tutorial/example2.rb
|
12
|
+
|
13
|
+
docs:
|
14
|
+
$(RDOC) --main inline.rb
|
15
|
+
|
16
|
+
bench:
|
17
|
+
@echo "Running native"
|
18
|
+
@$(RUBY) -I. ./example.rb 3 2> /dev/null
|
19
|
+
@echo "Running primer - preloads the compiler and stuff"
|
20
|
+
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 0 2>&1 > /dev/null
|
21
|
+
@echo "With full builds"
|
22
|
+
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 0 2> /dev/null
|
23
|
+
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 1 2> /dev/null
|
24
|
+
@rm -rf ~/.ruby_inline; $(RUBY) -I. ./example.rb 2 2> /dev/null
|
25
|
+
@echo "Without builds"
|
26
|
+
@$(RUBY) -I. ./example.rb 0 2> /dev/null
|
27
|
+
@$(RUBY) -I. ./example.rb 1 2> /dev/null
|
28
|
+
@$(RUBY) -I. ./example.rb 2 2> /dev/null
|
29
|
+
|
30
|
+
install:
|
31
|
+
@where=`$(RUBY) -rrbconfig -e 'include Config; print CONFIG["sitelibdir"]'`; \
|
32
|
+
echo "installing inline.rb in $$where"; \
|
33
|
+
cp -f inline.rb $$where; \
|
34
|
+
echo Installed
|
35
|
+
|
36
|
+
clean:
|
37
|
+
rm -rf *~ doc ~/.ruby_inline
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
** Ruby Inline
|
2
|
+
|
3
|
+
http://www.zenspider.com/ZSS/Products/RubyInline/
|
4
|
+
support@zenspider.com
|
5
|
+
|
6
|
+
** DESCRIPTION:
|
7
|
+
|
8
|
+
Ruby Inline is my quick attempt to create an analog to Perl's
|
9
|
+
Inline::C. It allows you to embed C or C++ external module code in
|
10
|
+
your ruby script directly. The code is compiled and run on the fly
|
11
|
+
when needed. The ruby version isn't near as feature-full as the perl
|
12
|
+
version, but it is neat!
|
13
|
+
|
14
|
+
** FEATURES/PROBLEMS:
|
15
|
+
|
16
|
+
+ Quick and easy inlining of your C or C++ code embedded in your ruby script.
|
17
|
+
+ Rudimentary automatic conversion between ruby and C basic types
|
18
|
+
(char, unsigned, unsigned int, char *, int, long, unsigned long).
|
19
|
+
+ inline_c_raw exists for when the automatic conversion isn't sufficient.
|
20
|
+
+ Only recompiles if the inlined code has changed.
|
21
|
+
+ Pretends to be secure.
|
22
|
+
+ Only uses standard ruby libraries, nothing extra to download.
|
23
|
+
+ Simple as it can be. Less than 230 lines long... um... sorta simple.
|
24
|
+
|
25
|
+
** SYNOPSYS:
|
26
|
+
|
27
|
+
require "inline"
|
28
|
+
class MyTest
|
29
|
+
inline_c "
|
30
|
+
long factorial(int max) {
|
31
|
+
int i=max, result=1;
|
32
|
+
while (i >= 2) { result *= i--; }
|
33
|
+
return result;
|
34
|
+
}"
|
35
|
+
end
|
36
|
+
t = MyTest.new()
|
37
|
+
factorial_5 = t.factorial(5)
|
38
|
+
|
39
|
+
** SYNOPSYS (C++):
|
40
|
+
|
41
|
+
$INLINE_FLAGS = " -x c++ "
|
42
|
+
$INLINE_LIBS = " -lstdc++ "
|
43
|
+
require "inline"
|
44
|
+
class MyTest
|
45
|
+
inline_c "
|
46
|
+
#include <iostream>
|
47
|
+
static
|
48
|
+
VALUE
|
49
|
+
hello(int i) {
|
50
|
+
while (i-- > 0) {
|
51
|
+
std::cout << \"hello\" << std::endl;
|
52
|
+
}
|
53
|
+
}"
|
54
|
+
end
|
55
|
+
t = MyTest.new()
|
56
|
+
t.hello(3)
|
57
|
+
|
58
|
+
** (PSEUDO)BENCHMARKS:
|
59
|
+
|
60
|
+
> make bench
|
61
|
+
|
62
|
+
Running native
|
63
|
+
Type = Native , Iter = 1000000, T = 28.70058100 sec, 0.00002870 sec / iter
|
64
|
+
Running primer - preloads the compiler and stuff
|
65
|
+
With full builds
|
66
|
+
Type = Inline C , Iter = 1000000, T = 7.55118600 sec, 0.00000755 sec / iter
|
67
|
+
Type = InlineRaw, Iter = 1000000, T = 7.54488300 sec, 0.00000754 sec / iter
|
68
|
+
Type = Alias , Iter = 1000000, T = 7.53243100 sec, 0.00000753 sec / iter
|
69
|
+
Without builds
|
70
|
+
Type = Inline C , Iter = 1000000, T = 7.59543300 sec, 0.00000760 sec / iter
|
71
|
+
Type = InlineRaw, Iter = 1000000, T = 7.54097200 sec, 0.00000754 sec / iter
|
72
|
+
Type = Alias , Iter = 1000000, T = 7.53654000 sec, 0.00000754 sec / iter
|
73
|
+
|
74
|
+
** PROFILING STRATEGY:
|
75
|
+
|
76
|
+
0) Always keep a log of your progress and changes.
|
77
|
+
1) Run code with 'time' and large dataset.
|
78
|
+
2) Run code with '-rprofile' and smaller dataset, large enough to get good #s.
|
79
|
+
3) Examine profile output and translate 1 bottleneck to C.
|
80
|
+
4) Run new code with 'time' and large dataset. Repeat 2-3 if unsatisfied.
|
81
|
+
5) Run final code with 'time' and compare to the first run.
|
82
|
+
|
83
|
+
** REQUIREMENTS:
|
84
|
+
|
85
|
+
+ Ruby - 1.6.7 & 1.7.2 has been used on FreeBSD 4.6 and MacOSX.
|
86
|
+
+ POSIX compliant system (ie pretty much any UNIX, or Cygwin on MS platforms).
|
87
|
+
+ A C/C++ compiler (the same one that compiled your ruby interpreter).
|
88
|
+
+ test::unit for running tests ( http://testunit.talbott.ws/ ).
|
89
|
+
|
90
|
+
** INSTALL:
|
91
|
+
|
92
|
+
+ make test (optional)
|
93
|
+
+ make install
|
94
|
+
|
95
|
+
** LICENSE:
|
96
|
+
|
97
|
+
(The MIT License)
|
98
|
+
|
99
|
+
Copyright (c) 2001-2002 Ryan Davis, Zen Spider Software
|
100
|
+
|
101
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
102
|
+
a copy of this software and associated documentation files (the
|
103
|
+
"Software"), to deal in the Software without restriction, including
|
104
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
105
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
106
|
+
permit persons to whom the Software is furnished to do so, subject to
|
107
|
+
the following conditions:
|
108
|
+
|
109
|
+
The above copyright notice and this permission notice shall be
|
110
|
+
included in all copies or substantial portions of the Software.
|
111
|
+
|
112
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
113
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
114
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
115
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
116
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
117
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
118
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/example.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require "inline"
|
4
|
+
|
5
|
+
class MyTest
|
6
|
+
|
7
|
+
def factorial(n)
|
8
|
+
f = 1
|
9
|
+
n.downto(2) { |x| f *= x }
|
10
|
+
f
|
11
|
+
end
|
12
|
+
|
13
|
+
inline do |builder|
|
14
|
+
builder.include "<math.h>"
|
15
|
+
|
16
|
+
builder.c "
|
17
|
+
long factorial_c(int max) {
|
18
|
+
int i=max, result=1;
|
19
|
+
while (i >= 2) { result *= i--; }
|
20
|
+
return result;
|
21
|
+
}"
|
22
|
+
|
23
|
+
builder.c_raw "
|
24
|
+
static
|
25
|
+
VALUE
|
26
|
+
factorial_c_raw(int argc, VALUE *argv, VALUE self) {
|
27
|
+
int i=FIX2INT(argv[0]), result=1;
|
28
|
+
while (i >= 2) { result *= i--; }
|
29
|
+
return INT2NUM(result);
|
30
|
+
}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
t = MyTest.new()
|
35
|
+
|
36
|
+
arg = ARGV.shift || 0
|
37
|
+
arg = arg.to_i
|
38
|
+
|
39
|
+
# breakeven for build run vs native doing 5 factorial:
|
40
|
+
# on a PIII/750 running FreeBSD: about 5000
|
41
|
+
# on a PPC/G4/800 running Mac OSX 10.2: always faster
|
42
|
+
max = ARGV.shift || 1000000
|
43
|
+
max = max.to_i
|
44
|
+
|
45
|
+
puts "RubyInline #{Inline::VERSION}" if $DEBUG
|
46
|
+
|
47
|
+
MyTest.send(:alias_method, :factorial_alias, :factorial_c_raw)
|
48
|
+
|
49
|
+
def validate(n)
|
50
|
+
if n != 120 then puts "ACK! - #{n}"; end
|
51
|
+
end
|
52
|
+
|
53
|
+
tstart = Time.now
|
54
|
+
case arg
|
55
|
+
when 0 then
|
56
|
+
type = "Inline C "
|
57
|
+
(1..max).each { |m| n = t.factorial_c(5); validate(n); }
|
58
|
+
when 1 then
|
59
|
+
type = "InlineRaw"
|
60
|
+
(1..max).each { |m| n = t.factorial_c_raw(5); validate(n); }
|
61
|
+
when 2 then
|
62
|
+
type = "Alias "
|
63
|
+
(1..max).each { |m| n = t.factorial_alias(5); validate(n); }
|
64
|
+
when 3 then
|
65
|
+
type = "Native "
|
66
|
+
(1..max).each { |m| n = t.factorial(5); validate(n); }
|
67
|
+
else
|
68
|
+
$stderr.puts "ERROR: argument #{arg} not recognized"
|
69
|
+
exit(1)
|
70
|
+
end
|
71
|
+
tend = Time.now
|
72
|
+
|
73
|
+
total = tend - tstart
|
74
|
+
avg = total / max
|
75
|
+
printf "Type = #{type}, Iter = #{max}, T = %.8f sec, %.8f sec / iter\n", total, avg
|
data/example2.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/local/bin/ruby17 -w
|
2
|
+
|
3
|
+
require "inline"
|
4
|
+
|
5
|
+
class MyTest
|
6
|
+
|
7
|
+
inline do |builder|
|
8
|
+
|
9
|
+
builder.add_compile_flags %q(-x c++)
|
10
|
+
builder.add_link_flags %q(-lstdc++)
|
11
|
+
|
12
|
+
builder.c "
|
13
|
+
// stupid c++ comment
|
14
|
+
#include <iostream>
|
15
|
+
/* stupid c comment */
|
16
|
+
static
|
17
|
+
void
|
18
|
+
hello(int i) {
|
19
|
+
while (i-- > 0) {
|
20
|
+
std::cout << \"hello\" << std::endl;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
t = MyTest.new()
|
28
|
+
|
29
|
+
t.hello(3)
|
data/inline-compat.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
require "inline"
|
4
|
+
|
5
|
+
############################################################
|
6
|
+
# DEPRECATED: Remove by version 3.1 or 2003-03-01
|
7
|
+
#
|
8
|
+
# This file is only provided for those who require backwards compatibility with version 2.x.
|
9
|
+
# If you don't need it, don't use it. If you do, please heed the deprecation warnings and
|
10
|
+
# migrate to the new system as fast as you can. Thanks...
|
11
|
+
|
12
|
+
module Inline
|
13
|
+
class C
|
14
|
+
|
15
|
+
$INLINE_FLAGS = nil
|
16
|
+
$INLINE_LIBS = nil
|
17
|
+
|
18
|
+
trace_var(:$INLINE_FLAGS) do |val|
|
19
|
+
$stderr.puts "WARNING: $INLINE_FLAGS is deprecated. Use #add_link_flags. Called from #{caller[1]}."
|
20
|
+
end
|
21
|
+
|
22
|
+
trace_var(:$INLINE_LIBS) do |val|
|
23
|
+
$stderr.puts "WARNING: $INLINE_LIBS is deprecated. Use #add_compile_flags. Called from #{caller[1]}."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Module
|
29
|
+
public
|
30
|
+
|
31
|
+
def inline_c(src)
|
32
|
+
$stderr.puts "WARNING: inline_c is deprecated. Switch to Inline module"
|
33
|
+
inline(:C) do | builder |
|
34
|
+
builder.c src
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def inline_c_raw(src)
|
39
|
+
$stderr.puts "WARNING: inline_c_raw is deprecated. Switch to Inline module"
|
40
|
+
inline(:C) do | builder |
|
41
|
+
builder.c_raw src
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/inline.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'inline'
|
5
|
+
|
6
|
+
spec = Gem::Specification.new do |s|
|
7
|
+
|
8
|
+
s.name = 'RubyInline'
|
9
|
+
s.version = Inline::VERSION
|
10
|
+
s.summary = "Multi-language extension coding within ruby."
|
11
|
+
|
12
|
+
paragraphs = File.read("README.txt").split(/\n\n+/)
|
13
|
+
s.description = paragraphs[3]
|
14
|
+
|
15
|
+
s.requirements << "A POSIX environment and a compiler for your language."
|
16
|
+
s.files = IO.readlines("Manifest.txt").map {|f| f.chomp }
|
17
|
+
|
18
|
+
s.require_path = '.'
|
19
|
+
s.autorequire = 'inline'
|
20
|
+
|
21
|
+
s.has_rdoc = false # I SUCK - TODO
|
22
|
+
s.test_suite_file = "test_inline.rb"
|
23
|
+
|
24
|
+
s.author = "Ryan Davis"
|
25
|
+
s.email = "ryand-ruby@zenspider.com"
|
26
|
+
s.homepage = "http://www.zenspider.com/ZSS/Products/RubyInline/"
|
27
|
+
s.rubyforge_project = "rubyinline"
|
28
|
+
end
|
29
|
+
|
30
|
+
if $0 == __FILE__
|
31
|
+
Gem.manage_gems
|
32
|
+
Gem::Builder.new(spec).build
|
33
|
+
end
|