Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial version of rubinius-core-api JRuby support.
- Loading branch information
0 parents
commit 93d98fc
Showing
19 changed files
with
1,835 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
lib/rubinius-core-api.jar | ||
pkg | ||
*.gem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
This is an attempt to provide some of Rubinius's additional core classes on | ||
other implementations. | ||
|
||
Rubinius has all the normal Ruby classes, but to support implementing them | ||
mostly in Ruby, they have added a number of other support classes. This | ||
library hopes to implement those additional support classes for other Ruby | ||
implementations, so they their utility can be shared across implementations. | ||
|
||
Currently, only the following classes are implemented, and only on JRuby: | ||
|
||
Rubinius::ByteArray - a fixed-size array of bytes | ||
Rubinius::Channel - a low-level synchronization mechanism | ||
Rubinius::EnvironmentAccess - env variable support | ||
Rubinius::Tuple - a fixed-size array of object references | ||
Rubinius::Type - utilities for type conversions | ||
|
||
In addition, some utility methods added to Thread for recursive guards and | ||
Kernel::StringValue are also implemented. | ||
|
||
More APIs will be added over time. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
task :default => :spec | ||
|
||
if defined?(JRUBY_VERSION) | ||
require 'ant' | ||
|
||
directory "pkg/classes" | ||
|
||
desc "Clean up build artifacts" | ||
task :clean do | ||
rm_rf "pkg/classes" | ||
rm_rf "lib/rubinius-core-api.jar" | ||
end | ||
|
||
desc "Compile the extension" | ||
task :compile => "pkg/classes" do |t| | ||
ant.javac :srcdir => "src", :destdir => t.prerequisites.first, | ||
:source => "1.5", :target => "1.5", :debug => true, | ||
:classpath => "${java.class.path}:${sun.boot.class.path}" | ||
end | ||
|
||
desc "Build the jar" | ||
task :jar => :compile do | ||
ant.jar :basedir => "pkg/classes", :destfile => "lib/rubinius-core-api.jar", :includes => "**/*.class" | ||
end | ||
|
||
task :package => :jar | ||
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' | ||
task :package do | ||
# nop | ||
end | ||
end | ||
|
||
desc "Run the specs" | ||
task :spec => :package do | ||
ruby "-S", "rspec", "spec" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
if defined?(JRUBY_VERSION) | ||
begin | ||
require 'rubinius-core-api.jar' | ||
rescue LoadError | ||
# keep going; might be bundled into classpath already | ||
end | ||
|
||
# for access to JRuby runtime | ||
require 'jruby' | ||
|
||
org.jruby.ext.rubinius.RubiniusLibrary.new.load(JRuby.runtime, false) | ||
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' | ||
# do nothing for Rubinius | ||
else | ||
raise "Only supported on JRuby and Rubinius" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
## | ||
# Channel is a FIFO, thread-aware value passing class that can hold any number | ||
# of objects similar to Queue. Use #send to add objects to the channel and | ||
# #receive to remove objects from the channel. | ||
# | ||
# If Channel#receive is called on an empty channel, the VM puts the current | ||
# Thread (t1) to sleep. At some future time, when Channel#send is called on | ||
# that same thread, the VM wakes up t1 and the value passed to #send is | ||
# returned. This allows us to implement all manner of Thread semantics, such | ||
# as Mutex. | ||
# | ||
# Channel is used heavily by Scheduler, to allow ruby code to interact with | ||
# the outside world in a thread aware manner. | ||
|
||
module Rubinius | ||
class Channel | ||
|
||
## | ||
# Returns nil if nothing is waiting, or a List object which contains all | ||
# Thread objects waiting on this Channel. | ||
|
||
attr_reader :waiting | ||
|
||
## | ||
# Returns nil if there are no values, otherwise a List object containing all | ||
# values the Channel contains. | ||
|
||
attr_reader :value | ||
|
||
## | ||
# Creates a new Channel and registers it with the VM. | ||
|
||
def self.new | ||
Ruby.primitive :channel_new | ||
raise PrimitiveFailure, "Channel.new primitive failed" | ||
end | ||
|
||
# We must be sure a Channel is always created properly, so handle | ||
# this the same as new. | ||
def self.allocate | ||
Ruby.primitive :channel_new | ||
raise PrimitiveFailure, "Channel.new primitive failed" | ||
end | ||
|
||
## | ||
# Puts +obj+ in the Channel. If there are waiting threads the first thread | ||
# will be woken up and handed +obj+. | ||
|
||
def send(obj) | ||
Ruby.primitive :channel_send | ||
raise PrimitiveFailure, "Channel#send primitive failed" | ||
end | ||
|
||
alias_method :<<, :send | ||
|
||
## | ||
# Removes and returns the first value from the Channel. If the channel | ||
# is empty, Thread.current is put to sleep until #send is called. | ||
|
||
def receive | ||
Ruby.primitive :channel_receive | ||
raise PrimitiveFailure, "Channel#receive primitive failed" | ||
end | ||
|
||
def receive_timeout(duration) | ||
Ruby.primitive :channel_receive_timeout | ||
raise PrimitiveFailure, "Channel#receive_timeout primitive failed" | ||
end | ||
|
||
def try_receive | ||
Ruby.primitive :channel_try_receive | ||
raise PrimitiveFailure, "Channel#try_receive primitive failed" | ||
end | ||
|
||
## | ||
# Converts +obj+ into a Channel using #to_channel. | ||
|
||
def self.convert_to_channel(obj) | ||
return obj if Channel === obj | ||
begin | ||
o2 = obj.to_channel | ||
unless Channel === o2 | ||
raise ArgumentError, "to_channel on #{obj.inspect} did not return a Channel" | ||
end | ||
return o2 | ||
rescue NoMethodError | ||
raise ArgumentError, "Unable to convert #{obj.inspect} into a channel" | ||
end | ||
end | ||
|
||
## | ||
# Legacy API. To be removed. | ||
|
||
def self.receive(obj) # :nodoc: | ||
return convert_to_channel(obj).receive | ||
end | ||
|
||
## | ||
# API compliance, returns self. | ||
|
||
def to_channel | ||
self | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
## | ||
# An array of bytes, used as a low-level data store for implementing various | ||
# other classes. | ||
|
||
class Rubinius::ByteArray | ||
alias_method :[], :get_byte | ||
alias_method :[]=, :set_byte | ||
|
||
def each | ||
i = 0 | ||
max = size() | ||
|
||
while i < max | ||
yield get_byte(i) | ||
i += 1 | ||
end | ||
end | ||
|
||
def inspect | ||
"#<#{self.class}:0x#{object_id.to_s(16)} #{size} bytes>" | ||
end | ||
|
||
def <=>(other) | ||
compare_bytes other, size, other.size | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
## | ||
# A communication mechanism based on pi-calculus channels used primarily to | ||
# communicate between ruby and the VM about events. | ||
|
||
module Rubinius | ||
class Channel | ||
def inspect | ||
"#<Rubinius::Channel>" | ||
end | ||
|
||
def as_lock(val=nil) | ||
receive | ||
|
||
begin | ||
yield | ||
ensure | ||
self << val | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.