RubyInline 3.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/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
|