Skip to content

Commit

Permalink
Showing 206 changed files with 2,178 additions and 1,676 deletions.
10 changes: 5 additions & 5 deletions antlib/extra.xml
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ build jruby-complete.jar
<env key='GEM_PATH' value='lib/ruby/gems/shared'/>
<arg value='-Djruby.home=uri:classloader://META-INF/jruby.home'/>
<arg value='-cp'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-1.7.21-SNAPSHOT.jar'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-9.0.0.0.rc1.jar'/>
<arg value='org.jruby.Main'/>
<arg value='-I.:test/externals/ruby1.9:test/externals/ruby1.9/ruby'/>
<arg value='-r./test/ruby19_env.rb'/>
@@ -136,7 +136,7 @@ build jruby-complete.jar
<env key='GEM_PATH' value='lib/ruby/gems/shared'/>
<arg value='-Djruby.home=uri:classloader://META-INF/jruby.home'/>
<arg value='-cp'/>
<arg value='core/target/test-classes:test/target/test-classes:maven/jruby-complete/target/jruby-complete-1.7.21-SNAPSHOT.jar'/>
<arg value='core/target/test-classes:test/target/test-classes:maven/jruby-complete/target/jruby-complete-9.0.0.0.rc1.jar'/>
<arg value='org.jruby.Main'/>
<arg value='-I.:test/externals/ruby1.9:test/externals/ruby1.9/ruby'/>
<arg value='-r./test/ruby19_env.rb'/>
@@ -152,7 +152,7 @@ build jruby-complete.jar
<env key='GEM_PATH' value='lib/ruby/gems/shared'/>
<arg value='-Djruby.home=uri:classloader://META-INF/jruby.home'/>
<arg value='-cp'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-1.7.21-SNAPSHOT.jar'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-9.0.0.0.rc1.jar'/>
<arg value='org.jruby.Main'/>
<arg value='-I.:test/externals/ruby1.9:test/externals/ruby1.9/ruby'/>
<arg value='-r./test/ruby19_env.rb'/>
@@ -168,7 +168,7 @@ build jruby-complete.jar
<env key='GEM_PATH' value='lib/ruby/gems/shared'/>
<arg value='-Djruby.home=uri:classloader://META-INF/jruby.home'/>
<arg value='-cp'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-1.7.21-SNAPSHOT.jar'/>
<arg value='core/target/test-classes:test/target/test-classes:lib/jruby.jar:maven/jruby-stdlib/target/jruby-stdlib-9.0.0.0.rc1.jar'/>
<arg value='org.jruby.Main'/>
<arg value='-I.:test/externals/ruby1.9:test/externals/ruby1.9/ruby'/>
<arg value='-r./test/ruby19_env.rb'/>
@@ -460,7 +460,7 @@ build jruby-complete.jar
<env key='GEM_PATH' value='lib/ruby/gems/shared'/>
<arg value='-Djruby.home=uri:classloader://META-INF/jruby.home'/>
<arg value='-cp'/>
<arg value='core/target/test-classes:test/target/test-classes:maven/jruby-complete/target/jruby-complete-1.7.21-SNAPSHOT.jar'/>
<arg value='core/target/test-classes:test/target/test-classes:maven/jruby-complete/target/jruby-complete-9.0.0.0.rc1.jar'/>
<arg value='org.jruby.Main'/>
<arg value='-I.:test/externals/ruby1.9:test/externals/ruby1.9/ruby'/>
<arg value='-r./test/ruby19_env.rb'/>
2 changes: 1 addition & 1 deletion core/pom.rb
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@
jar 'org.jruby.joni:joni:2.1.6'
jar 'org.jruby.extras:bytelist:1.0.13'
jar 'org.jruby.jcodings:jcodings:1.0.13'
jar 'org.jruby:dirgra:0.2'
jar 'org.jruby:dirgra:0.3'

jar 'com.headius:invokebinder:1.5'
jar 'com.headius:options:1.1'
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@
<dependency>
<groupId>org.jruby</groupId>
<artifactId>dirgra</artifactId>
<version>0.2</version>
<version>0.3</version>
</dependency>
<dependency>
<groupId>com.headius</groupId>
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyMatchData.java
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.ByteListHolder;
import org.jruby.util.StringSupport;

/**
@@ -398,7 +399,7 @@ private int nameToBackrefNumber(RubyString str) {
return nameToBackrefNumber(getRuntime(), pattern, regs, str);
}

private static int nameToBackrefNumber(Ruby runtime, Regex pattern, Region regs, RubyString str) {
private static int nameToBackrefNumber(Ruby runtime, Regex pattern, Region regs, ByteListHolder str) {
if (pattern == null) {
throw runtime.newIndexError("undefined group name reference: " + str);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jruby.ir.representations;

import org.jruby.RubyInstanceConfig;
import org.jruby.dirgra.ExplicitVertexID;
import org.jruby.ir.IRManager;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.instructions.YieldInstr;
@@ -10,7 +11,6 @@
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.InlineCloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.ir.util.ExplicitVertexID;

import java.util.ArrayList;
import java.util.List;
9 changes: 0 additions & 9 deletions core/src/main/java/org/jruby/ir/util/ExplicitVertexID.java

This file was deleted.

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
require 'thread'

module Gem
VERSION = '2.4.6'
VERSION = '2.4.8'
end

# Must be first since it unloads the prelude from 1.9.2
8 changes: 7 additions & 1 deletion lib/ruby/stdlib/rubygems/remote_fetcher.rb
Original file line number Diff line number Diff line change
@@ -94,7 +94,13 @@ def api_endpoint(uri)
rescue Resolv::ResolvError
uri
else
URI.parse "#{uri.scheme}://#{res.target}#{uri.path}"
target = res.target.to_s.strip

if /\.#{Regexp.quote(host)}\z/ =~ target
return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
end

uri
end
end

1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/attlistdecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/attribute.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/cdata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/child.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/doctype.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/document.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/dtd/attlistdecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/dtd/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/dtd/dtd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/dtd/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/dtd/elementdecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/dtd/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/dtd/entitydecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/dtd/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/dtd/notationdecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/dtd/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/element.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/encoding.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/entity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/formatters/default.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/formatters/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/formatters/pretty.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/formatters/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/formatters/transitive.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/formatters/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/functions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/instruction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/light/node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/light/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/namespace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/node.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/output.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parseexception.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/baseparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/lightparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/pullparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/sax2parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/streamparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/treeparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/ultralightparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/parsers/xpathparser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/parsers/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/quickpath.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/rexml.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/sax2listener.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/security.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/streamlistener.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/syncenumerator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/text.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/undefinednamespaceexception.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/validation/relaxng.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/validation/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/validation/validation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/validation/' + File.basename(__FILE__)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../../stdlib/rexml/validation/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/xmldecl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/xmltokens.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/xpath.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/rexml/xpath_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/rexml/' + File.basename(__FILE__)
96 changes: 1 addition & 95 deletions lib/ruby/truffle/mri/thread.rb
Original file line number Diff line number Diff line change
@@ -26,101 +26,7 @@ class ThreadError < StandardError
Thread.abort_on_exception = true
end

#
# ConditionVariable objects augment class Mutex. Using condition variables,
# it is possible to suspend while in the middle of a critical section until a
# resource becomes available.
#
# Example:
#
# require 'thread'
#
# mutex = Mutex.new
# resource = ConditionVariable.new
#
# a = Thread.new {
# mutex.synchronize {
# # Thread 'a' now needs the resource
# resource.wait(mutex)
# # 'a' can now have the resource
# }
# }
#
# b = Thread.new {
# mutex.synchronize {
# # Thread 'b' has finished using the resource
# resource.signal
# }
# }
#
class ConditionVariable
#
# Creates a new ConditionVariable
#
def initialize
@waiters = {}
@waiters_mutex = Mutex.new
end

#
# Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup.
#
# If +timeout+ is given, this method returns after +timeout+ seconds passed,
# even if no other thread has signaled.
#
def wait(mutex, timeout=nil)
Thread.handle_interrupt(StandardError => :never) do
begin
Thread.handle_interrupt(StandardError => :on_blocking) do
@waiters_mutex.synchronize do
@waiters[Thread.current] = true
end
mutex.sleep timeout
end
ensure
@waiters_mutex.synchronize do
@waiters.delete(Thread.current)
end
end
end
self
end

#
# Wakes up the first thread in line waiting for this lock.
#
def signal
Thread.handle_interrupt(StandardError => :on_blocking) do
begin
t, _ = @waiters_mutex.synchronize { @waiters.shift }
t.run if t
rescue ThreadError
retry # t was already dead?
end
end
self
end

#
# Wakes up all threads waiting for this lock.
#
def broadcast
Thread.handle_interrupt(StandardError => :on_blocking) do
threads = nil
@waiters_mutex.synchronize do
threads = @waiters.keys
@waiters.clear
end
for t in threads
begin
t.run
rescue ThreadError
end
end
end
self
end
end
# Truffle: ConditionVariable is defined in Java.

#
# This class provides a way to synchronize communication between threads.
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../stdlib/xmlrpc'
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/base64.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/create.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/datetime.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/marshal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
1 change: 1 addition & 0 deletions lib/ruby/truffle/mri/xmlrpc/utils.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative '../../../stdlib/xmlrpc/' + File.basename(__FILE__)
2 changes: 1 addition & 1 deletion maven/jruby/pom.xml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
<parent>
<groupId>org.jruby</groupId>
<artifactId>jruby-artifacts</artifactId>
<version>9.0.0.0-SNAPSHOT</version>
<version>9.0.0.0.rc1</version>
</parent>
<artifactId>jruby</artifactId>
<name>JRuby Main Maven Artifact</name>
2 changes: 1 addition & 1 deletion spec/ruby/core/symbol/all_symbols_spec.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
it "increases size of the return array when new symbol comes" do
symbols = Symbol.all_symbols
sym = [eval(":aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
Symbol.all_symbols.size.should == symbols.size + 1
Symbol.all_symbols.size.should > symbols.size
sym.clear
end
end
2 changes: 1 addition & 1 deletion spec/ruby/library/etc/getlogin_spec.rb
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
if Etc.getlogin
# Etc.getlogin returns the same result of logname(2)
# if it returns non NULL
Etc.getlogin.should == `logname`.chomp
Etc.getlogin.should == `id -un`.chomp
else
# Etc.getlogin may return nil if the login name is not set
# because of chroot or sudo or something.
2 changes: 2 additions & 0 deletions spec/tags/ruby/core/kernel/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -51,3 +51,5 @@ fails:Kernel#spawn redirects STDOUT to the given file if :out => String
fails:Kernel#spawn redirects STDERR to the given file if :err => String
fails:Kernel#spawn when passed :close_others => false does not close file descriptors >= 3 in the child process if fds are set close_on_exec=false
fails:Kernel.spawn when passed :close_others => false does not close file descriptors >= 3 in the child process if fds are set close_on_exec=false
fails:Kernel#spawn when passed :close_others => false closes file descriptors >= 3 in the child process because they are set close_on_exec by default
fails:Kernel.spawn when passed :close_others => false closes file descriptors >= 3 in the child process because they are set close_on_exec by default
1 change: 1 addition & 0 deletions spec/tags/ruby/core/process/spawn_tags.txt
Original file line number Diff line number Diff line change
@@ -18,3 +18,4 @@ fails:Process.spawn joins the current process if :pgroup => false
fails:Process.spawn redirects STDOUT to the given file if :out => String
fails:Process.spawn redirects STDERR to the given file if :err => String
fails:Process.spawn when passed :close_others => false does not close file descriptors >= 3 in the child process if fds are set close_on_exec=false
fails:Process.spawn when passed :close_others => false closes file descriptors >= 3 in the child process because they are set close_on_exec by default
9 changes: 0 additions & 9 deletions spec/truffle/tags/core/encoding/compatible_tags.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
fails:Encoding.compatible? String, Regexp returns US-ASCII if both are US-ASCII
fails:Encoding.compatible? String, Regexp returns the String's Encoding if it is not US-ASCII but both are ASCII only
fails:Encoding.compatible? String, Regexp returns the String's Encoding if the String is not ASCII only
fails:Encoding.compatible? Regexp, String returns US-ASCII if both are US-ASCII
fails:Encoding.compatible? Regexp, Regexp returns US-ASCII if both are US-ASCII
fails:Encoding.compatible? Regexp, Regexp returns the first's Encoding if it is not US-ASCII and not ASCII only
fails:Encoding.compatible? Regexp, Symbol returns US-ASCII if both are US-ASCII
fails:Encoding.compatible? Regexp, Symbol returns the first's Encoding if it is not US-ASCII and not ASCII only
fails:Encoding.compatible? Symbol, Regexp returns US-ASCII if both are US-ASCII
fails:Encoding.compatible? Object, Object returns nil for Object, String
fails:Encoding.compatible? Object, Object returns nil for Object, Regexp
fails:Encoding.compatible? Object, Object returns nil for Object, Symbol
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/encoding/default_external_tags.txt
Original file line number Diff line number Diff line change
@@ -4,5 +4,3 @@ slow:Encoding.default_external with command line options is not changed by the -
slow:Encoding.default_external with command line options returns the encoding specified by '-E external'
slow:Encoding.default_external with command line options returns the encoding specified by '-E external:'
fails:Encoding.default_external with command line options is not changed by the -U option
fails:Encoding.default_external with command line options returns the encoding specified by '-E external:'
fails:Encoding.default_external with command line options returns the encoding specified by '-E external'
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/encoding/default_internal_tags.txt
Original file line number Diff line number Diff line change
@@ -4,6 +4,3 @@ windows:Encoding.default_internal with command line options uses the encoding sp
slow:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
fails:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
fails:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
1 change: 0 additions & 1 deletion spec/truffle/tags/core/encoding/locale_charmap_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Encoding.locale_charmap returns a value based on the LC_ALL environment variable
fails:Encoding.locale_charmap is unaffected by assigning to ENV['LC_ALL'] in the same process
8 changes: 0 additions & 8 deletions spec/truffle/tags/core/enumerable/chunk_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/enumerable/cycle_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:Enumerable#cycle passed no argument or nil loops indefinitely
fails:Enumerable#cycle Enumerable with size when no block is given returned Enumerator size should be the result of multiplying the enumerable size by the argument passed
fails:Enumerable#cycle Enumerable with size when no block is given returned Enumerator size should be zero when the argument passed is 0 or less
fails:Enumerable#cycle Enumerable with size when no block is given returned Enumerator size should be Float::INFINITY when no argument is passed
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/enumerable/slice_before_tags.txt

This file was deleted.

10 changes: 0 additions & 10 deletions spec/truffle/tags/core/proc/arity_tags.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
fails:"Proc#arity for instances created with -> () { } returns positive values for definition \n @a = -> (a:) { }\n @b = -> (a:, b:) { }\n @c = -> (a: 1, b:, c:, d: 2) { }"
fails:"Proc#arity for instances created with -> () { } returns positive values for definition \n @a = -> (a, b:) { }\n @b = -> (a, b:, &l) { }"
fails:"Proc#arity for instances created with -> () { } returns positive values for definition \n @a = -> (a, b, c:, d: 1) { }\n @b = -> (a, b, c:, d: 1, **k, &l) { }"
fails:"Proc#arity for instances created with -> () { } returns negative values for definition \n @a = -> (a: 1) { }\n @b = -> (a: 1, b: 2) { }"
fails:"Proc#arity for instances created with -> () { } returns negative values for definition \n @a = -> (a=1, b: 2) { }\n @b = -> (*a, b: 1) { }\n @c = -> (a=1, b: 2) { }\n @d = -> (a=1, *b, c: 2, &l) { }"
fails:"Proc#arity for instances created with -> () { } returns negative values for definition \n @a = -> (**k, &l) { }\n @b= -> (*a, **k) { }\n @c = ->(a: 1, b: 2, **k) { }"
fails:"Proc#arity for instances created with -> () { } returns negative values for definition \n @a = -> (a=1, *b, c:, d: 2, **k, &l) { }"
fails:"Proc#arity for instances created with -> () { } returns negative values for definition \n @a = -> (a, b=1, *c, d, e:, f: 2, **k, &l) { }\n @b = -> (a, b=1, *c, d:, e:, f: 2, **k, &l) { }\n @c = -> (a=0, b=1, *c, d, e:, f: 2, **k, &l) { }\n @d = -> (a=0, b=1, *c, d:, e:, f: 2, **k, &l) { }"
fails:"Proc#arity for instances created with lambda { || } returns positive values for definition \n @a = lambda { |a:| }\n @b = lambda { |a:, b:| }\n @c = lambda { |a: 1, b:, c:, d: 2| }"
fails:"Proc#arity for instances created with lambda { || } returns positive values for definition \n @a = lambda { |a, b:| }\n @b = lambda { |a, b:, &l| }"
fails:"Proc#arity for instances created with lambda { || } returns positive values for definition \n @a = lambda { |a, b, c:, d: 1| }\n @b = lambda { |a, b, c:, d: 1, **k, &l| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |a: 1| }\n @b = lambda { |a: 1, b: 2| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |a=1, b: 2| }\n @b = lambda { |*a, b: 1| }\n @c = lambda { |a=1, b: 2| }\n @d = lambda { |a=1, *b, c: 2, &l| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |**k, &l| }\n @b = lambda { |*a, **k| }\n @c = lambda { |a: 1, b: 2, **k| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |a=1, *b, c:, d: 2, **k, &l| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |(a, (*b, c)), d=1| }\n @b = lambda { |a, (*b, c), d, (*e), (*), **k| }\n @c = lambda { |a, (b, c), *, d:, e: 2, **| }"
fails:"Proc#arity for instances created with lambda { || } returns negative values for definition \n @a = lambda { |a, b=1, *c, d, e:, f: 2, **k, &l| }\n @b = lambda { |a, b=1, *c, d:, e:, f: 2, **k, &l| }\n @c = lambda { |a=0, b=1, *c, d, e:, f: 2, **k, &l| }\n @d = lambda { |a=0, b=1, *c, d:, e:, f: 2, **k, &l| }"
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/string/element_set_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/string/index_tags.txt

This file was deleted.

10 changes: 0 additions & 10 deletions spec/truffle/tags/core/string/match_tags.txt

This file was deleted.

9 changes: 0 additions & 9 deletions spec/truffle/tags/core/string/rindex_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/rpartition_tags.txt

This file was deleted.

10 changes: 0 additions & 10 deletions spec/truffle/tags/core/string/scan_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/split_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/core/string/strip_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/symbol/all_symbols_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Symbol.all_symbols increases size of the return array when new symbol comes
slow:Symbol.all_symbols returns an array containing all the Symbols in the symbol table
slow:Symbol.all_symbols increases size of the return array when new symbol comes
17 changes: 0 additions & 17 deletions spec/truffle/tags/core/symbol/element_reference_tags.txt

This file was deleted.

17 changes: 0 additions & 17 deletions spec/truffle/tags/core/symbol/slice_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/symbol/to_proc_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:REXML::Attributes#delete_all deletes all attributes that match name
fails:REXML::Attributes#delete_all deletes all attributes that match name with a namespace
fails:REXML::Attributes#delete_all returns the removed attribute
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Attributes#each_attribute iterates over the attributes yielding actual Attribute objects
1 change: 1 addition & 0 deletions spec/truffle/tags/library/rexml/attributes/each_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Attributes#each iterates over the attributes yielding expanded-name/value
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Attributes#[]= deletes an attribute is value is nil
1 change: 1 addition & 0 deletions spec/truffle/tags/library/rexml/attributes/length_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Attributes#length returns the number of attributes
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/attributes/prefixes_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Attributes#prefixes returns an array with the prefixes of each attribute
fails:REXML::Attributes#prefixes does not include the default namespace
1 change: 1 addition & 0 deletions spec/truffle/tags/library/rexml/attributes/size_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Attributes#size returns the number of attributes
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/attributes/to_a_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Attributes#to_a returns an array with the attributes
fails:REXML::Attributes#to_a returns an empty array if it has no attributes
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/document/clone_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Document#clone clones document attributes
fails:REXML::Document#clone clones document context
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/document/new_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Document#new can use other document context
fails:REXML::Document#new clones source attributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Element#add_element adds a child with name
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/element/attribute_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Element#attribute returns an attribute by name
fails:REXML::Element#attribute supports attributes inside namespaces
2 changes: 2 additions & 0 deletions spec/truffle/tags/library/rexml/element/attributes_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Element#attributes returns element's Attributes
fails:REXML::Element#attributes returns an empty hash if element has no attributes
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/rexml/element/clone_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:REXML::Element#clone creates a copy of element
fails:REXML::Element#clone copies the attributes
fails:REXML::Element#clone does not copy the text
fails:REXML::Element#clone does not copy the child elements
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fails:REXML::Element#delete_namespace deletes a namespace from the element
fails:REXML::Element#delete_namespace deletes default namespace when called with no args
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/rexml/element/inspect_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:REXML::Element#inspect returns the node as a string
fails:REXML::Element#inspect inserts '...' if the node has children
fails:REXML::Element#inspect inserts the attributes in the string
4 changes: 4 additions & 0 deletions spec/truffle/tags/library/rexml/element/namespaces_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fails:REXML::Element#namespaces returns a hash of the namespaces
fails:REXML::Element#namespaces returns an empty hash if no namespaces exist
fails:REXML::Element#namespaces uses namespace prefixes as keys
fails:REXML::Element#namespaces uses namespace values as the hash values
1 change: 1 addition & 0 deletions spec/truffle/tags/library/rexml/element/new_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:REXML::Element#new creates element from another element
3 changes: 3 additions & 0 deletions spec/truffle/tags/library/rexml/element/prefixes_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fails:REXML::Element#prefixes returns an array of the prefixes of the namespaces
fails:REXML::Element#prefixes does not include the default namespace
fails:REXML::Element#prefixes returns an empty array if no namespace was defined
1 change: 0 additions & 1 deletion spec/truffle/tags/library/stringscanner/getch_tags.txt

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/truffle.mspec
Original file line number Diff line number Diff line change
@@ -80,7 +80,6 @@ class MSpecScript
"^spec/ruby/library/fiber",
"^spec/ruby/library/mathn",
"^spec/ruby/library/readline",
"^spec/ruby/library/rexml",
"^spec/ruby/library/syslog",
"^spec/ruby/library/weakref",

6 changes: 6 additions & 0 deletions test/mri/excludes_truffle/TestConditionVariable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
exclude :test_condvar_wait_exception_handling, "not yet implemented"
exclude :test_condvar_wait_deadlock_2, "timeout"
exclude :test_condvar_wait_and_broadcast, "timeout"
exclude :test_condvar_wait_deadlock, "spawn"
exclude :test_dup, "needs investigation"
exclude :test_dump, "Binding#eval"
16 changes: 8 additions & 8 deletions test/mri_truffle.index
Original file line number Diff line number Diff line change
@@ -884,7 +884,7 @@ testunit/test_assertion.rb
# testunit/test_rake_integration.rb
# testunit/test_redefinition.rb
# testunit/test_sorting.rb
# thread/test_cv.rb
thread/test_cv.rb
# thread/test_sync.rb
# uri/test_common.rb
# uri/test_ftp.rb
@@ -924,10 +924,10 @@ webrick/test_utils.rb
# win32ole/test_win32ole_variant_m.rb
# win32ole/test_win32ole_variant_outarg.rb
# win32ole/test_word.rb
# xmlrpc/test_client.rb
# xmlrpc/test_cookie.rb
# xmlrpc/test_datetime.rb
# xmlrpc/test_features.rb
# xmlrpc/test_marshal.rb
# xmlrpc/test_parser.rb
# xmlrpc/test_webrick_server.rb
# xmlrpc/test_client.rb # pollutes other tests
# xmlrpc/test_cookie.rb # undefined method `http' for NilClass
xmlrpc/test_datetime.rb
xmlrpc/test_features.rb
xmlrpc/test_marshal.rb
# xmlrpc/test_parser.rb # `const_missing': uninitialized constant Test_REXMLStreamParser::GenericParserTest
# xmlrpc/test_webrick_server.rb # undefined method `<<' for Object
8 changes: 8 additions & 0 deletions tool/truffle-findbugs-exclude.xml
Original file line number Diff line number Diff line change
@@ -77,6 +77,10 @@
<Class name="org.jruby.truffle.nodes.core.MutexNodes$UnlockNode" />
<Bug pattern="IMSE_DONT_CATCH_IMSE" />
</Match>
<Match>
<Class name="~org\.jruby\.truffle\.nodes\.core\.ConditionVariableNodes\$WaitNode.*" />
<Bug pattern="WA_AWAIT_NOT_IN_LOOP" />
</Match>
<Match>
<Class name="org.jruby.truffle.nodes.core.KernelNodes$BacktickNode" />
<Bug pattern="OS_OPEN_STREAM" />
@@ -152,6 +156,10 @@
<Class name="org.jruby.truffle.runtime.RubyContext" />
<Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" />
</Match>
<Match>
<Class name="org.jruby.truffle.runtime.core.RubyMatchData$Pair" />
<Bug pattern="EQ_COMPARETO_USE_OBJECT_EQUALS" />
</Match>

<!-- These we really should fix sooner rather than later -->

3 changes: 1 addition & 2 deletions truffle/pom.rb
Original file line number Diff line number Diff line change
@@ -58,8 +58,7 @@
:artifactSet => { :includes => [
'com.oracle:truffle',
'com.oracle:truffle-interop' ] },
:shadedArtifactAttached => 'true',
:shadedClassifierName => 'complete' )
:outputFile => '${project.build.directory}/jruby-truffle-${project.version}-complete.jar' )
end
end
end
12 changes: 4 additions & 8 deletions truffle/pom.xml
Original file line number Diff line number Diff line change
@@ -114,8 +114,7 @@
<include>com.oracle:truffle-interop</include>
</includes>
</artifactSet>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>complete</shadedClassifierName>
<outputFile>${project.build.directory}/jruby-truffle-${project.version}-complete.jar</outputFile>
</configuration>
</execution>
</executions>
@@ -143,8 +142,7 @@
<include>com.oracle:truffle-interop</include>
</includes>
</artifactSet>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>complete</shadedClassifierName>
<outputFile>${project.build.directory}/jruby-truffle-${project.version}-complete.jar</outputFile>
</configuration>
</execution>
</executions>
@@ -172,8 +170,7 @@
<include>com.oracle:truffle-interop</include>
</includes>
</artifactSet>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>complete</shadedClassifierName>
<outputFile>${project.build.directory}/jruby-truffle-${project.version}-complete.jar</outputFile>
</configuration>
</execution>
</executions>
@@ -201,8 +198,7 @@
<include>com.oracle:truffle-interop</include>
</includes>
</artifactSet>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>complete</shadedClassifierName>
<outputFile>${project.build.directory}/jruby-truffle-${project.version}-complete.jar</outputFile>
</configuration>
</execution>
</executions>
12 changes: 10 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyGuards.java
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@

import com.oracle.truffle.api.interop.TruffleObject;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.ext.BigDecimalNodes;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.ext.BigDecimalNodes;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.ThreadLocalObject;
import org.jruby.truffle.runtime.core.*;
@@ -105,7 +105,11 @@ public static boolean isRubyEncoding(Object value) {
}

public static boolean isRubySymbol(Object value) {
return value instanceof RubySymbol;
return (value instanceof RubyBasicObject) && isRubySymbol((RubyBasicObject) value);
}

public static boolean isRubySymbol(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == SymbolNodes.SYMBOL_TYPE;
}

public static boolean isRubyMethod(Object value) {
@@ -124,6 +128,10 @@ public static boolean isRubyUnboundMethod(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == UnboundMethodNodes.UNBOUND_METHOD_TYPE;
}

public static boolean isRubyMutex(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == MutexNodes.MUTEX_TYPE;
}

public static boolean isRubyBasicObject(Object value) {
return value instanceof RubyBasicObject;
}
12 changes: 12 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -239,6 +239,14 @@ protected RubyBasicObject nil() {
return getContext().getCoreLibrary().getNilObject();
}

public RubyBasicObject getSymbol(String name) {
return getContext().getSymbol(name);
}

public RubyBasicObject getSymbol(ByteList name) {
return getContext().getSymbol(name);
}

protected RubyBasicObject createEmptyString() {
return StringNodes.createEmptyString(getContext().getCoreLibrary().getStringClass());
}
@@ -267,6 +275,10 @@ protected RubyBasicObject createEmptyArray() {
return ArrayNodes.createEmptyArray(getContext().getCoreLibrary().getArrayClass());
}

protected RubyBasicObject createArray(Object... store) {
return createArray(store, store.length);
}

protected RubyBasicObject createArray(int[] store, int size) {
return ArrayNodes.createArray(getContext().getCoreLibrary().getArrayClass(), store, size);
}
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -21,6 +22,8 @@
import org.jruby.truffle.runtime.hash.KeyValue;
import org.jruby.truffle.runtime.methods.Arity;

import java.util.Map;

/**
* Check arguments meet the arity of the method.
*/
@@ -67,7 +70,7 @@ public void executeVoid(VirtualFrame frame) {
}

if (!keywordsRest && keywordArguments != null) {
for (KeyValue keyValue : HashOperations.verySlowToKeyValues(keywordArguments)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(keywordArguments)) {
if (!keywordAllowed(keyValue.getKey().toString())) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("unknown keyword: " + keyValue.getKey().toString(), this));
Original file line number Diff line number Diff line change
@@ -16,12 +16,15 @@
import com.oracle.truffle.api.utilities.ValueProfile;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.hash.KeyValue;

import java.util.Map;

public class ReadKeywordArgumentNode extends RubyNode {

private final int minimum;
@@ -75,7 +78,7 @@ public Object execute(VirtualFrame frame) {
private Object lookupKeywordInHash(RubyBasicObject hash) {
assert RubyGuards.isRubyHash(hash);

for (KeyValue keyValue : HashOperations.verySlowToKeyValues(hash)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(hash)) {
if (keyValue.getKey().toString().equals(name)) {
return keyValue.getValue();
}
Original file line number Diff line number Diff line change
@@ -19,11 +19,13 @@
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.hash.BucketsStrategy;
import org.jruby.truffle.runtime.hash.HashOperations;
import org.jruby.truffle.runtime.hash.KeyValue;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ReadKeywordRestArgumentNode extends RubyNode {

@@ -65,19 +67,19 @@ private Object lookupRestKeywordArgumentHash(VirtualFrame frame) {
return HashNodes.createEmptyHash(getContext().getCoreLibrary().getHashClass());
}

final List<KeyValue> entries = new ArrayList<>();
final List<Map.Entry<Object, Object>> entries = new ArrayList<>();

outer: for (KeyValue keyValue : HashOperations.verySlowToKeyValues(hash)) {
outer: for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(hash)) {
for (String excludedKeyword : excludedKeywords) {
if (excludedKeyword.equals(keyValue.getKey().toString())) {
continue outer;
}
}

entries.add(new KeyValue(keyValue.getKey(), keyValue.getValue()));
entries.add(keyValue);
}

return HashOperations.verySlowFromEntries(getContext(), entries, HashNodes.isCompareByIdentity(hash));
return BucketsStrategy.create(getContext().getCoreLibrary().getHashClass(), entries, HashNodes.isCompareByIdentity(hash));
}

}
Original file line number Diff line number Diff line change
@@ -14,8 +14,8 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

/**
* Creates a symbol from a string.
@@ -28,8 +28,8 @@ public StringToSymbolNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubySymbol doString(RubyString string) {
return getContext().getSymbol(string.toString());
public RubyBasicObject doString(RubyString string) {
return getSymbol(string.toString());
}

}
Original file line number Diff line number Diff line change
@@ -16,12 +16,13 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.SymbolNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

/**
* Take a Symbol or some object accepting #to_str
@@ -39,9 +40,9 @@ public NameToJavaStringNode(RubyContext context, SourceSection sourceSection) {

public abstract String executeToJavaString(VirtualFrame frame, Object name);

@Specialization
public String coerceRubySymbol(RubySymbol symbol) {
return symbol.toString();
@Specialization(guards = "isRubySymbol(symbol)")
public String coerceRubySymbol(RubyBasicObject symbol) {
return SymbolNodes.getString(symbol);
}

@Specialization
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

/**
* Take a Symbol or some object accepting #to_str
@@ -40,8 +39,8 @@ public NameToSymbolOrStringNode(RubyContext context, SourceSection sourceSection

public abstract RubyBasicObject executeToSymbolOrString(VirtualFrame frame, Object name);

@Specialization
public RubySymbol coerceRubySymbol(RubySymbol symbol) {
@Specialization(guards = "isRubySymbol(symbol)")
public RubyBasicObject coerceRubySymbol(RubyBasicObject symbol) {
return symbol;
}

Original file line number Diff line number Diff line change
@@ -24,9 +24,9 @@
import org.jruby.truffle.runtime.RubyConstant;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.util.IdUtil;

@NodeChildren({
@@ -63,7 +63,7 @@ protected Object autoloadConstant(VirtualFrame frame, RubyModule module, String
protected Object missingConstant(VirtualFrame frame, RubyModule module, String name, Object constant,
@Cached("isValidConstantName(name)") boolean isValidConstantName,
@Cached("createConstMissingNode()") CallDispatchHeadNode constMissingNode,
@Cached("getContext().getSymbol(name)") RubySymbol symbolName) {
@Cached("getSymbol(name)") RubyBasicObject symbolName) {
if (!isValidConstantName) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameError(String.format("wrong constant name %s", name), name, this));
Original file line number Diff line number Diff line change
@@ -11,11 +11,13 @@

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
@@ -27,8 +29,8 @@ public class TraceNode extends RubyNode {

private final RubyContext context;

@CompilerDirectives.CompilationFinal private Assumption traceAssumption;
@CompilerDirectives.CompilationFinal private RubyProc traceFunc;
@CompilationFinal private Assumption traceAssumption;
@CompilationFinal private RubyProc traceFunc;
@Child private DirectCallNode callNode;

private final RubyBasicObject event;
Original file line number Diff line number Diff line change
@@ -15,9 +15,10 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.SymbolNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

@NodeChild(value="child", type=RubyNode.class)
public abstract class ToJavaStringNode extends RubyNode {
@@ -31,9 +32,9 @@ public ToJavaStringNode(RubyContext context, SourceSection sourceSection) {
// TODO(CS): cache the conversion to a Java String? Or should the user do that themselves?

@TruffleBoundary
@Specialization
protected String toJavaString(RubySymbol symbol) {
return symbol.toString();
@Specialization(guards = "isRubySymbol(symbol)")
protected String toJavaString(RubyBasicObject symbol) {
return SymbolNodes.getString(symbol);
}

@TruffleBoundary
Original file line number Diff line number Diff line change
@@ -16,8 +16,8 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.StringNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

@NodeChild(value="child", type=RubyNode.class)
public abstract class ToSymbolNode extends RubyNode {
@@ -26,23 +26,23 @@ public ToSymbolNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public abstract RubySymbol executeRubySymbol(VirtualFrame frame, Object object);
public abstract RubyBasicObject executeRubySymbol(VirtualFrame frame, Object object);

// TODO(CS): cache the conversion to a symbol? Or should the user do that themselves?

@Specialization
protected RubySymbol toSymbol(RubySymbol symbol) {
@Specialization(guards = "isRubySymbol(symbol)")
protected RubyBasicObject toSymbol(RubyBasicObject symbol) {
return symbol;
}

@Specialization
protected RubySymbol toSymbol(RubyString string) {
return getContext().getSymbol(StringNodes.getByteList(string));
protected RubyBasicObject toSymbol(RubyString string) {
return getSymbol(StringNodes.getByteList(string));
}

@Specialization
protected RubySymbol toSymbol(String string) {
return getContext().getSymbol(string);
protected RubyBasicObject toSymbol(String string) {
return getSymbol(string);
}

}
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;

@CoreClass(name = "BasicObject")
public abstract class BasicObjectNodes {
@@ -233,22 +232,22 @@ public Object methodMissing(Object self, Object[] args, NotProvided block) {
public Object methodMissing(Object self, Object[] args, RubyProc block) {
CompilerDirectives.transferToInterpreter();

final RubySymbol name = (RubySymbol) args[0];
final RubyBasicObject name = (RubyBasicObject) args[0];
final Object[] sentArgs = ArrayUtils.extractRange(args, 1, args.length);
return methodMissing(self, name, sentArgs, block);
}

private Object methodMissing(Object self, RubySymbol name, Object[] args, RubyProc block) {
private Object methodMissing(Object self, RubyBasicObject name, Object[] args, RubyProc block) {
CompilerDirectives.transferToInterpreter();
// TODO: should not be a call to Java toString(), but rather sth like name_err_mesg_to_str() in MRI error.c
if (lastCallWasVCall()) {
throw new RaiseException(
getContext().getCoreLibrary().nameErrorUndefinedLocalVariableOrMethod(
name.toString(),
SymbolNodes.getString(name),
getContext().getCoreLibrary().getLogicalClass(self).getName(),
this));
} else {
throw new RaiseException(getContext().getCoreLibrary().noMethodErrorOnReceiver(name.toString(), self, this));
throw new RaiseException(getContext().getCoreLibrary().noMethodErrorOnReceiver(SymbolNodes.getString(name), self, this));
}
}

Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
@@ -701,7 +702,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public RubyBasicObject toS(RubyBasicObject value, NotProvided base) {
return createString(getBigIntegerValue(value).toString());
return createString(getBigIntegerValue(value).toString(), USASCIIEncoding.INSTANCE);
}

@TruffleBoundary
@@ -712,7 +713,7 @@ public RubyBasicObject toS(RubyBasicObject value, int base) {
throw new RaiseException(getContext().getCoreLibrary().argumentErrorInvalidRadix(base, this));
}

return createString(getBigIntegerValue(value).toString(base));
return createString(getBigIntegerValue(value).toString(base), USASCIIEncoding.INSTANCE);
}

}
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNode;
import org.jruby.truffle.nodes.locals.ReadFrameSlotNodeGen;
@@ -30,7 +31,6 @@
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyBinding;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.truffle.runtime.methods.InternalMethod;

@CoreClass(name = "Binding")
@@ -68,53 +68,54 @@ public Object initializeCopy(RubyBinding self, RubyBinding from) {
@CoreMethod(names = "local_variable_get", required = 1)
public abstract static class LocalVariableGetNode extends CoreMethodArrayArgumentsNode {

private final RubySymbol dollarUnderscore;
private final RubyBasicObject dollarUnderscore;

public LocalVariableGetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dollarUnderscore = getContext().getSymbol("$_");
dollarUnderscore = getSymbol("$_");
}

@Specialization(guards = {
"isRubySymbol(symbol)",
"symbol == cachedSymbol",
"!isLastLine(cachedSymbol)",
"getFrameDescriptor(binding) == cachedFrameDescriptor"

})
public Object localVariableGetCached(RubyBinding binding, RubySymbol symbol,
@Cached("symbol") RubySymbol cachedSymbol,
public Object localVariableGetCached(RubyBinding binding, RubyBasicObject symbol,
@Cached("symbol") RubyBasicObject cachedSymbol,
@Cached("getFrameDescriptor(binding)") FrameDescriptor cachedFrameDescriptor,
@Cached("findFrameSlot(binding, symbol)") FrameSlot cachedFrameSlot,
@Cached("createReadNode(cachedFrameSlot)") ReadFrameSlotNode readLocalVariableNode) {
if (cachedFrameSlot == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(symbol.toString(), binding, this));
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(SymbolNodes.getString(symbol), binding, this));
} else {
return readLocalVariableNode.executeRead(binding.getFrame());
}
}

@TruffleBoundary
@Specialization(guards = "!isLastLine(symbol)")
public Object localVariableGetUncached(RubyBinding binding, RubySymbol symbol) {
@Specialization(guards = {"isRubySymbol(symbol)", "!isLastLine(symbol)"})
public Object localVariableGetUncached(RubyBinding binding, RubyBasicObject symbol) {
final MaterializedFrame frame = binding.getFrame();
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString());
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(SymbolNodes.getString(symbol));

if (frameSlot == null) {
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(symbol.toString(), binding, this));
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(SymbolNodes.getString(symbol), binding, this));
}

return frame.getValue(frameSlot);
}

@TruffleBoundary
@Specialization(guards = "isLastLine(symbol)")
public Object localVariableGetLastLine(RubyBinding binding, RubySymbol symbol) {
@Specialization(guards = {"isRubySymbol(symbol)", "isLastLine(symbol)"})
public Object localVariableGetLastLine(RubyBinding binding, RubyBasicObject symbol) {
final MaterializedFrame frame = binding.getFrame();
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString());
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(SymbolNodes.getString(symbol));

if (frameSlot == null) {
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(symbol.toString(), binding, this));
throw new RaiseException(getContext().getCoreLibrary().nameErrorLocalVariableNotDefined(SymbolNodes.getString(symbol), binding, this));
}

final Object value = frame.getValue(frameSlot);
@@ -129,8 +130,10 @@ protected FrameDescriptor getFrameDescriptor(RubyBinding binding) {
return binding.getFrame().getFrameDescriptor();
}

protected FrameSlot findFrameSlot(RubyBinding binding, RubySymbol symbol) {
final String symbolString = symbol.toString();
protected FrameSlot findFrameSlot(RubyBinding binding, RubyBasicObject symbol) {
assert RubyGuards.isRubySymbol(symbol);

final String symbolString = SymbolNodes.getString(symbol);

MaterializedFrame frame = binding.getFrame();

@@ -155,7 +158,7 @@ protected ReadFrameSlotNode createReadNode(FrameSlot frameSlot) {
}
}

protected boolean isLastLine(RubySymbol symbol) {
protected boolean isLastLine(RubyBasicObject symbol) {
return symbol == dollarUnderscore;
}

@@ -164,39 +167,40 @@ protected boolean isLastLine(RubySymbol symbol) {
@CoreMethod(names = "local_variable_set", required = 2)
public abstract static class LocalVariableSetNode extends CoreMethodArrayArgumentsNode {

private final RubySymbol dollarUnderscore;
private final RubyBasicObject dollarUnderscore;

public LocalVariableSetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dollarUnderscore = getContext().getSymbol("$_");
dollarUnderscore = getSymbol("$_");
}

@Specialization(guards = {
"isRubySymbol(symbol)",
"!isLastLine(symbol)",
"getFrameDescriptor(binding) == cachedFrameDescriptor",
"symbol == cachedSymbol"
})
public Object localVariableSetCached(RubyBinding binding, RubySymbol symbol, Object value,
@Cached("symbol") RubySymbol cachedSymbol,
public Object localVariableSetCached(RubyBinding binding, RubyBasicObject symbol, Object value,
@Cached("symbol") RubyBasicObject cachedSymbol,
@Cached("getFrameDescriptor(binding)") FrameDescriptor cachedFrameDescriptor,
@Cached("createWriteNode(findFrameSlot(binding, symbol))") WriteFrameSlotNode writeLocalVariableNode) {
return writeLocalVariableNode.executeWrite(binding.getFrame(), value);
}

@TruffleBoundary
@Specialization(guards = "!isLastLine(symbol)")
public Object localVariableSetUncached(RubyBinding binding, RubySymbol symbol, Object value) {
@Specialization(guards = {"isRubySymbol(symbol)", "!isLastLine(symbol)"})
public Object localVariableSetUncached(RubyBinding binding, RubyBasicObject symbol, Object value) {
final MaterializedFrame frame = binding.getFrame();
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString());
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(SymbolNodes.getString(symbol));
frame.setObject(frameSlot, value);
return value;
}

@TruffleBoundary
@Specialization(guards = "isLastLine(symbol)")
public Object localVariableSetLastLine(RubyBinding binding, RubySymbol symbol, Object value) {
@Specialization(guards = {"isRubySymbol(symbol)", "isLastLine(symbol)"})
public Object localVariableSetLastLine(RubyBinding binding, RubyBasicObject symbol, Object value) {
final MaterializedFrame frame = binding.getFrame();
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(symbol.toString());
final FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(SymbolNodes.getString(symbol));
frame.setObject(frameSlot, ThreadLocalObject.wrap(getContext(), value));
return value;
}
@@ -205,8 +209,10 @@ protected FrameDescriptor getFrameDescriptor(RubyBinding binding) {
return binding.getFrame().getFrameDescriptor();
}

protected FrameSlot findFrameSlot(RubyBinding binding, RubySymbol symbol) {
final String symbolString = symbol.toString();
protected FrameSlot findFrameSlot(RubyBinding binding, RubyBasicObject symbol) {
assert RubyGuards.isRubySymbol(symbol);

final String symbolString = SymbolNodes.getString(symbol);

MaterializedFrame frame = binding.getFrame();

@@ -227,7 +233,7 @@ protected WriteFrameSlotNode createWriteNode(FrameSlot frameSlot) {
return WriteFrameSlotNodeGen.create(frameSlot);
}

protected boolean isLastLine(RubySymbol symbol) {
protected boolean isLastLine(RubyBasicObject symbol) {
return symbol == dollarUnderscore;
}
}
@@ -249,7 +255,7 @@ public RubyBasicObject localVariables(RubyBinding binding) {
while (frame != null) {
for (Object name : frame.getFrameDescriptor().getIdentifiers()) {
if (name instanceof String) {
ArrayNodes.slowPush(array, getContext().getSymbol((String) name));
ArrayNodes.slowPush(array, getSymbol((String) name));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.object.BasicObjectType;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;

import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@CoreClass(name = "ConditionVariable")
public abstract class ConditionVariableNodes {

private static class ConditionVariableType extends BasicObjectType {
}

public static final ConditionVariableType CONDITION_VARIABLE_TYPE = new ConditionVariableType();

private static final HiddenKey ASSOCIATED_MUTEX_IDENTIFIER = new HiddenKey("associated_mutex");
private static final Property ASSOCIATED_MUTEX_PROPERTY;
private static final HiddenKey CONDITION_IDENTIFIER = new HiddenKey("condition");
private static final Property CONDITION_PROPERTY;
private static final DynamicObjectFactory CONDITION_VARIABLE_FACTORY;

static {
Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
ASSOCIATED_MUTEX_PROPERTY = Property.create(ASSOCIATED_MUTEX_IDENTIFIER,
allocator.locationForType(AtomicReference.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);
CONDITION_PROPERTY = Property.create(CONDITION_IDENTIFIER,
allocator.locationForType(AtomicReference.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);
Shape shape = RubyBasicObject.LAYOUT.createShape(CONDITION_VARIABLE_TYPE)
.addProperty(ASSOCIATED_MUTEX_PROPERTY)
.addProperty(CONDITION_PROPERTY);
CONDITION_VARIABLE_FACTORY = shape.createFactory();
}

public static class ConditionVariableAllocator implements Allocator {
@Override
public RubyBasicObject allocate(RubyContext context, RubyClass rubyClass, Node currentNode) {
return new RubyBasicObject(rubyClass, CONDITION_VARIABLE_FACTORY.newInstance(new AtomicReference<RubyBasicObject>(), new AtomicReference<Condition>()));
}
}

@SuppressWarnings("unchecked")
protected static AtomicReference<RubyBasicObject> getAssociatedMutex(RubyBasicObject mutex) {
assert mutex.getDynamicObject().getShape().hasProperty(ASSOCIATED_MUTEX_IDENTIFIER);
return (AtomicReference<RubyBasicObject>) ASSOCIATED_MUTEX_PROPERTY.get(mutex.getDynamicObject(), true);
}

@SuppressWarnings("unchecked")
protected static AtomicReference<Condition> getCondition(RubyBasicObject conditionVariable) {
assert conditionVariable.getDynamicObject().getShape().hasProperty(CONDITION_IDENTIFIER);
return (AtomicReference<Condition>) CONDITION_PROPERTY.get(conditionVariable.getDynamicObject(), true);
}

@CoreMethod(names = "broadcast")
public abstract static class BroadcastNode extends UnaryCoreMethodNode {

public BroadcastNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject broadcast(RubyBasicObject conditionVariable) {
final Condition condition = getCondition(conditionVariable).get();
final RubyBasicObject associatedMutex = getAssociatedMutex(conditionVariable).get();

if (condition == null) {
return conditionVariable;
}

if (!MutexNodes.getLock(associatedMutex).isHeldByCurrentThread()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().threadError("Called ConditionVariable#broadcast without holding associated Mutex", this));
}

condition.signalAll();

return conditionVariable;
}

}

@CoreMethod(names = "signal")
public abstract static class SignalNode extends UnaryCoreMethodNode {

public SignalNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject signal(RubyBasicObject conditionVariable) {
final Condition condition = getCondition(conditionVariable).get();
final RubyBasicObject associatedMutex = getAssociatedMutex(conditionVariable).get();

if (condition == null) {
return conditionVariable;
}

if (!MutexNodes.getLock(associatedMutex).isHeldByCurrentThread()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().threadError("Called ConditionVariable#signal without holding associated Mutex", this));
}

condition.signal();

return conditionVariable;
}

}

@CoreMethod(names = "wait", required = 1, optional = 1)
public abstract static class WaitNode extends CoreMethodArrayArgumentsNode {

public WaitNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

private static interface WaitAction {
void wait(Condition condition) throws InterruptedException;
}

@Specialization(guards = "isRubyMutex(mutex)")
RubyBasicObject wait(RubyBasicObject conditionVariable, RubyBasicObject mutex, NotProvided timeout) {
return wait(conditionVariable, mutex, nil());
}

@Specialization(guards = { "isRubyMutex(mutex)", "isNil(timeout)" })
RubyBasicObject wait(RubyBasicObject conditionVariable, RubyBasicObject mutex, RubyBasicObject timeout) {
return waitOn(conditionVariable, mutex, new WaitAction() {
@Override
public void wait(Condition condition) throws InterruptedException {
condition.await();
}
});
}

@Specialization(guards = "isRubyMutex(mutex)")
RubyBasicObject wait(RubyBasicObject conditionVariable, RubyBasicObject mutex, final int timeout) {
return wait(conditionVariable, mutex, (double) timeout);
}

@Specialization(guards = "isRubyMutex(mutex)")
RubyBasicObject wait(RubyBasicObject conditionVariable, RubyBasicObject mutex, final double timeout) {
final long timeoutInNanos = ((long) (timeout * 1_000_000_000));

return waitOn(conditionVariable, mutex, new WaitAction() {
private long remaining = timeoutInNanos;

@Override
public void wait(Condition condition) throws InterruptedException {
while (remaining > 0) {
remaining = condition.awaitNanos(remaining);
}
}
});
}

private RubyBasicObject waitOn(RubyBasicObject conditionVariable, RubyBasicObject mutex, final WaitAction waitAction) {
final AtomicReference<RubyBasicObject> associatedMutexReference = getAssociatedMutex(conditionVariable);
final AtomicReference<Condition> conditionReference = getCondition(conditionVariable);

final Condition condition;
if (associatedMutexReference.compareAndSet(null, mutex)) {
final ReentrantLock lock = MutexNodes.getLock(mutex);
condition = lock.newCondition();
conditionReference.set(condition);
} else if (associatedMutexReference.get() == mutex) {
condition = conditionReference.get();
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().threadError("Attempt to associate a ConditionVariable which already has a Mutex", this));
}

if (!MutexNodes.getLock(associatedMutexReference.get()).isHeldByCurrentThread()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().threadError("Called ConditionVariable#wait without holding associated Mutex", this));
}

getContext().getThreadManager().runUntilResult(new BlockingActionWithoutGlobalLock<Boolean>() {
@Override
public Boolean block() throws InterruptedException {
waitAction.wait(condition);
return SUCCESS;
}
});

return conditionVariable;
}

}

}
Original file line number Diff line number Diff line change
@@ -25,7 +25,10 @@
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyEncoding;
import org.jruby.truffle.runtime.core.RubyRegexp;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.util.ByteList;

@CoreClass(name = "Encoding")
@@ -113,9 +116,9 @@ public Object isCompatible(RubyRegexp first, RubyRegexp second) {
}

@TruffleBoundary
@Specialization
public Object isCompatible(RubyRegexp first, RubySymbol second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(first.getRegex().getEncoding(), second.getByteList().getEncoding());
@Specialization(guards = "isRubySymbol(second)")
public Object isCompatible(RubyRegexp first, RubyBasicObject second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(first.getRegex().getEncoding(), SymbolNodes.getByteList(second).getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
@@ -125,9 +128,9 @@ public Object isCompatible(RubyRegexp first, RubySymbol second) {
}

@TruffleBoundary
@Specialization
public Object isCompatible(RubySymbol first, RubyRegexp second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(first.getByteList().getEncoding(), second.getRegex().getEncoding());
@Specialization(guards = "isRubySymbol(first)")
public Object isCompatible(RubyBasicObject first, RubyRegexp second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(SymbolNodes.getByteList(first).getEncoding(), second.getRegex().getEncoding());

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
@@ -137,9 +140,9 @@ public Object isCompatible(RubySymbol first, RubyRegexp second) {
}

@TruffleBoundary
@Specialization
public Object isCompatible(RubyString first, RubySymbol second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getCodeRangeable(first), second);
@Specialization(guards = "isRubySymbol(second)")
public Object isCompatible(RubyString first, RubyBasicObject second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(StringNodes.getCodeRangeable(first), SymbolNodes.getCodeRangeable(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
@@ -149,9 +152,9 @@ public Object isCompatible(RubyString first, RubySymbol second) {
}

@TruffleBoundary
@Specialization
public Object isCompatible(RubySymbol first, RubySymbol second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(first, second);
@Specialization(guards = {"isRubySymbol(first)", "isRubySymbol(second)"})
public Object isCompatible(RubyBasicObject first, RubyBasicObject second) {
final Encoding compatibleEncoding = org.jruby.RubyEncoding.areCompatible(SymbolNodes.getCodeRangeable(first), SymbolNodes.getCodeRangeable(second));

if (compatibleEncoding != null) {
return RubyEncoding.getEncoding(compatibleEncoding);
@@ -362,19 +365,19 @@ public Object encodingMap(VirtualFrame frame) {

final Encoding defaultInternalEncoding = getContext().getRuntime().getDefaultInternalEncoding();
final Object internalTuple = getContext().makeTuple(frame, newTupleNode, createString("internal"), indexLookup(encodings, defaultInternalEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getContext().getSymbol("INTERNAL"), internalTuple);
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("INTERNAL"), internalTuple);

final Encoding defaultExternalEncoding = getContext().getRuntime().getDefaultExternalEncoding();
final Object externalTuple = getContext().makeTuple(frame, newTupleNode, createString("external"), indexLookup(encodings, defaultExternalEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getContext().getSymbol("EXTERNAL"), externalTuple);
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("EXTERNAL"), externalTuple);

final Encoding localeEncoding = getContext().getRuntime().getEncodingService().getLocaleEncoding();
final Object localeTuple = getContext().makeTuple(frame, newTupleNode, createString("locale"), indexLookup(encodings, localeEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getContext().getSymbol("LOCALE"), localeTuple);
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("LOCALE"), localeTuple);

final Encoding filesystemEncoding = getContext().getRuntime().getEncodingService().getLocaleEncoding();
final Object filesystemTuple = getContext().makeTuple(frame, newTupleNode, createString("filesystem"), indexLookup(encodings, filesystemEncoding));
lookupTableWriteNode.call(frame, ret, "[]=", null, getContext().getSymbol("FILESYSTEM"), filesystemTuple);
lookupTableWriteNode.call(frame, ret, "[]=", null, getSymbol("FILESYSTEM"), filesystemTuple);

return ret;
}
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.NotProvided;
@@ -203,7 +204,7 @@ public Object div(VirtualFrame frame, double a, Object b) {
redoCoercedNode = insert(DispatchHeadNodeFactory.createMethodCallOnSelf(getContext()));
}

return redoCoercedNode.call(frame, a, "redo_coerced", null, getContext().getSymbolTable().getSymbol("/"), b);
return redoCoercedNode.call(frame, a, "redo_coerced", null, getSymbol("/"), b);
}

}
@@ -678,7 +679,7 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization
public RubyBasicObject toS(double value) {
return createString(Double.toString(value));
return createString(Double.toString(value), USASCIIEncoding.INSTANCE);
}

}
114 changes: 57 additions & 57 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@
import org.jruby.truffle.nodes.core.KernelNodesFactory.SameOrEqualNodeFactory;
import org.jruby.truffle.nodes.core.KernelNodesFactory.SingletonMethodsNodeFactory;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.dispatch.*;
import org.jruby.truffle.nodes.objects.*;
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode;
@@ -66,6 +67,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@CoreClass(name = "Kernel")
public abstract class KernelNodes {
@@ -90,7 +92,7 @@ public RubyBasicObject backtick(RubyString command) {
final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (KeyValue keyValue : HashOperations.verySlowToKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

@@ -299,10 +301,10 @@ public CalleeNameNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubySymbol calleeName() {
public RubyBasicObject calleeName() {
CompilerDirectives.transferToInterpreter();
// the "called name" of a method.
return getContext().getSymbolTable().getSymbol(RubyCallStack.getCallingMethod(getContext()).getName());
return getSymbol(RubyCallStack.getCallingMethod(getContext()).getName());
}
}

@@ -551,7 +553,7 @@ private static void exec(RubyContext context, String[] commandLine) {

final RubyBasicObject env = context.getCoreLibrary().getENV();

for (KeyValue keyValue : HashOperations.verySlowToKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
builder.environment().put(keyValue.getKey().toString(), keyValue.getValue().toString());
}

@@ -839,18 +841,16 @@ public InstanceVariableDefinedNode(RubyContext context, SourceSection sourceSect
super(context, sourceSection);
}

@Specialization
public boolean isInstanceVariableDefined(RubyBasicObject object, RubyString name) {
CompilerDirectives.transferToInterpreter();

@TruffleBoundary
@Specialization(guards = "isRubyString(name)")
public boolean isInstanceVariableDefinedString(RubyBasicObject object, RubyBasicObject name) {
return object.isFieldDefined(RubyContext.checkInstanceVariableName(getContext(), name.toString(), this));
}

@Specialization
public boolean isInstanceVariableDefined(RubyBasicObject object, RubySymbol name) {
CompilerDirectives.transferToInterpreter();

return object.isFieldDefined(RubyContext.checkInstanceVariableName(getContext(), name.toString(), this));
@TruffleBoundary
@Specialization(guards = "isRubySymbol(name)")
public boolean isInstanceVariableDefinedSymbol(RubyBasicObject object, RubyBasicObject name) {
return object.isFieldDefined(RubyContext.checkInstanceVariableName(getContext(), SymbolNodes.getString(name), this));
}

}
@@ -863,15 +863,15 @@ public InstanceVariableGetNode(RubyContext context, SourceSection sourceSection)
}

@TruffleBoundary
@Specialization
public Object instanceVariableGet(RubyBasicObject object, RubyString name) {
@Specialization(guards = "isRubyString(name)")
public Object instanceVariableGetString(RubyBasicObject object, RubyBasicObject name) {
return instanceVariableGet(object, name.toString());
}

@TruffleBoundary
@Specialization
public Object instanceVariableGet(RubyBasicObject object, RubySymbol name) {
return instanceVariableGet(object, name.toString());
@Specialization(guards = "isRubySymbol(name)")
public Object instanceVariableGetSymbol(RubyBasicObject object, RubyBasicObject name) {
return instanceVariableGet(object, SymbolNodes.getString(name));
}

private Object instanceVariableGet(RubyBasicObject object, String name) {
@@ -890,16 +890,16 @@ public InstanceVariableSetNode(RubyContext context, SourceSection sourceSection)
// TODO CS 4-Mar-15 this badly needs to be cached

@TruffleBoundary
@Specialization
public Object instanceVariableSet(RubyBasicObject object, RubyString name, Object value) {
@Specialization(guards = "isRubyString(name)")
public Object instanceVariableSetString(RubyBasicObject object, RubyBasicObject name, Object value) {
RubyBasicObject.setInstanceVariable(object, RubyContext.checkInstanceVariableName(getContext(), name.toString(), this), value);
return value;
}

@TruffleBoundary
@Specialization
public Object instanceVariableSet(RubyBasicObject object, RubySymbol name, Object value) {
RubyBasicObject.setInstanceVariable(object, RubyContext.checkInstanceVariableName(getContext(), name.toString(), this), value);
@Specialization(guards = "isRubySymbol(name)")
public Object instanceVariableSetSymbol(RubyBasicObject object, RubyBasicObject name, Object value) {
RubyBasicObject.setInstanceVariable(object, RubyContext.checkInstanceVariableName(getContext(), SymbolNodes.getString(name), this), value);
return value;
}

@@ -924,7 +924,7 @@ public RubyBasicObject instanceVariables(RubyBasicObject self) {

for (Object name : instanceVariableNames) {
if (name instanceof String) {
ArrayNodes.slowPush(array, getContext().getSymbolTable().getSymbol((String) name));
ArrayNodes.slowPush(array, getSymbol((String) name));
}
}

@@ -1037,7 +1037,7 @@ public RubyBasicObject localVariables() {

for (Object name : Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.READ_ONLY, false).getFrameDescriptor().getIdentifiers()) {
if (name instanceof String) {
ArrayNodes.slowPush(array, getContext().getSymbol((String) name));
ArrayNodes.slowPush(array, getSymbol((String) name));
}
}

@@ -1054,10 +1054,10 @@ public MethodNameNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubySymbol methodName() {
public RubyBasicObject methodName() {
CompilerDirectives.transferToInterpreter();
// the "original/definition name" of the method.
return getContext().getSymbolTable().getSymbol(RubyCallStack.getCallingMethod(getContext()).getSharedMethodInfo().getName());
return getSymbol(RubyCallStack.getCallingMethod(getContext()).getSharedMethodInfo().getName());
}

}
@@ -1069,14 +1069,14 @@ public MethodNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject method(Object object, RubySymbol name) {
@Specialization(guards = "isRubyString(name)")
public RubyBasicObject methodString(Object object, RubyBasicObject name) {
return method(object, name.toString());
}

@Specialization
public RubyBasicObject method(Object object, RubyString name) {
return method(object, name.toString());
@Specialization(guards = "isRubySymbol(name)")
public RubyBasicObject methodSymbol(Object object, RubyBasicObject name) {
return method(object, SymbolNodes.getString(name));
}

private RubyBasicObject method(Object object, String name) {
@@ -1433,37 +1433,37 @@ public RespondToNode(RubyContext context, SourceSection sourceSection) {

public abstract boolean executeDoesRespondTo(VirtualFrame frame, Object object, Object name, boolean includePrivate);

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name, NotProvided checkVisibility) {
return doesRespondTo(frame, object, name, false);
@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, NotProvided checkVisibility) {
return doesRespondToString(frame, object, name, false);
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name, RubyBasicObject checkVisibility) {
return doesRespondTo(frame, object, name, false);
@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, RubyBasicObject checkVisibility) {
return doesRespondToString(frame, object, name, false);
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name, boolean ignoreVisibility) {
@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, boolean ignoreVisibility) {
if (ignoreVisibility) {
return dispatchIgnoreVisibility.doesRespondTo(frame, name, object);
} else {
return dispatch.doesRespondTo(frame, name, object);
}
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubySymbol name, NotProvided checkVisibility) {
return doesRespondTo(frame, object, name, false);
@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, NotProvided checkVisibility) {
return doesRespondToSymbol(frame, object, name, false);
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubySymbol name, RubyBasicObject checkVisibility) {
return doesRespondTo(frame, object, name, false);
@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, RubyBasicObject checkVisibility) {
return doesRespondToSymbol(frame, object, name, false);
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubySymbol name, boolean ignoreVisibility) {
@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, boolean ignoreVisibility) {
if (ignoreVisibility) {
return dispatchIgnoreVisibility.doesRespondTo(frame, name, object);
} else {
@@ -1480,23 +1480,23 @@ public RespondToMissingNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public boolean doesRespondToMissing(Object object, RubyString name, NotProvided includeAll) {
@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToMissingString(Object object, RubyBasicObject name, NotProvided includeAll) {
return false;
}

@Specialization
public boolean doesRespondToMissing(Object object, RubySymbol name, NotProvided includeAll) {
@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToMissingSymbol(Object object, RubyBasicObject name, NotProvided includeAll) {
return false;
}

@Specialization
public boolean doesRespondToMissing(Object object, RubySymbol name, boolean includeAll) {
@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToMissingString(Object object, RubyBasicObject name, boolean includeAll) {
return false;
}

@Specialization
public boolean doesRespondToMissing(Object object, RubyString name, boolean includeAll) {
@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToMissingSymbol(Object object, RubyBasicObject name, boolean includeAll) {
return false;
}

@@ -1834,7 +1834,7 @@ public boolean system(RubyString command) {
final List<String> envp = new ArrayList<>();

// TODO(CS): cast
for (KeyValue keyValue : HashOperations.verySlowToKeyValues(env)) {
for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(env)) {
envp.add(keyValue.getKey().toString() + "=" + keyValue.getValue().toString());
}

Original file line number Diff line number Diff line change
@@ -21,10 +21,15 @@
import org.jruby.truffle.nodes.coerce.ToIntNode;
import org.jruby.truffle.nodes.coerce.ToIntNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyMatchData;
import org.jruby.truffle.runtime.core.RubyRange;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.util.ByteList;

import java.util.Arrays;
@@ -65,19 +70,19 @@ public Object getIndex(RubyMatchData matchData, int index, int length) {
return createArray(store, length);
}

@Specialization
public Object getIndex(RubyMatchData matchData, RubySymbol index, NotProvided length) {
@Specialization(guards = "isRubySymbol(index)")
public Object getIndex(RubyMatchData matchData, RubyBasicObject index, NotProvided length) {
CompilerDirectives.transferToInterpreter();

try {
final int i = matchData.getBackrefNumber(index.getSymbolBytes());
final int i = matchData.getBackrefNumber(SymbolNodes.getByteList(index));

return getIndex(matchData, i, NotProvided.INSTANCE);
} catch (final ValueException e) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().indexError(String.format("undefined group name reference: %s", index.toString()), this));
getContext().getCoreLibrary().indexError(String.format("undefined group name reference: %s", SymbolNodes.getString(index)), this));
}
}

@@ -190,6 +195,38 @@ public Object end(RubyMatchData matchData, int index) {
}
}

@RubiniusOnly
@CoreMethod(names = "full")
public abstract static class FullNode extends CoreMethodArrayArgumentsNode {

@Child private CallDispatchHeadNode newTupleNode;

public FullNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public Object full(VirtualFrame frame, RubyMatchData matchData) {
if (matchData.getFullTuple() != null) {
return matchData.getFullTuple();
}

if (newTupleNode == null) {
CompilerDirectives.transferToInterpreter();
newTupleNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

final Object fullTuple = newTupleNode.call(frame,
getContext().getCoreLibrary().getTupleClass(),
"create",
null, matchData.getFullBegin(), matchData.getFullEnd());

matchData.setFullTuple(fullTuple);

return fullTuple;
}
}

@CoreMethod(names = {"length", "size"})
public abstract static class LengthNode extends CoreMethodArrayArgumentsNode {

Original file line number Diff line number Diff line change
@@ -161,10 +161,10 @@ public NameNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubySymbol name(RubyBasicObject method) {
public RubyBasicObject name(RubyBasicObject method) {
CompilerDirectives.transferToInterpreter();

return getContext().getSymbol(getMethod(method).getName());
return getSymbol(getMethod(method).getName());
}

}
105 changes: 51 additions & 54 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.Encoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.arguments.CheckArityNode;
@@ -527,13 +528,13 @@ public AutoloadNode(RubyContext context, SourceSection sourceSection) {
return ToStrNodeGen.create(getContext(), getSourceSection(), filename);
}

@Specialization
public RubyBasicObject autoload(RubyModule module, RubySymbol name, RubyString filename) {
return autoload(module, name.toString(), filename);
@Specialization(guards = "isRubySymbol(name)")
public RubyBasicObject autoloadSymbol(RubyModule module, RubyBasicObject name, RubyString filename) {
return autoload(module, SymbolNodes.getString(name), filename);
}

@Specialization
public RubyBasicObject autoload(RubyModule module, RubyString name, RubyString filename) {
@Specialization(guards = "isRubyString(name)")
public RubyBasicObject autoloadString(RubyModule module, RubyBasicObject name, RubyString filename) {
return autoload(module, name.toString(), filename);
}

@@ -561,13 +562,13 @@ public AutoloadQueryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public Object autoloadQuery(RubyModule module, RubySymbol name) {
return autoloadQuery(module, name.toString());
@Specialization(guards = "isRubySymbol(name)")
public Object autoloadQuerySymbol(RubyModule module, RubyBasicObject name) {
return autoloadQuery(module, SymbolNodes.getString(name));
}

@Specialization
public Object autoloadQuery(RubyModule module, RubyString name) {
@Specialization(guards = "isRubyString(name)")
public Object autoloadQueryString(RubyModule module, RubyBasicObject name) {
return autoloadQuery(module, name.toString());
}

@@ -701,18 +702,16 @@ public ClassVariableDefinedNode(RubyContext context, SourceSection sourceSection
super(context, sourceSection);
}

@Specialization
public boolean isClassVariableDefined(RubyModule module, RubyString name) {
CompilerDirectives.transferToInterpreter();

@TruffleBoundary
@Specialization(guards = "isRubyString(name)")
public boolean isClassVariableDefinedString(RubyModule module, RubyBasicObject name) {
return module.getClassVariables().containsKey(name.toString());
}

@Specialization
public boolean isClassVariableDefined(RubyModule module, RubySymbol name) {
CompilerDirectives.transferToInterpreter();

return module.getClassVariables().containsKey(name.toString());
@TruffleBoundary
@Specialization(guards = "isRubySymbol(name)")
public boolean isClassVariableDefinedSymbol(RubyModule module, RubyBasicObject name) {
return module.getClassVariables().containsKey(SymbolNodes.getString(name));
}

}
@@ -764,7 +763,7 @@ public RubyBasicObject getClassVariables(RubyModule module) {
final RubyBasicObject array = ArrayNodes.createEmptyArray(module.getContext().getCoreLibrary().getArrayClass());

for (String variable : ModuleOperations.getAllClassVariables(module).keySet()) {
ArrayNodes.slowPush(array, RubySymbol.newSymbol(module.getContext(), variable));
ArrayNodes.slowPush(array, getSymbol(variable));
}
return array;
}
@@ -796,7 +795,7 @@ public RubyBasicObject constants(RubyModule module, NotProvided inherit) {
public RubyBasicObject constants(RubyModule module, boolean inherit) {
CompilerDirectives.transferToInterpreter();

final List<RubySymbol> constantsArray = new ArrayList<>();
final List<RubyBasicObject> constantsArray = new ArrayList<>();

final Map<String, RubyConstant> constants;
if (inherit) {
@@ -807,7 +806,7 @@ public RubyBasicObject constants(RubyModule module, boolean inherit) {

for (Entry<String, RubyConstant> constant : constants.entrySet()) {
if (!constant.getValue().isPrivate()) {
constantsArray.add(getContext().getSymbol(constant.getKey()));
constantsArray.add(getSymbol(constant.getKey()));
}
}

@@ -873,19 +872,19 @@ public RubyNode coerceToString(RubyNode name) {
}

// Symbol
@Specialization
public Object getConstant(VirtualFrame frame, RubyModule module, RubySymbol name, NotProvided inherit) {
@Specialization(guards = "isRubySymbol(name)")
public Object getConstant(VirtualFrame frame, RubyModule module, RubyBasicObject name, NotProvided inherit) {
return getConstant(frame, module, name, true);
}

@Specialization(guards = "inherit")
public Object getConstant(VirtualFrame frame, RubyModule module, RubySymbol name, boolean inherit) {
return getConstantNode.executeGetConstant(frame, module, name.toString());
@Specialization(guards = {"inherit", "isRubySymbol(name)"})
public Object getConstant(VirtualFrame frame, RubyModule module, RubyBasicObject name, boolean inherit) {
return getConstantNode.executeGetConstant(frame, module, SymbolNodes.getString(name));
}

@Specialization(guards = "!inherit")
public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, RubySymbol name, boolean inherit) {
return getConstantNoInherit(module, name.toString(), this);
@Specialization(guards = {"!inherit", "isRubySymbol(name)"})
public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, RubyBasicObject name, boolean inherit) {
return getConstantNoInherit(module, SymbolNodes.getString(name), this);
}

// String
@@ -1020,31 +1019,31 @@ public RubyNode coerceToString(RubyNode name) {

@TruffleBoundary
@Specialization
public RubySymbol defineMethod(RubyModule module, String name, NotProvided proc, NotProvided block) {
public RubyBasicObject defineMethod(RubyModule module, String name, NotProvided proc, NotProvided block) {
throw new RaiseException(getContext().getCoreLibrary().argumentError("needs either proc or block", this));
}

@TruffleBoundary
@Specialization
public RubySymbol defineMethod(RubyModule module, String name, NotProvided proc, RubyProc block) {
public RubyBasicObject defineMethod(RubyModule module, String name, NotProvided proc, RubyProc block) {
return defineMethod(module, name, block, NotProvided.INSTANCE);
}

@TruffleBoundary
@Specialization
public RubySymbol defineMethod(RubyModule module, String name, RubyProc proc, NotProvided block) {
public RubyBasicObject defineMethod(RubyModule module, String name, RubyProc proc, NotProvided block) {
return defineMethod(module, name, proc);
}

@TruffleBoundary
@Specialization(guards = "isRubyMethod(method)")
public RubySymbol defineMethod(RubyModule module, String name, RubyBasicObject method, NotProvided block) {
public RubyBasicObject defineMethod(RubyModule module, String name, RubyBasicObject method, NotProvided block) {
module.addMethod(this, MethodNodes.getMethod(method).withName(name));
return getContext().getSymbolTable().getSymbol(name);
return getSymbol(name);
}

@Specialization(guards = "isRubyUnboundMethod(method)")
public RubySymbol defineMethod(VirtualFrame frame, RubyModule module, String name, RubyBasicObject method, NotProvided block) {
public RubyBasicObject defineMethod(VirtualFrame frame, RubyModule module, String name, RubyBasicObject method, NotProvided block) {
CompilerDirectives.transferToInterpreter();

RubyModule origin = UnboundMethodNodes.getOrigin(method);
@@ -1058,7 +1057,7 @@ public RubySymbol defineMethod(VirtualFrame frame, RubyModule module, String nam
return addMethod(module, name, UnboundMethodNodes.getMethod(method));
}

private RubySymbol defineMethod(RubyModule module, String name, RubyProc proc) {
private RubyBasicObject defineMethod(RubyModule module, String name, RubyProc proc) {
CompilerDirectives.transferToInterpreter();

final CallTarget modifiedCallTarget = proc.getCallTargetForLambdas();
@@ -1068,15 +1067,15 @@ private RubySymbol defineMethod(RubyModule module, String name, RubyProc proc) {
return addMethod(module, name, modifiedMethod);
}

private RubySymbol addMethod(RubyModule module, String name, InternalMethod method) {
private RubyBasicObject addMethod(RubyModule module, String name, InternalMethod method) {
method = method.withName(name);

if (ModuleOperations.isMethodPrivateFromName(name)) {
method = method.withVisibility(Visibility.PRIVATE);
}

module.addMethod(this, method);
return getContext().getSymbolTable().getSymbol(name);
return getSymbol(name);
}

}
@@ -1643,8 +1642,8 @@ public RubyModule privateConstant(RubyModule module, Object[] args) {
CompilerDirectives.transferToInterpreter();

for (Object name : args) {
if (name instanceof RubySymbol) {
module.changeConstantVisibility(this, name.toString(), true);
if (RubyGuards.isRubySymbol(name)) {
module.changeConstantVisibility(this, SymbolNodes.getString((RubyBasicObject) name), true);
} else {
throw new UnsupportedOperationException();
}
@@ -1665,8 +1664,8 @@ public RubyModule publicConstant(RubyModule module, Object[] args) {
CompilerDirectives.transferToInterpreter();

for (Object name : args) {
if (name instanceof RubySymbol) {
module.changeConstantVisibility(this, name.toString(), false);
if (RubyGuards.isRubySymbol(name)) {
module.changeConstantVisibility(this, SymbolNodes.getString((RubyBasicObject) name), false);
} else {
throw new UnsupportedOperationException();
}
@@ -1699,19 +1698,17 @@ public RemoveClassVariableNode(RubyContext context, SourceSection sourceSection)
super(context, sourceSection);
}

@Specialization
public RubyModule removeClassVariable(RubyModule module, RubyString name) {
CompilerDirectives.transferToInterpreter();

@TruffleBoundary
@Specialization(guards = "isRubyString(name)")
public RubyModule removeClassVariableString(RubyModule module, RubyBasicObject name) {
module.removeClassVariable(this, name.toString());
return module;
}

@Specialization
public RubyModule removeClassVariable(RubyModule module, RubySymbol name) {
CompilerDirectives.transferToInterpreter();

module.removeClassVariable(this, name.toString());
@TruffleBoundary
@Specialization(guards = "isRubySymbol(name)")
public RubyModule removeClassVariableSymbol(RubyModule module, RubyBasicObject name) {
module.removeClassVariable(this, SymbolNodes.getString(name));
return module;
}

@@ -1774,7 +1771,7 @@ private void removeMethod(VirtualFrame frame, RubyModule module, String name) {
CompilerDirectives.transferToInterpreter();
if (module.getMethods().containsKey(name)) {
module.removeMethod(name);
methodRemovedNode.call(frame, module, "method_removed", null, getContext().getSymbol(name));
methodRemovedNode.call(frame, module, "method_removed", null, getSymbol(name));
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().nameErrorMethodNotDefinedIn(module, name, this));
@@ -1828,7 +1825,7 @@ private void undefMethod(VirtualFrame frame, RubyModule module, String name) {

if (method != null) {
module.undefMethod(this, method);
methodUndefinedNode.call(frame, module, "method_undefined", null, getContext().getSymbol(name));
methodUndefinedNode.call(frame, module, "method_undefined", null, getSymbol(name));
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().noMethodErrorOnModule(name, module, this));
Original file line number Diff line number Diff line change
@@ -14,12 +14,14 @@
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyThread;
import org.jruby.truffle.runtime.object.BasicObjectType;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;

import java.util.EnumSet;
@@ -28,14 +30,19 @@
@CoreClass(name = "Mutex")
public abstract class MutexNodes {

private static class MutexType extends BasicObjectType {
}

public static final MutexType MUTEX_TYPE = new MutexType();

private static final HiddenKey LOCK_IDENTIFIER = new HiddenKey("lock");
private static final Property LOCK_PROPERTY;
private static final DynamicObjectFactory MUTEX_FACTORY;

static {
Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
LOCK_PROPERTY = Property.create(LOCK_IDENTIFIER, allocator.locationForType(ReentrantLock.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);
Shape shape = RubyBasicObject.EMPTY_SHAPE.addProperty(LOCK_PROPERTY);
Shape shape = RubyBasicObject.LAYOUT.createShape(MUTEX_TYPE).addProperty(LOCK_PROPERTY);
MUTEX_FACTORY = shape.createFactory();
}

Loading

0 comments on commit cba68fd

Please sign in to comment.