Skip to content

Commit

Permalink
Showing 81 changed files with 1,327 additions and 618 deletions.
30 changes: 19 additions & 11 deletions core/pom.rb
Original file line number Diff line number Diff line change
@@ -252,16 +252,24 @@
'shadedPattern' => 'org.jruby.org.objectweb' } ],
'outputFile' => '${jruby.basedir}/lib/jruby.jar',
'transformers' => [ { '@implementation' => 'org.apache.maven.plugins.shade.resource.ManifestResourceTransformer',
'mainClass' => 'org.jruby.Main' } ] )
execute_goals( 'shade',
:id => 'shade the asm classes',
:phase => 'package',
'artifactSet' => {
'includes' => [ 'com.github.jnr:jnr-ffi',
'org.ow2.asm:*' ]
},
'relocations' => [ { 'pattern' => 'org.objectweb',
'shadedPattern' => 'org.jruby.org.objectweb' } ] )
'mainClass' => 'org.jruby.Main' } ],
:artifactSet => { :excludes => ['com.github.jnr:jffi:native'] } )
end

[:release, :main, :osgi, :j2ee, :complete, :dist, :'jruby_complete_jar_extended', :'jruby-jars' ].each do |name|
profile name do
plugin :shade do
execute_goals( 'shade',
:id => 'shade the asm classes',
:phase => 'package',
'artifactSet' => {
'includes' => [ 'com.github.jnr:jnr-ffi',
'org.ow2.asm:*' ]
},
'relocations' => [ { 'pattern' => 'org.objectweb',
'shadedPattern' => 'org.jruby.org.objectweb' } ] )
end
end
end

profile 'jruby.bash' do
@@ -322,7 +330,7 @@
profile 'build.properties' do

activation do
file( :exits => '../build.properties' )
file( :exists => '../build.properties' )
end

plugin 'org.codehaus.mojo:properties-maven-plugin:1.0-alpha-2' do
290 changes: 270 additions & 20 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -544,34 +544,282 @@
<mainClass>org.jruby.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
<excludes>
<exclude>com.github.jnr:jffi:native</exclude>
</excludes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>main</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>osgi</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>j2ee</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>complete</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dist</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jruby_complete_jar_extended</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jruby-jars</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade the asm classes</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.github.jnr:jnr-ffi</include>
<include>org.ow2.asm:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jruby.bash</id>
<activation>
@@ -651,7 +899,9 @@
<profile>
<id>build.properties</id>
<activation>
<file />
<file>
<exists>../build.properties</exists>
</file>
</activation>
<build>
<plugins>
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -927,7 +927,7 @@ private TruffleContextInterface loadTruffleContext() {
try {
clazz = getJRubyClassLoader().loadClass("org.jruby.truffle.runtime.RubyContext");
} catch (Exception e) {
throw new UnsupportedOperationException("Truffle classes not available", e);
throw new RuntimeException("Truffle backend not available", e);
}

final TruffleContextInterface truffleBridge;
@@ -936,7 +936,7 @@ private TruffleContextInterface loadTruffleContext() {
Constructor<?> con = clazz.getConstructor(Ruby.class);
truffleBridge = (TruffleContextInterface) con.newInstance(this);
} catch (Exception e) {
throw new UnsupportedOperationException("Error while calling the constructor of TruffleBridgeImpl", e);
throw new RuntimeException("Error while calling the constructor of Truffle's RubyContext", e);
}

return truffleBridge;
10 changes: 5 additions & 5 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -2251,8 +2251,9 @@ public Operand buildEnsureInternal(Node ensureBodyNode, Node ensurerNode) {
activeRescuers.pop();

// Clone the ensure body and jump to the end.
// Don't bother if the protected body ended in a return.
if (rv != U_NIL && !(ensureBodyNode instanceof RescueNode)) {
// Don't bother if the protected body ended in a return
// OR if we are really processing a rescue node
if (ensurerNode != null && rv != U_NIL && !(ensureBodyNode instanceof RescueNode)) {
ebi.cloneIntoHostScope(this);
addInstr(new JumpInstr(ebi.end));
}
@@ -3069,9 +3070,8 @@ private Operand buildRescueInternal(RescueNode rescueNode, EnsureBlockInfo ensur
activeRescuers.pop();

// Else part of the body -- we simply fall through from the main body if there were no exceptions
Label elseLabel = rescueNode.getElseNode() == null ? null : getNewLabel();
if (elseLabel != null) {
addInstr(new LabelInstr(elseLabel));
if (rescueNode.getElseNode() != null) {
addInstr(new LabelInstr(getNewLabel()));
tmp = build(rescueNode.getElseNode());
}

14 changes: 3 additions & 11 deletions core/src/main/java/org/jruby/lexer/ByteListLexerSource.java
Original file line number Diff line number Diff line change
@@ -43,20 +43,12 @@ public void setEncoding(Encoding encoding) {
@Override
public ByteList gets() {
int length = completeSource.length();
if (offset == length) return null; // At end of source/eof
if (offset >= length) return null; // At end of source/eof

int end = offset;

while (end < length) {
if (completeSource.get(end) == '\n') {
end++; // include newline
break;
}
end++;
}
int end = completeSource.indexOf('\n', offset) + 1;
if (end == 0) end = length;

ByteList line = completeSource.makeShared(offset, end - offset);

offset = end;

if (scriptLines != null) scriptLines.append(RubyString.newString(scriptLines.getRuntime(), line));
8 changes: 6 additions & 2 deletions maven/jruby-complete/pom.rb
Original file line number Diff line number Diff line change
@@ -15,7 +15,10 @@
'jruby.complete.home' => '${project.build.outputDirectory}/META-INF/jruby.home' )

scope :provided do
jar 'org.jruby:jruby-core:${project.version}'
jar 'org.jruby:jruby-core:${project.version}' do
# this needs to match the Embed-Dependency on the maven-bundle-plugin
exclusion 'com.github.jnr:jnr-ffi'
end
jar 'org.jruby:jruby-stdlib:${project.version}'
end

@@ -33,7 +36,8 @@
'Bundle-Name' => 'JRuby ${project.version}',
'Bundle-Description' => 'JRuby ${project.version} OSGi bundle',
'Bundle-SymbolicName' => 'org.jruby.jruby',
'Embed-Dependency' => '*;type=jar;scope=provided;inline=true',
# the artifactId exclusion needs to match the jruby-core from above
'Embed-Dependency' => '*;type=jar;scope=provided;inline=true;artifactId=!jnr-ffi',
'Embed-Transitive' => true
} ) do
# TODO fix DSL
8 changes: 7 additions & 1 deletion maven/jruby-complete/pom.xml
Original file line number Diff line number Diff line change
@@ -23,6 +23,12 @@
<artifactId>jruby-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
<groupId>com.github.jnr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
@@ -51,7 +57,7 @@
<Bundle-Name>JRuby ${project.version}</Bundle-Name>
<Bundle-Description>JRuby ${project.version} OSGi bundle</Bundle-Description>
<Bundle-SymbolicName>org.jruby.jruby</Bundle-SymbolicName>
<Embed-Dependency>*;type=jar;scope=provided;inline=true</Embed-Dependency>
<Embed-Dependency>*;type=jar;scope=provided;inline=true;artifactId=!jnr-ffi</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
4 changes: 2 additions & 2 deletions maven/jruby-complete/src/it/integrity/pom.xml
Original file line number Diff line number Diff line change
@@ -148,8 +148,8 @@
<!-- make sure openssl loads -->
<argument>
begin
import_java "org.objectweb.asm.ClassWriter"
raise "error there is org.objectweb.asm.ClassWriter on the classpath"
a = org.objectweb.asm.ClassWriter
raise "error there is org.objectweb.asm.ClassWriter on the classpath: #{a}"
rescue NameError => e
puts "there is NO org.objectweb.asm.ClassWriter on the classpath"
end
2 changes: 1 addition & 1 deletion maven/pom.rb
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@
# module to profile map
map = { 'jruby' => [ :release, :main, :osgi, :j2ee ],
'jruby-complete' => [ :release, :complete, :osgi, :'jruby_complete_jar_extended'],
'jruby-jars' => [ :release, 'jruby-jars' ],
'jruby-jars' => [ :release, :'jruby-jars' ],
'jruby-dist' => [ :release, :dist ]
}

12 changes: 6 additions & 6 deletions spec/ruby/core/kernel/singleton_methods_spec.rb
Original file line number Diff line number Diff line change
@@ -4,27 +4,27 @@

describe :kernel_singleton_methods, :shared => true do
it "returns an empty Array for an object with no singleton methods" do
ReflectSpecs.o.singleton_methods(@object).should == []
ReflectSpecs.o.singleton_methods(*@object).should == []
end

it "returns the names of module methods for a module" do
ReflectSpecs::M.singleton_methods(@object).should include(*stasy(:ms_pro, :ms_pub))
ReflectSpecs::M.singleton_methods(*@object).should include(*stasy(:ms_pro, :ms_pub))
end

it "does not return private module methods for a module" do
ReflectSpecs::M.singleton_methods(@object).should_not include(stasy(:ms_pri))
ReflectSpecs::M.singleton_methods(*@object).should_not include(stasy(:ms_pri))
end

it "returns the names of class methods for a class" do
ReflectSpecs::A.singleton_methods(@object).should include(*stasy(:as_pro, :as_pub))
ReflectSpecs::A.singleton_methods(*@object).should include(*stasy(:as_pro, :as_pub))
end

it "does not return private class methods for a class" do
ReflectSpecs::A.singleton_methods(@object).should_not include(stasy(:as_pri))
ReflectSpecs::A.singleton_methods(*@object).should_not include(stasy(:as_pri))
end

it "returns the names of singleton methods for an object" do
ReflectSpecs.os.singleton_methods(@object).should include(*stasy(:os_pro, :os_pub))
ReflectSpecs.os.singleton_methods(*@object).should include(*stasy(:os_pro, :os_pub))
end
end

5 changes: 0 additions & 5 deletions spec/truffle/tags/core/kernel/methods_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/kernel/private_methods_tags.txt

This file was deleted.

11 changes: 0 additions & 11 deletions spec/truffle/tags/core/kernel/protected_methods_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/kernel/public_methods_tags.txt

This file was deleted.

33 changes: 0 additions & 33 deletions spec/truffle/tags/core/kernel/singleton_methods_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/thread/new_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:Thread.new can pass arguments to the thread block
fails:Thread.new raises an exception when not given a block
fails:Thread.new creates a subclass of thread calls super with a block in initialize
fails:Thread.new calls #initialize and raises an error if super not used
1 change: 0 additions & 1 deletion spec/truffle/tags/library/cgi/cookie/path_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/cgi/cookie/to_s_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:CGI::Cookie#to_s returns a String representation of self
fails:CGI::Cookie#to_s escapes the self's values
1 change: 0 additions & 1 deletion spec/truffle/tags/library/cgi/http_header_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/cgi/rfc1123_date_tags.txt

This file was deleted.

1 change: 1 addition & 0 deletions test/mri/excludes_truffle/TestERBCore.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
exclude :test_def_erb_method, "needs investigation"
exclude :test_def_method_with_fname, "needs investigation"
exclude :test_def_method_without_filename, "needs investigation"
exclude :test_keep_lineno, "needs investigation"
3 changes: 0 additions & 3 deletions test/mri/excludes_truffle/TestERBCoreWOStrScan.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
exclude :test_def_erb_method, "needs investigation"
exclude :test_def_method_with_fname, "needs investigation"
exclude :test_def_method_without_filename, "needs investigation"
exclude :test_keep_lineno, "needs investigation"

This file was deleted.

This file was deleted.

24 changes: 14 additions & 10 deletions test/mri/excludes_truffle/TestSprintfComb.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
exclude :test_format_float(%-00.E) , "needs investigation"
exclude :test_format_float(%.E) , "needs investigation"
exclude :test_format_float(%0.e) , "needs investigation"
exclude :test_format_float(%0E) , "needs investigation"
exclude :test_format_float(%e) , "needs investigation"
exclude :test_format_integer(%-00.b) , "needs investigation"
exclude :test_format_integer(%.b) , "needs investigation"
exclude :test_format_integer(%0.B) , "needs investigation"
exclude :test_format_integer(%0b) , "needs investigation"
exclude :test_format_integer(%B) , "needs investigation"
exclude :"test_format_float(%-00.E)", "needs investigation"
exclude :"test_format_float(%.E)", "needs investigation"
exclude :"test_format_float(%0.e)", "needs investigation"
exclude :"test_format_float(%0E)", "needs investigation"
exclude :"test_format_float(%e)", "needs investigation"
exclude :"test_format_integer(%-00.b)", "needs investigation"
exclude :"test_format_integer(%.b)", "needs investigation"
exclude :"test_format_integer(%0.B)", "needs investigation"
exclude :"test_format_integer(%0b)", "needs investigation"
exclude :"test_format_integer(%B)", "needs investigation"
exclude :"test_format_float(% #+-0e)", "needs investigation"
exclude :"test_format_float(% #+0.E)", "needs investigation"
exclude :"test_format_integer(% #+-0B)", "needs investigation"
exclude :"test_format_integer(% #+0.b)", "needs investigation"
2 changes: 2 additions & 0 deletions test/mri/excludes_truffle/TestTranscode.rb
Original file line number Diff line number Diff line change
@@ -21,3 +21,5 @@
exclude :test_utf_32, "needs investigation"
exclude :test_utf_16 , "needs investigation"
exclude :test_utf_32 , "needs investigation"
exclude :"test_pseudo_encoding_inspect(UTF-16)", "needs investigation"
exclude :"test_pseudo_encoding_inspect(UTF-32)", "needs investigation"
6 changes: 3 additions & 3 deletions test/mri_truffle.index
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ ruby/test_signal.rb
# ruby/test_sleep.rb # cannot load such file -- etc
ruby/test_sprintf.rb

# ruby/test_sprintf_comb.rb # syntax error, unexpected tLPAREN2
ruby/test_sprintf_comb.rb
ruby/test_string.rb
ruby/test_stringchar.rb
ruby/test_struct.rb
@@ -96,7 +96,7 @@ ruby/test_thread.rb
ruby/test_time.rb
ruby/test_time_tz.rb
ruby/test_trace.rb
# ruby/test_transcode.rb # exclude methods with parentheses
ruby/test_transcode.rb
ruby/test_undef.rb
ruby/test_unicode_escape.rb
ruby/test_variable.rb
@@ -176,7 +176,7 @@ date/test_switch_hitter.rb
# digest/test_digest.rb
# digest/test_digest_extend.rb

# erb/test_erb.rb # unit.rb:1094:in `abort': wrong number of arguments (1 for 0) (ArgumentError)
erb/test_erb.rb
erb/test_erb_m17n.rb

# etc/test_etc.rb
8 changes: 4 additions & 4 deletions tool/truffle-findbugs-exclude.xml
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@
<Bug pattern="DM_EXIT" />
</Match>
<Match>
<Class name="org.jruby.truffle.nodes.TopLevelRaiseHandler" />
<Class name="org.jruby.truffle.nodes.exceptions.TopLevelRaiseHandler" />
<Bug pattern="DM_EXIT" />
</Match>

@@ -44,7 +44,7 @@
<!-- Sometimes we really do want to compare floating point equality -->

<Match>
<Class name="org.jruby.truffle.nodes.core.FixnumNodes$PowNode" />
<Class name="org.jruby.truffle.nodes.core.fixnum.FixnumNodes$PowNode" />
<Bug pattern="FE_FLOATING_POINT_EQUALITY" />
</Match>
<Match>
@@ -56,7 +56,7 @@
<Bug pattern="FE_FLOATING_POINT_EQUALITY" />
</Match>
<Match>
<Class name="org.jruby.truffle.nodes.core.FixnumNodes$EqualNode" />
<Class name="org.jruby.truffle.nodes.core.fixnum.FixnumNodes$EqualNode" />
<Bug pattern="FE_FLOATING_POINT_EQUALITY" />
</Match>
<Match>
@@ -124,7 +124,7 @@
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON" />
</Match>
<Match>
<Class name="org.jruby.truffle.nodes.RubyCallNode" />
<Class name="org.jruby.truffle.nodes.dispatch.RubyCallNode" />
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS" />
</Match>

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.arguments;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ValueProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;

public class WritePreArgumentNode extends RubyNode {

@Child private RubyNode rhs;

private final int index;

public WritePreArgumentNode(RubyContext context, SourceSection sourceSection, int index, RubyNode rhs) {
super(context, sourceSection);
this.index = index;
this.rhs = rhs;
}

@Override
public Object execute(VirtualFrame frame) {
RubyArguments.setUserArgument(frame.getArguments(), index, rhs.execute(frame));
return nil();
}

}
Original file line number Diff line number Diff line change
@@ -92,6 +92,10 @@ public boolean executeRepeating(VirtualFrame frame) {
}
}

@Override
public String toString() {
return condition.getEncapsulatingSourceSection().getShortDescription();
}
}

private static class DoWhileRepeatingNode extends WhileRepeatingBaseNode implements RepeatingNode {
117 changes: 77 additions & 40 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/BignumNodes.java
Original file line number Diff line number Diff line change
@@ -13,31 +13,68 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyBignum;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.*;

import java.math.BigInteger;
import java.util.EnumSet;
import java.util.concurrent.locks.ReentrantLock;

@CoreClass(name = "Bignum")
public abstract class BignumNodes {

public static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
public static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);

private static final HiddenKey VALUE_IDENTIFIER = new HiddenKey("value");
public static final Property VALUE_PROPERTY;

static {
Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
VALUE_PROPERTY = Property.create(VALUE_IDENTIFIER, allocator.locationForType(BigInteger.class, EnumSet.of(LocationModifier.NonNull)), 0);
}

public static Allocator createBigumAllocator(Shape emptyShape) {
Shape shape = emptyShape.addProperty(VALUE_PROPERTY);
final DynamicObjectFactory factory = shape.createFactory();

return new Allocator() {
@Override
public RubyBasicObject allocate(RubyContext context, RubyClass rubyClass, Node currentNode) {
return new RubyBignum(rubyClass, factory.newInstance(BigInteger.ZERO));
}
};
}

public static RubyBasicObject createRubyBignum(RubyClass rubyClass, BigInteger value) {
final RubyBasicObject bignum = rubyClass.getAllocator().allocate(rubyClass.getContext(), rubyClass, null);

try {
VALUE_PROPERTY.set(bignum.getDynamicObject(), value, bignum.getDynamicObject().getShape());
} catch (IncompatibleLocationException e) {
throw new UnsupportedOperationException();
} catch (FinalLocationException e) {
throw new UnsupportedOperationException();
}

return bignum;
}

public static BigInteger getBigIntegerValue(RubyBasicObject bignum) {
return ((RubyBignum) bignum).internalGetBigIntegerValue();
assert bignum.getDynamicObject().getShape().hasProperty(VALUE_IDENTIFIER);
return (BigInteger) VALUE_PROPERTY.get(bignum.getDynamicObject(), true);
}

public static abstract class BignumCoreMethodNode extends CoreMethodArrayArgumentsNode {
@@ -91,8 +128,8 @@ public double add(RubyBasicObject a, double b) {
return getBigIntegerValue(a).doubleValue() + b;
}

@Specialization
public Object add(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object add(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).add(getBigIntegerValue(b)));
}

@@ -120,8 +157,8 @@ public double sub(RubyBasicObject a, double b) {
return getBigIntegerValue(a).doubleValue() - b;
}

@Specialization
public Object sub(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object sub(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).subtract(getBigIntegerValue(b)));
}

@@ -152,8 +189,8 @@ public double mul(RubyBasicObject a, double b) {
}

@TruffleBoundary
@Specialization
public Object mul(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object mul(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).multiply(getBigIntegerValue(b)));
}

@@ -181,8 +218,8 @@ public double div(RubyBasicObject a, double b) {
return getBigIntegerValue(a).doubleValue() / b;
}

@Specialization
public Object div(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object div(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).divide(getBigIntegerValue(b)));
}

@@ -219,8 +256,8 @@ public Object mod(RubyBasicObject a, long b) {
return fixnumOrBignum(getBigIntegerValue(a).mod(BigInteger.valueOf(b)));
}

@Specialization
public Object mod(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object mod(RubyBasicObject a, RubyBasicObject b) {
final BigInteger bigint = getBigIntegerValue(b);
final int compare = bigint.compareTo(BigInteger.ZERO);
if (compare == 0) {
@@ -233,7 +270,7 @@ public Object mod(RubyBasicObject a, RubyBignum b) {
}

@Specialization(guards = {"!isInteger(b)", "!isLong(b)", "!isRubyBignum(b)"})
public Object mod(VirtualFrame frame, RubyBignum a, Object b) {
public Object mod(VirtualFrame frame, RubyBasicObject a, Object b) {
return ruby(frame, "redo_coerced :%, other", "other", b);
}

@@ -261,13 +298,13 @@ public boolean less(RubyBasicObject a, double b) {
return Double.compare(getBigIntegerValue(a).doubleValue(), b) < 0;
}

@Specialization
public boolean less(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean less(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).compareTo(getBigIntegerValue(b)) < 0;
}

@Specialization(guards = "!isRubyBignum(b)")
public Object lessCoerced(VirtualFrame frame, RubyBignum a, RubyBasicObject b) {
public Object lessCoerced(VirtualFrame frame, RubyBasicObject a, RubyBasicObject b) {
return ruby(frame, "redo_coerced :<, b", "b", b);
}

@@ -295,8 +332,8 @@ public boolean lessEqual(RubyBasicObject a, double b) {
return getBigIntegerValue(a).compareTo(BigInteger.valueOf((long) b)) <= 0;
}

@Specialization
public boolean lessEqual(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean lessEqual(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).compareTo(getBigIntegerValue(b)) <= 0;
}
}
@@ -326,13 +363,13 @@ public boolean equal(RubyBasicObject a, double b) {
return getBigIntegerValue(a).doubleValue() == b;
}

@Specialization
public boolean equal(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean equal(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).equals(getBigIntegerValue(b));
}

@Specialization(guards = "!isRubyBignum(b)")
public Object equal(VirtualFrame frame, RubyBignum a, RubyBasicObject b) {
public Object equal(VirtualFrame frame, RubyBasicObject a, RubyBasicObject b) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreter();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
@@ -377,8 +414,8 @@ public int compare(RubyBasicObject a, double b) {
}
}

@Specialization
public int compare(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public int compare(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).compareTo(getBigIntegerValue(b));
}
}
@@ -405,8 +442,8 @@ public boolean greaterEqual(RubyBasicObject a, double b) {
return Double.compare(getBigIntegerValue(a).doubleValue(), b) >= 0;
}

@Specialization
public boolean greaterEqual(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean greaterEqual(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).compareTo(getBigIntegerValue(b)) >= 0;
}
}
@@ -433,8 +470,8 @@ public boolean greater(RubyBasicObject a, double b) {
return Double.compare(getBigIntegerValue(a).doubleValue(), b) > 0;
}

@Specialization
public boolean greater(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean greater(RubyBasicObject a, RubyBasicObject b) {
return getBigIntegerValue(a).compareTo(getBigIntegerValue(b)) > 0;
}
}
@@ -456,8 +493,8 @@ public Object bitAnd(RubyBasicObject a, long b) {
return fixnumOrBignum(getBigIntegerValue(a).and(BigInteger.valueOf(b)));
}

@Specialization
public Object bitAnd(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object bitAnd(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).and(getBigIntegerValue(b)));
}
}
@@ -479,8 +516,8 @@ public Object bitOr(RubyBasicObject a, long b) {
return fixnumOrBignum(getBigIntegerValue(a).or(BigInteger.valueOf(b)));
}

@Specialization
public Object bitOr(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object bitOr(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).or(getBigIntegerValue(a)));
}
}
@@ -502,8 +539,8 @@ public Object bitXOr(RubyBasicObject a, long b) {
return fixnumOrBignum(getBigIntegerValue(a).xor(BigInteger.valueOf(b)));
}

@Specialization
public Object bitXOr(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public Object bitXOr(RubyBasicObject a, RubyBasicObject b) {
return fixnumOrBignum(getBigIntegerValue(a).xor(getBigIntegerValue(b)));
}
}
@@ -605,8 +642,8 @@ public RubyArray coerce(RubyBasicObject a, long b) {
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), store, store.length);
}

@Specialization
public RubyArray coerce(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public RubyArray coerce(RubyBasicObject a, RubyBasicObject b) {
CompilerDirectives.transferToInterpreter();

Object[] store = new Object[] { b, a };
@@ -635,8 +672,8 @@ public RubyArray divMod(RubyBasicObject a, long b) {
return divModNode.execute(getBigIntegerValue(a), b);
}

@Specialization
public RubyArray divMod(RubyBasicObject a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public RubyArray divMod(RubyBasicObject a, RubyBasicObject b) {
return divModNode.execute(getBigIntegerValue(a), getBigIntegerValue(b));
}

Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBignum;

import java.math.BigDecimal;
import java.math.BigInteger;
@@ -50,7 +49,7 @@ public Object fixnumOrBignum(BigInteger value) {
return longValue;
}
} else {
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), value);
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), value);
}
}

58 changes: 29 additions & 29 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/FloatNodes.java
Original file line number Diff line number Diff line change
@@ -61,8 +61,8 @@ public double add(double a, double b) {
return a + b;
}

@Specialization
public double add(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double add(double a, RubyBasicObject b) {
return a + BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -90,8 +90,8 @@ public double sub(double a, double b) {
return a - b;
}

@Specialization
public double sub(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double sub(double a, RubyBasicObject b) {
return a - BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -124,8 +124,8 @@ public double mul(double a, double b) {
return a * b;
}

@Specialization
public double mul(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double mul(double a, RubyBasicObject b) {
return a * BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -175,8 +175,8 @@ public Object pow(VirtualFrame frame, double a, double b) {
}
}

@Specialization
public double pow(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double pow(double a, RubyBasicObject b) {
return Math.pow(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

@@ -211,8 +211,8 @@ public double div(double a, double b) {
return a / b;
}

@Specialization
public double div(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double div(double a, RubyBasicObject b) {
return a / BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -267,8 +267,8 @@ public double mod(double a, double b) {
return result;
}

@Specialization
public double mod(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double mod(double a, RubyBasicObject b) {
return mod(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

@@ -299,9 +299,9 @@ public RubyArray divMod(double a, double b) {
return divModNode.execute(a, b);
}

@Specialization
public RubyArray divMod(double a, RubyBignum b) {
return divModNode.execute(a, b);
@Specialization(guards = "isRubyBignum(b)")
public RubyArray divMod(double a, RubyBasicObject b) {
return divModNode.execute(a, BignumNodes.getBigIntegerValue(b));
}

}
@@ -328,8 +328,8 @@ public boolean less(double a, double b) {
return a < b;
}

@Specialization
public boolean less(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean lessBignum(double a, RubyBasicObject b) {
return a < BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -362,8 +362,8 @@ public boolean lessEqual(double a, double b) {
return a <= b;
}

@Specialization
public boolean lessEqual(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean lessEqual(double a, RubyBasicObject b) {
return a <= BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -398,8 +398,8 @@ public boolean equal(double a, double b) {
return a == b;
}

@Specialization
public boolean equal(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean equal(double a, RubyBasicObject b) {
return a == BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -441,17 +441,17 @@ public int compare(double a, long b) {
return Double.compare(a, b);
}

@Specialization(guards = "isInfinity(a)")
public int compareInfinity(double a, RubyBignum b) {
@Specialization(guards = {"isInfinity(a)", "isRubyBignum(b)"})
public int compareInfinity(double a, RubyBasicObject b) {
if (a < 0) {
return -1;
} else {
return +1;
}
}

@Specialization(guards = {"!isNaN(a)", "!isInfinity(a)"})
public int compare(double a, RubyBignum b) {
@Specialization(guards = {"!isNaN(a)", "!isInfinity(a)", "isRubyBignum(b)"})
public int compareBignum(double a, RubyBasicObject b) {
return Double.compare(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

@@ -489,8 +489,8 @@ public boolean greaterEqual(double a, double b) {
return a >= b;
}

@Specialization
public boolean greaterEqual(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean greaterEqual(double a, RubyBasicObject b) {
return a >= BignumNodes.getBigIntegerValue(b).doubleValue();
}

@@ -523,8 +523,8 @@ public boolean equal(double a, double b) {
return a > b;
}

@Specialization
public boolean equal(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public boolean equal(double a, RubyBasicObject b) {
return a > BignumNodes.getBigIntegerValue(b).doubleValue();
}

Original file line number Diff line number Diff line change
@@ -92,8 +92,8 @@ public RubyArray execute(double a, long b) {
return divMod(a, b);
}

public RubyArray execute(double a, RubyBignum b) {
return divMod(a, BignumNodes.getBigIntegerValue(b).doubleValue());
public RubyArray execute(double a, BigInteger b) {
return divMod(a, b.doubleValue());
}

public RubyArray execute(double a, double b) {
@@ -193,8 +193,8 @@ private RubyArray divMod(BigInteger a, BigInteger b) {
fixnumOrBignumRemainder.fixnumOrBignum(bigIntegerResults[1])}, 2);
}

public RubyBignum create(BigInteger value) {
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), value);
public RubyBasicObject create(BigInteger value) {
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), value);
}

@Override
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.runtime.control.NextException;
import org.jruby.truffle.runtime.control.RedoException;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyBignum;
import org.jruby.truffle.runtime.core.RubyProc;

@@ -31,7 +32,6 @@ public abstract class IntegerNodes {
@CoreMethod(names = "downto", needsBlock = true, required = 1, returnsEnumeratorIfNoBlock = true, unsupportedOperationBehavior = UnsupportedOperationBehavior.ARGUMENT_ERROR)
public abstract static class DownToNode extends YieldingCoreMethodNode {

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -128,7 +128,6 @@ public abstract static class TimesNode extends YieldingCoreMethodNode {

@Child private FixnumOrBignumNode fixnumOrBignum;

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -209,8 +208,8 @@ public Object times(VirtualFrame frame, long n, RubyProc block) {
return n;
}

@Specialization
public Object times(VirtualFrame frame, RubyBignum n, RubyProc block) {
@Specialization(guards = "isRubyBignum(n)")
public Object times(VirtualFrame frame, RubyBasicObject n, RubyProc block) {
if (fixnumOrBignum == null) {
CompilerDirectives.transferToInterpreter();
fixnumOrBignum = insert(new FixnumOrBignumNode(getContext(), getSourceSection()));
@@ -252,8 +251,8 @@ public long toI(long n) {
return n;
}

@Specialization
public RubyBignum toI(RubyBignum n) {
@Specialization(guards = "isRubyBignum(n)")
public RubyBasicObject toI(RubyBasicObject n) {
return n;
}

@@ -262,7 +261,6 @@ public RubyBignum toI(RubyBignum n) {
@CoreMethod(names = "upto", needsBlock = true, required = 1, returnsEnumeratorIfNoBlock = true, unsupportedOperationBehavior = UnsupportedOperationBehavior.ARGUMENT_ERROR)
public abstract static class UpToNode extends YieldingCoreMethodNode {

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

205 changes: 130 additions & 75 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java

Large diffs are not rendered by default.

57 changes: 29 additions & 28 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/MathNodes.java
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyBignum;

@CoreClass(name = "Math")
@@ -332,8 +333,8 @@ public RubyArray frexp(long a) {
return frexp((double) a);
}

@Specialization
public RubyArray frexp(RubyBignum a) {
@Specialization(guards = "isRubyBignum(a)")
public RubyArray frexp(RubyBasicObject a) {
return frexp(BignumNodes.getBigIntegerValue(a).doubleValue());
}

@@ -492,18 +493,18 @@ public double function(long a, double b) {
return function((double) a, b);
}

@Specialization
public double function(RubyBignum a, int b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, int b) {
return function(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@Specialization
public double function(RubyBignum a, long b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, long b) {
return function(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@Specialization
public double function(RubyBignum a, double b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, double b) {
return function(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@@ -572,8 +573,8 @@ public RubyArray lgamma(long a) {
return lgamma((double) a);
}

@Specialization
public RubyArray lgamma(RubyBignum a) {
@Specialization(guards = "isRubyBignum(a)")
public RubyArray lgamma(RubyBasicObject a) {
return lgamma(BignumNodes.getBigIntegerValue(a).doubleValue());
}

@@ -627,8 +628,8 @@ public double function(long a, UndefinedPlaceholder b) {
return doFunction(a);
}

@Specialization
public double function(RubyBignum a, UndefinedPlaceholder b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, UndefinedPlaceholder b) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue());
}

@@ -813,8 +814,8 @@ public double function(long a) {
return doFunction(a);
}

@Specialization
public double function(RubyBignum a) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue());
}

@@ -871,8 +872,8 @@ public double function(int a, long b) {
return doFunction(a, b);
}

@Specialization
public double function(int a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double function(int a, RubyBasicObject b) {
return doFunction(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

@@ -891,8 +892,8 @@ public double function(long a, long b) {
return doFunction(a, b);
}

@Specialization
public double function(long a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(long a, RubyBasicObject b) {
return doFunction(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

@@ -901,23 +902,23 @@ public double function(long a, double b) {
return doFunction(a, b);
}

@Specialization
public double function(RubyBignum a, int b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, int b) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@Specialization
public double function(RubyBignum a, long b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, long b) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@Specialization
public double function(RubyBignum a, RubyBignum b) {
@Specialization(guards = {"isRubyBignum(a)", "isRubyBignum(b)"})
public double function(RubyBasicObject a, RubyBasicObject b) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue(), BignumNodes.getBigIntegerValue(b).doubleValue());
}

@Specialization
public double function(RubyBignum a, double b) {
@Specialization(guards = "isRubyBignum(a)")
public double function(RubyBasicObject a, double b) {
return doFunction(BignumNodes.getBigIntegerValue(a).doubleValue(), b);
}

@@ -931,8 +932,8 @@ public double function(double a, long b) {
return doFunction(a, b);
}

@Specialization
public double function(double a, RubyBignum b) {
@Specialization(guards = "isRubyBignum(b)")
public double function(double a, RubyBasicObject b) {
return doFunction(a, BignumNodes.getBigIntegerValue(b).doubleValue());
}

63 changes: 19 additions & 44 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -18,10 +18,13 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.Node.Child;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;

import jnr.posix.Passwd;

import org.jcodings.Encoding;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
@@ -46,6 +49,7 @@
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.core.RubyModule.MethodFilter;
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
@@ -1011,20 +1015,21 @@ private RubySymbol addMethod(RubyModule module, String name, InternalMethod meth
@CoreMethod(names = "extend_object", required = 1, visibility = Visibility.PRIVATE)
public abstract static class ExtendObjectNode extends CoreMethodArrayArgumentsNode {

@Child private SingletonClassNode singletonClassNode;

public ExtendObjectNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.singletonClassNode = SingletonClassNodeGen.create(context, sourceSection, null);
}

@Specialization
public RubyBasicObject extendObject(RubyModule module, RubyBasicObject object) {
CompilerDirectives.transferToInterpreter();

public RubyBasicObject extendObject(VirtualFrame frame, RubyModule module, RubyBasicObject object) {
if (module instanceof RubyClass) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorWrongArgumentType(module, "Module", this));
}

object.getSingletonClass(this).include(this, module);
singletonClassNode.executeSingletonClass(frame, object).include(this, module);
return module;
}

@@ -1396,12 +1401,7 @@ public RubyArray protectedInstanceMethods(RubyModule module, boolean includeAnce


return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(),
module.filterMethods(includeAncestors, new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PROTECTED;
}
}).toArray());
module.filterMethods(includeAncestors, MethodFilter.PROTECTED).toArray());
}
}

@@ -1448,12 +1448,7 @@ public RubyArray privateInstanceMethods(RubyModule module, boolean includeAncest
CompilerDirectives.transferToInterpreter();

return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(),
module.filterMethods(includeAncestors, new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PRIVATE;
}
}).toArray());
module.filterMethods(includeAncestors, MethodFilter.PRIVATE).toArray());
}
}

@@ -1510,12 +1505,7 @@ public RubyArray publicInstanceMethods(RubyModule module, boolean includeAncesto
CompilerDirectives.transferToInterpreter();

return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(),
module.filterMethods(includeAncestors, new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PUBLIC;
}
}).toArray());
module.filterMethods(includeAncestors, MethodFilter.PUBLIC).toArray());
}
}

@@ -1554,32 +1544,15 @@ public InstanceMethodsNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public RubyArray instanceMethods(RubyModule module, UndefinedPlaceholder argument) {
CompilerDirectives.transferToInterpreter();

return instanceMethods(module, true);
}

@Specialization
public RubyArray instanceMethods(RubyModule module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

Map<String, InternalMethod> methods;

if (includeAncestors) {
methods = ModuleOperations.getAllMethods(module);
} else {
methods = module.getMethods();
}

final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
for (InternalMethod method : methods.values()) {
if (method.getVisibility() != Visibility.PRIVATE && !method.isUndefined()) {
// TODO(CS): shoudln't be using this
array.slowPush(getContext().getSymbol(method.getName()));
}
}

return array;
return RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(),
module.filterMethods(includeAncestors, MethodFilter.PUBLIC_PROTECTED).toArray());
}
}

@@ -1833,13 +1806,15 @@ public RubyString userHome(RubyString uname) {
public abstract static class SetVisibilityNode extends CoreMethodNode {

@Child SymbolOrToStrNode symbolOrToStrNode;
@Child private SingletonClassNode singletonClassNode;

private final Visibility visibility;

public SetVisibilityNode(RubyContext context, SourceSection sourceSection, Visibility visibility) {
super(context, sourceSection);
this.visibility = visibility;
this.symbolOrToStrNode = SymbolOrToStrNodeGen.create(context, sourceSection, null);
this.singletonClassNode = SingletonClassNodeGen.create(context, sourceSection, null);
}

public abstract RubyModule executeSetVisibility(VirtualFrame frame, RubyModule module, Object[] arguments);
@@ -1853,14 +1828,14 @@ RubyModule setVisibility(VirtualFrame frame, RubyModule module, Object[] names)
} else {
for (Object name : names) {
final String methodName = symbolOrToStrNode.executeToJavaString(frame, name);
setMethodVisibility(module, methodName);
setMethodVisibility(frame, module, methodName);
}
}

return module;
}

private void setMethodVisibility(RubyModule module, final String methodName) {
private void setMethodVisibility(VirtualFrame frame, RubyModule module, final String methodName) {
final InternalMethod method = module.deepMethodSearch(methodName);

if (method == null) {
@@ -1876,7 +1851,7 @@ private void setMethodVisibility(RubyModule module, final String methodName) {
*/
if (visibility == Visibility.MODULE_FUNCTION) {
module.addMethod(this, method.withVisibility(Visibility.PRIVATE));
module.getSingletonClass(this).addMethod(this, method.withVisibility(Visibility.PUBLIC));
singletonClassNode.executeSingletonClass(frame, module).addMethod(this, method.withVisibility(Visibility.PUBLIC));
} else {
module.addMethod(this, method.withVisibility(visibility));
}
Original file line number Diff line number Diff line change
@@ -56,21 +56,21 @@ public Object id2Ref(long id) {
}
}

@Specialization(guards = "isLargeFixnumID(id)")
public Object id2RefLargeFixnum(RubyBignum id) {
@Specialization(guards = {"isRubyBignum(id)", "isLargeFixnumID(id)"})
public Object id2RefLargeFixnum(RubyBasicObject id) {
return BignumNodes.getBigIntegerValue(id).longValue();
}

@Specialization(guards = "isFloatID(id)")
public double id2RefFloat(RubyBignum id) {
@Specialization(guards = {"isRubyBignum(id)", "isFloatID(id)"})
public double id2RefFloat(RubyBasicObject id) {
return Double.longBitsToDouble(BignumNodes.getBigIntegerValue(id).longValue());
}

protected boolean isLargeFixnumID(RubyBignum id) {
protected boolean isLargeFixnumID(RubyBasicObject id) {
return ObjectIDOperations.isLargeFixnumID(BignumNodes.getBigIntegerValue(id));
}

protected boolean isFloatID(RubyBignum id) {
protected boolean isFloatID(RubyBasicObject id) {
return ObjectIDOperations.isFloatID(BignumNodes.getBigIntegerValue(id));
}

Original file line number Diff line number Diff line change
@@ -70,7 +70,6 @@ public RubyArray collect(VirtualFrame frame, RubyRange.IntegerFixnumRange range,
@CoreMethod(names = "each", needsBlock = true, lowerFixnumSelf = true, returnsEnumeratorIfNoBlock = true)
public abstract static class EachNode extends YieldingCoreMethodNode {

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -248,7 +247,6 @@ public Object last(RubyRange.ObjectRange range) {
@CoreMethod(names = "step", needsBlock = true, optional = 1, returnsEnumeratorIfNoBlock = true)
public abstract static class StepNode extends YieldingCoreMethodNode {

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

37 changes: 18 additions & 19 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Original file line number Diff line number Diff line change
@@ -137,8 +137,8 @@ public RubyString multiply(RubyString string, int times) {
return ret;
}

@Specialization
public RubyString multiply(RubyString string, RubyBignum times) {
@Specialization(guards = "isRubyBignum(times)")
public RubyString multiply(RubyString string, RubyBasicObject times) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
@@ -309,8 +309,8 @@ public RubyString concat(RubyString string, long other) {
return concatNumeric(string, (int) other);
}

@Specialization
public RubyString concat(RubyString string, RubyBignum other) {
@Specialization(guards = "isRubyBignum(other)")
public RubyString concat(RubyString string, RubyBasicObject other) {
if (BignumNodes.getBigIntegerValue(other).signum() < 0) {
CompilerDirectives.transferToInterpreter();

@@ -695,7 +695,6 @@ public ChopBangNode(RubyContext context, SourceSection sourceSection) {
sizeNode = StringNodesFactory.SizeNodeFactory.create(context, sourceSection, new RubyNode[] { null });
}

@TruffleBoundary
@Specialization
public Object chopBang(VirtualFrame frame, RubyString string) {
if (sizeNode.executeInteger(frame, string) == 0) {
@@ -730,27 +729,27 @@ public CountNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int count(VirtualFrame frame, RubyString string, Object[] otherStrings) {
public int count(VirtualFrame frame, RubyString string, Object[] args) {
if (string.getByteList().getRealSize() == 0) {
return 0;
}

if (otherStrings.length == 0) {
if (args.length == 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentErrorEmptyVarargs(this));
}

return countSlow(frame, string, otherStrings);
}

@TruffleBoundary
private int countSlow(VirtualFrame frame, RubyString string, Object[] args) {
RubyString[] otherStrings = new RubyString[args.length];

for (int i = 0; i < args.length; i++) {
otherStrings[i] = toStr.executeRubyString(frame, args[i]);
}

return countSlow(string, otherStrings);
}

@TruffleBoundary
private int countSlow(RubyString string, RubyString[] otherStrings) {
RubyString otherStr = otherStrings[0];
Encoding enc = otherStr.getByteList().getEncoding();

@@ -851,27 +850,27 @@ public DeleteBangNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object deleteBang(VirtualFrame frame, RubyString string, Object... otherStrings) {
public Object deleteBang(VirtualFrame frame, RubyString string, Object... args) {
if (string.getByteList().length() == 0) {
return nil();
}

if (otherStrings.length == 0) {
if (args.length == 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentErrorEmptyVarargs(this));
}

return deleteBangSlow(frame, string, otherStrings);
}

@TruffleBoundary
private Object deleteBangSlow(VirtualFrame frame, RubyString string, Object... args) {
RubyString[] otherStrings = new RubyString[args.length];

for (int i = 0; i < args.length; i++) {
otherStrings[i] = toStr.executeRubyString(frame, args[i]);
}

return deleteBangSlow(string, otherStrings);
}

@TruffleBoundary
private Object deleteBangSlow(RubyString string, RubyString... otherStrings) {
RubyString otherString = otherStrings[0];
Encoding enc = string.checkEncoding(otherString, this);

Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public class ThreadBacktraceLocationNodes {

static {
Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
ACTIVATION_PROPERTY = Property.create(ACTIVATION_IDENTIFIER, allocator.locationForType(ReentrantLock.class, EnumSet.of(LocationModifier.NonNull)), 0);
ACTIVATION_PROPERTY = Property.create(ACTIVATION_IDENTIFIER, allocator.locationForType(Activation.class, EnumSet.of(LocationModifier.NonNull)), 0);
}

public static Allocator createThreadBacktraceLocationAllocator(Shape emptyShape) {
Original file line number Diff line number Diff line change
@@ -77,16 +77,16 @@ public void run(RubyThread currentThread, Node currentNode) {

}

@CoreMethod(names = "initialize", needsBlock = true)
@CoreMethod(names = "initialize", argumentsAsArray = true, needsBlock = true)
public abstract static class InitializeNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public RubyBasicObject initialize(RubyThread thread, RubyProc block) {
thread.initialize(getContext(), this, block);
public RubyBasicObject initialize(RubyThread thread, Object[] arguments, RubyProc block) {
thread.initialize(getContext(), this, arguments, block);
return nil();
}

18 changes: 18 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/TimeNodes.java
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;

import org.joda.time.DateTimeZone;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
@@ -21,6 +22,23 @@
@CoreClass(name = "Time")
public abstract class TimeNodes {

// We need it to copy the internal data for a call to Kernel#clone.
@CoreMethod(names = "initialize_copy", required = 1)
public abstract static class InitializeCopyNode extends CoreMethodArrayArgumentsNode {

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

@Specialization
public Object initializeCopy(RubyTime self, RubyTime from) {
self.setDateTime(from.getDateTime());
self.setOffset(from.getOffset());
return self;
}

}

// Not a core method, used to simulate Rubinius @is_gmt.
@NodeChild(type = RubyNode.class, value = "self")
public abstract static class InternalGMTNode extends CoreMethodNode {
Original file line number Diff line number Diff line change
@@ -1243,7 +1243,6 @@ public abstract static class EachNode extends YieldingCoreMethodNode {

@Child private CallDispatchHeadNode toEnumNode;

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -1411,7 +1410,6 @@ public Object eachObject(VirtualFrame frame, RubyArray array, RubyProc block) {
@ImportStatic(ArrayGuards.class)
public abstract static class EachWithIndexNode extends YieldingCoreMethodNode {

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -2158,7 +2156,6 @@ public abstract static class MapNode extends YieldingCoreMethodNode {

@Child private ArrayBuilderNode arrayBuilder;

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

@@ -2319,7 +2316,6 @@ public abstract static class MapInPlaceNode extends YieldingCoreMethodNode {

@Child private ArrayWriteDenormalizedNode writeNode;

private final BranchProfile breakProfile = BranchProfile.create();
private final BranchProfile nextProfile = BranchProfile.create();
private final BranchProfile redoProfile = BranchProfile.create();

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

import java.math.BigInteger;
@@ -581,7 +580,7 @@ public Object mod(long a, RubyBasicObject b) {

if (mod < 0 && BignumNodes.getBigIntegerValue(b).compareTo(BigInteger.ZERO) > 0 || mod > 0 && BignumNodes.getBigIntegerValue(b).compareTo(BigInteger.ZERO) < 0) {
adjustProfile.enter();
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), BigInteger.valueOf(mod).add(BignumNodes.getBigIntegerValue(b)));
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), BigInteger.valueOf(mod).add(BignumNodes.getBigIntegerValue(b)));
}

return mod;
@@ -1341,7 +1340,7 @@ public long absInBounds(long n) {
@Specialization(contains = "absInBounds")
public Object abs(long n) {
if (n == Long.MIN_VALUE) {
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), BigInteger.valueOf(n).abs());
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), BigInteger.valueOf(n).abs());
}
return (n < 0) ? -n : n;
}
@@ -1351,7 +1350,7 @@ public Object abs(long n) {
@CoreMethod(names = "bit_length")
public abstract static class BitLengthNode extends CoreMethodArrayArgumentsNode {

private static final int INTEGER_BITS = Integer.numberOfLeadingZeros(0);
private static final int INT_BITS = Integer.numberOfLeadingZeros(0);
private static final int LONG_BITS = Long.numberOfLeadingZeros(0);

public BitLengthNode(RubyContext context, SourceSection sourceSection) {
@@ -1360,7 +1359,11 @@ public BitLengthNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public int bitLength(int n) {
return bitLength((long) n);
if (n < 0) {
n = ~n;
}

return INT_BITS - Integer.numberOfLeadingZeros(n);
}

@Specialization
@@ -1369,10 +1372,6 @@ public int bitLength(long n) {
n = ~n;
}

if (n == Long.MAX_VALUE) {
return LONG_BITS - 1;
}

return LONG_BITS - Long.numberOfLeadingZeros(n);
}

Original file line number Diff line number Diff line change
@@ -10,10 +10,7 @@
package org.jruby.truffle.nodes.core.hash;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.source.SourceSection;
@@ -129,7 +126,7 @@ public abstract static class GetIndexNode extends CoreMethodArrayArgumentsNode {
@Child private CallDispatchHeadNode eqlNode;
@Child private BasicObjectNodes.ReferenceEqualNode equalNode;
@Child private CallDispatchHeadNode callDefaultNode;
@Child private FindEntryNode findEntryNode;
@Child private LookupEntryNode lookupEntryNode;

private final ConditionProfile byIdentityProfile = ConditionProfile.createBinaryProfile();
private final BranchProfile notInHashProfile = BranchProfile.create();
@@ -143,7 +140,7 @@ public GetIndexNode(RubyContext context, SourceSection sourceSection) {
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
callDefaultNode = DispatchHeadNodeFactory.createMethodCall(context);
findEntryNode = new FindEntryNode(context, sourceSection);
lookupEntryNode = new LookupEntryNode(context, sourceSection);
}

public abstract Object executeGet(VirtualFrame frame, RubyHash hash, Object key);
@@ -198,10 +195,10 @@ public Object getPackedArray(VirtualFrame frame, RubyHash hash, Object key) {

@Specialization(guards = "isBucketsStorage(hash)")
public Object getBuckets(VirtualFrame frame, RubyHash hash, Object key) {
final HashSearchResult hashSearchResult = findEntryNode.search(frame, hash, key);
final HashLookupResult hashLookupResult = lookupEntryNode.lookup(frame, hash, key);

if (hashSearchResult.getEntry() != null) {
return hashSearchResult.getEntry().getValue();
if (hashLookupResult.getEntry() != null) {
return hashLookupResult.getEntry().getValue();
}

notInHashProfile.enter();
@@ -245,6 +242,7 @@ public abstract static class SetIndexNode extends CoreMethodArrayArgumentsNode {
@Child private HashNode hashNode;
@Child private CallDispatchHeadNode eqlNode;
@Child private BasicObjectNodes.ReferenceEqualNode equalNode;
@Child private LookupEntryNode lookupEntryNode;

private final ConditionProfile byIdentityProfile = ConditionProfile.createBinaryProfile();

@@ -329,13 +327,59 @@ public Object setPackedArray(VirtualFrame frame, RubyHash hash, RubyString key,
}
}

@Specialization(guards = {"isBucketsStorage(hash)", "!isRubyString(key)"})
public Object setBuckets(RubyHash hash, Object key, Object value) {
CompilerDirectives.transferToInterpreter();
// Can't be @Cached yet as we call from the RubyString specialisation
private final ConditionProfile foundProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile bucketCollisionProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile appendingProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile resizeProfile = ConditionProfile.createBinaryProfile();

@Specialization(guards = {"isBucketsStorage(hash)", "!isRubyString(key)"})
public Object setBuckets(VirtualFrame frame, RubyHash hash, Object key, Object value) {
assert HashOperations.verifyStore(hash);

HashOperations.verySlowSetInBuckets(hash, key, value, hash.isCompareByIdentity());
if (lookupEntryNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
lookupEntryNode = insert(new LookupEntryNode(getContext(), getEncapsulatingSourceSection()));
}

final HashLookupResult result = lookupEntryNode.lookup(frame, hash, key);

final Entry entry = result.getEntry();

if (foundProfile.profile(entry == null)) {
final Entry[] entries = (Entry[]) hash.getStore();

final Entry newEntry = new Entry(result.getHashed(), key, value);

if (bucketCollisionProfile.profile(result.getPreviousEntry() == null)) {
entries[result.getIndex()] = newEntry;
} else {
result.getPreviousEntry().setNextInLookup(newEntry);
}

final Entry lastInSequence = hash.getLastInSequence();

if (appendingProfile.profile(lastInSequence == null)) {
hash.setFirstInSequence(newEntry);
} else {
lastInSequence.setNextInSequence(newEntry);
newEntry.setPreviousInSequence(lastInSequence);
}

hash.setLastInSequence(newEntry);

final int newSize = hash.getSize() + 1;

hash.setSize(newSize);

// TODO CS 11-May-15 could store the next size for resize instead of doing a float operation each time

if (resizeProfile.profile(newSize / (double) entries.length > BucketsStrategy.MAX_LOAD_BALANCE)) {
BucketsStrategy.resize(hash);
}
} else {
entry.setKeyValue(result.getHashed(), key, value);
}

assert HashOperations.verifyStore(hash);

@@ -345,9 +389,9 @@ public Object setBuckets(RubyHash hash, Object key, Object value) {
@Specialization(guards = "isBucketsStorage(hash)")
public Object setBuckets(VirtualFrame frame, RubyHash hash, RubyString key, Object value) {
if (hash.isCompareByIdentity()) {
return setBuckets(hash, key, value);
return setBuckets(frame, hash, key, value);
} else {
return setBuckets(hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value);
return setBuckets(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value);
}
}

@@ -431,14 +475,14 @@ public abstract static class DeleteNode extends CoreMethodArrayArgumentsNode {

@Child private HashNode hashNode;
@Child private CallDispatchHeadNode eqlNode;
@Child private FindEntryNode findEntryNode;
@Child private LookupEntryNode lookupEntryNode;
@Child private YieldDispatchHeadNode yieldNode;

public DeleteNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = new HashNode(context, sourceSection);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
findEntryNode = new FindEntryNode(context, sourceSection);
lookupEntryNode = new LookupEntryNode(context, sourceSection);
yieldNode = new YieldDispatchHeadNode(context);
}

@@ -489,17 +533,17 @@ public Object deletePackedArray(VirtualFrame frame, RubyHash hash, Object key, O
public Object delete(VirtualFrame frame, RubyHash hash, Object key, Object block) {
assert HashOperations.verifyStore(hash);

final HashSearchResult hashSearchResult = findEntryNode.search(frame, hash, key);
final HashLookupResult hashLookupResult = lookupEntryNode.lookup(frame, hash, key);

if (hashSearchResult.getEntry() == null) {
if (hashLookupResult.getEntry() == null) {
if (block == UndefinedPlaceholder.INSTANCE) {
return nil();
} else {
return yieldNode.dispatch(frame, (RubyProc) block, key);
}
}

final Entry entry = hashSearchResult.getEntry();
final Entry entry = hashLookupResult.getEntry();

// Remove from the sequence chain

@@ -519,10 +563,10 @@ public Object delete(VirtualFrame frame, RubyHash hash, Object key, Object block

// Remove from the lookup chain

if (hashSearchResult.getPreviousEntry() == null) {
((Entry[]) hash.getStore())[hashSearchResult.getIndex()] = entry.getNextInLookup();
if (hashLookupResult.getPreviousEntry() == null) {
((Entry[]) hash.getStore())[hashLookupResult.getIndex()] = entry.getNextInLookup();
} else {
hashSearchResult.getPreviousEntry().setNextInLookup(entry.getNextInLookup());
hashLookupResult.getPreviousEntry().setNextInLookup(entry.getNextInLookup());
}

hash.setSize(hash.getSize() - 1);
@@ -952,7 +996,7 @@ public RubyHash merge(VirtualFrame frame, RubyHash hash, RubyHash other, RubyPro
}

for (KeyValue keyValue : HashOperations.verySlowToKeyValues(other)) {
final HashSearchResult searchResult = HashOperations.verySlowFindBucket(merged, keyValue.getKey(), false);
final HashLookupResult searchResult = HashOperations.verySlowFindBucket(merged, keyValue.getKey(), false);

if (searchResult.getEntry() == null) {
HashOperations.verySlowSetInBuckets(merged, keyValue.getKey(), keyValue.getValue(), false);
Original file line number Diff line number Diff line change
@@ -21,24 +21,24 @@
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.hash.BucketsStrategy;
import org.jruby.truffle.runtime.hash.Entry;
import org.jruby.truffle.runtime.hash.HashSearchResult;
import org.jruby.truffle.runtime.hash.HashLookupResult;

public class FindEntryNode extends RubyNode {
public class LookupEntryNode extends RubyNode {

@Child HashNode hashNode;
@Child CallDispatchHeadNode eqlNode;
@Child BasicObjectNodes.ReferenceEqualNode equalNode;

private final ConditionProfile byIdentityProfile = ConditionProfile.createBinaryProfile();

public FindEntryNode(RubyContext context, SourceSection sourceSection) {
public LookupEntryNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
hashNode = new HashNode(context, sourceSection);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
}

public HashSearchResult search(VirtualFrame frame, RubyHash hash, Object key) {
public HashLookupResult lookup(VirtualFrame frame, RubyHash hash, Object key) {
final int hashed = hashNode.hash(frame, key);

final Entry[] entries = (Entry[]) hash.getStore();
@@ -50,19 +50,19 @@ public HashSearchResult search(VirtualFrame frame, RubyHash hash, Object key) {
while (entry != null) {
if (byIdentityProfile.profile(hash.isCompareByIdentity())) {
if (equalNode.executeReferenceEqual(frame, key, entry.getKey())) {
return new HashSearchResult(hashed, index, previousEntry, entry);
return new HashLookupResult(hashed, index, previousEntry, entry);
}
} else {
if (eqlNode.callBoolean(frame, key, "eql?", null, entry.getKey())) {
return new HashSearchResult(hashed, index, previousEntry, entry);
return new HashLookupResult(hashed, index, previousEntry, entry);
}
}

previousEntry = entry;
entry = entry.getNextInLookup();
}

return new HashSearchResult(hashed, index, previousEntry, null);
return new HashLookupResult(hashed, index, previousEntry, null);
}

@Override
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -25,6 +26,7 @@ public AssertConstantNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@SuppressWarnings("unused")
private static volatile boolean[] sideEffect;

@Specialization
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -23,6 +24,7 @@ public AssertNotCompiledNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@SuppressWarnings("unused")
private static volatile boolean[] sideEffect;

@Specialization
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiv
super(context, section);
this.receiver = receiver;
this.methodNode = method;
singletonClassNode = SingletonClassNodeGen.create(context, section, null);
this.singletonClassNode = SingletonClassNodeGen.create(context, section, null);
}

@Override
@@ -59,7 +59,7 @@ public RubySymbol execute(VirtualFrame frame) {

if (method.getVisibility() == Visibility.MODULE_FUNCTION) {
module.addMethod(this, method.withVisibility(Visibility.PRIVATE));
module.getSingletonClass(this).addMethod(this, method.withVisibility(Visibility.PUBLIC));
singletonClassNode.executeSingletonClass(frame, module).addMethod(this, method.withVisibility(Visibility.PUBLIC));
} else {
module.addMethod(this, method);
}
Original file line number Diff line number Diff line change
@@ -12,23 +12,30 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
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.objects.SingletonClassNode;
import org.jruby.truffle.nodes.objects.SingletonClassNodeGen;
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.RubyBignum;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyModule;

@NodeChild(value="module", type=RubyNode.class)
public abstract class AliasNode extends RubyNode {

@Child private RubyNode module;
@Child private SingletonClassNode singletonClassNode;

final String newName;
final String oldName;

public AliasNode(RubyContext context, SourceSection sourceSection, String newName, String oldName) {
super(context, sourceSection);
this.singletonClassNode = SingletonClassNodeGen.create(context, sourceSection, null);
this.newName = newName;
this.oldName = oldName;
}
@@ -38,45 +45,17 @@ public Object noClass() {
throw new RaiseException(getContext().getCoreLibrary().typeErrorNoClassToMakeAlias(this));
}

@Specialization
public Object alias(boolean value) {
return noClass();
}

@Specialization
public Object alias(int value) {
return noClass();
}

@Specialization
public Object alias(long value) {
return noClass();
}

@Specialization
public Object alias(double value) {
return noClass();
}

@Specialization(guards = "isRubyBignum(value)")
public Object aliasBignum(RubyBasicObject value) {
return noClass();
}

@Specialization
public Object alias(RubyModule module) {
CompilerDirectives.transferToInterpreter();

module.alias(this, newName, oldName);
return null;
return module;
}

@Specialization(guards = {"!isRubyModule(object)", "!isRubyBignum(object)"})
public Object alias(RubyBasicObject object) {
CompilerDirectives.transferToInterpreter();

object.getSingletonClass(this).alias(this, newName, oldName);
return null;
// TODO (eregon, 10 May 2015): we should only have the module case as the child should be the default definee
@Specialization(guards = "!isRubyModule(object)")
public Object alias(VirtualFrame frame, Object object) {
singletonClassNode.executeSingletonClass(frame, object).alias(this, newName, oldName);
return object;
}

}
Original file line number Diff line number Diff line change
@@ -14,10 +14,12 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
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.RubyBignum;
import org.jruby.truffle.runtime.core.RubyClass;

/**
@@ -60,7 +62,13 @@ protected RubyClass singletonClass(double value) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantDefineSingleton(this));
}

@Specialization
@Specialization(guards = "isRubyBignum(value)")
protected RubyClass singletonClassBignum(RubyBasicObject value) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantDefineSingleton(this));
}

@Specialization(guards = "!isRubyBignum(object)")
protected RubyClass singletonClass(RubyBasicObject object) {
return object.getSingletonClass(this);
}
Original file line number Diff line number Diff line change
@@ -33,17 +33,17 @@ public BignumPowPrimitiveNode(RubyContext context, SourceSection sourceSection)
}

@Specialization
public RubyBignum pow(RubyBasicObject a, int b) {
public RubyBasicObject pow(RubyBasicObject a, int b) {
return pow(a, (long) b);
}

@Specialization
public RubyBignum pow(RubyBasicObject a, long b) {
public RubyBasicObject pow(RubyBasicObject a, long b) {
if (negativeProfile.profile(b < 0)) {
return null; // Primitive failure
} else {
// TODO CS 15-Feb-15 what about this cast?
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), BignumNodes.getBigIntegerValue(a).pow((int) b));
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), BignumNodes.getBigIntegerValue(a).pow((int) b));
}
}

Original file line number Diff line number Diff line change
@@ -13,15 +13,19 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import jnr.constants.platform.Fcntl;

import org.jruby.RubyEncoding;
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.RubyString;
import org.jruby.util.ByteList;
import org.jruby.util.Dir;

import java.nio.ByteBuffer;
import java.util.Arrays;

public abstract class IOPrimitiveNodes {
@@ -204,23 +208,28 @@ public int write(VirtualFrame frame, RubyBasicObject file, RubyString string) {

// We have to copy here as write starts at byte[0], and the ByteList may not

byte[] bytes = string.getByteList().bytes();
final ByteList byteList = string.getByteList();

// TODO (eregon, 11 May 2015): review consistency under concurrent modification
final ByteBuffer buffer = ByteBuffer.wrap(byteList.unsafeBytes(), byteList.begin(), byteList.length());

int total = 0;

while (bytes.length > 0) {
while (buffer.hasRemaining()) {
getContext().getSafepointManager().poll(this);

int written = posix().write(fd, bytes, bytes.length);
int written = posix().write(fd, buffer, buffer.remaining());

if (written == -1) {
throw new UnsupportedOperationException();
}

// Have to copy here again for the same reason!
buffer.position(buffer.position() + written);

bytes = Arrays.copyOfRange(bytes, written, bytes.length);
total += written;
}

return bytes.length;
return total;
}

}
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import org.jruby.RubyNumeric;
import org.jruby.RubyRandom;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.nodes.core.BignumNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyBignum;
@@ -84,9 +85,9 @@ public RandomizerGenSeedPrimitiveNode(RubyContext context, SourceSection sourceS

@CompilerDirectives.TruffleBoundary
@Specialization
public RubyBignum randomizerGenSeed(RubyBasicObject random) {
public RubyBasicObject randomizerGenSeed(RubyBasicObject random) {
BigInteger integer = RandomPrimitiveHelper.randomSeed(getContext().getRuntime().getCurrentContext().getRuntime());
return new RubyBignum(getContext().getCoreLibrary().getBignumClass(), integer);
return BignumNodes.createRubyBignum(getContext().getCoreLibrary().getBignumClass(), integer);
}
}

Original file line number Diff line number Diff line change
@@ -21,16 +21,20 @@
public class GeneralSuperReCallNode extends AbstractGeneralSuperCallNode {

private final boolean inBlock;
@Child private RubyNode reload;
@Child private RubyNode block;

public GeneralSuperReCallNode(RubyContext context, SourceSection sourceSection, boolean inBlock, RubyNode block) {
public GeneralSuperReCallNode(RubyContext context, SourceSection sourceSection, boolean inBlock, RubyNode reload, RubyNode block) {
super(context, sourceSection);
this.inBlock = inBlock;
this.reload = reload;
this.block = block;
}

@Override
public final Object execute(VirtualFrame frame) {
reload.execute(frame);

final Object self = RubyArguments.getSelf(frame.getArguments());

if (!guard(frame, self)) {
Original file line number Diff line number Diff line change
@@ -43,7 +43,6 @@ public Object write(VirtualFrame frame, ByteList bytes) {
int begin = bytes.begin();

int currentByte = 0;
int padLength = 0;

final int lengthToUse;

Original file line number Diff line number Diff line change
@@ -14,15 +14,21 @@
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.object.Location;
import com.oracle.truffle.api.object.Property;
import com.oracle.truffle.api.object.Shape;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.literal.ObjectLiteralNode;
import org.jruby.truffle.nodes.objects.FreezeNode;
import org.jruby.truffle.nodes.objects.FreezeNodeGen;
import org.jruby.truffle.nodes.objects.IsFrozenNode;
import org.jruby.truffle.nodes.objects.IsFrozenNodeGen;
import org.jruby.truffle.nodes.objects.IsTaintedNodeGen;
import org.jruby.truffle.runtime.backtrace.Backtrace;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyProc;
@@ -132,39 +138,20 @@ private static void printMethodASTBacktrace(Node currentNode) {
printASTForBacktrace(currentNode.getRootNode(), activeNodes, 0);
}

public static Object verySlowFreeze(RubyContext context, final Object object) {
final FreezeNode freezeNode = FreezeNodeGen.create(context, null, null);
private static Object executeInNewNode(final RubyNode node) {
new Node() {
@Child FreezeNode child = freezeNode;
@Child RubyNode child = node;
}.adoptChildren();
return freezeNode.executeFreeze(object);
}

public static boolean verySlowIsFrozen(RubyContext context, Object object) {
final IsFrozenNode isFrozenNode = IsFrozenNodeGen.create(context, null, null);
new Node() {
@Child IsFrozenNode child = isFrozenNode;
}.adoptChildren();
return isFrozenNode.executeIsFrozen(object);
return node.execute(null);
}

public static boolean verySlowIsTainted(Object o) {
if ((o instanceof Boolean) ||
(o instanceof Integer) ||
(o instanceof Long) ||
(o instanceof Double) ||
(o instanceof RubySymbol)) {
return false;
}

final RubyBasicObject object = (RubyBasicObject) o;

final Shape layout = object.getDynamicObject().getShape();
final Property property = layout.getProperty(RubyBasicObject.TAINTED_IDENTIFIER);

final Location storageLocation = property.getLocation();
public static Object verySlowFreeze(RubyContext context, Object object) {
return executeInNewNode(FreezeNodeGen.create(context, null, new ObjectLiteralNode(context, null, object)));
}

return (boolean) storageLocation.get(object.getDynamicObject(), layout);
public static boolean verySlowIsFrozen(RubyContext context, Object object) {
return (boolean) executeInNewNode(IsFrozenNodeGen.create(context, null, new ObjectLiteralNode(context, null, object)));
}

private static void printASTForBacktrace(Node node, List<Node> activeNodes, int indentation) {
Original file line number Diff line number Diff line change
@@ -192,6 +192,46 @@ public static Map<String, InternalMethod> getAllMethods(RubyModule module) {
return methods;
}

@TruffleBoundary
public static Map<String, InternalMethod> getMethodsBeforeLogicalClass(RubyModule module) {
final Map<String, InternalMethod> methods = new HashMap<>();

for (RubyModule ancestor : module.ancestors()) {
// When we find a class which is not a singleton class, we are done
if (ancestor instanceof RubyClass && !((RubyClass) ancestor).isSingleton()) {
break;
}

for (InternalMethod method : ancestor.getMethods().values()) {
if (!methods.containsKey(method.getName())) {
methods.put(method.getName(), method);
}
}
}

return methods;
}

@TruffleBoundary
public static Map<String, InternalMethod> getMethodsUntilLogicalClass(RubyModule module) {
final Map<String, InternalMethod> methods = new HashMap<>();

for (RubyModule ancestor : module.ancestors()) {
for (InternalMethod method : ancestor.getMethods().values()) {
if (!methods.containsKey(method.getName())) {
methods.put(method.getName(), method);
}
}

// When we find a class which is not a singleton class, we are done
if (ancestor instanceof RubyClass && !((RubyClass) ancestor).isSingleton()) {
break;
}
}

return methods;
}

@TruffleBoundary
public static Map<String, InternalMethod> withoutUndefinedMethods(Map<String, InternalMethod> methods) {
Map<String, InternalMethod> definedMethods = new HashMap<>();
Original file line number Diff line number Diff line change
@@ -90,6 +90,10 @@ public static Object getUserArgument(Object[] internalArguments, int index) {
return internalArguments[RUNTIME_ARGUMENT_COUNT + index];
}

public static void setUserArgument(Object[] internalArguments, int index, Object value) {
internalArguments[RUNTIME_ARGUMENT_COUNT + index] = value;
}

public static RubyHash getUserKeywordsHash(Object[] internalArguments, int minArgumentCount) {
final int argumentCount = getUserArgumentsCount(internalArguments);

@@ -138,5 +142,4 @@ private static MaterializedFrame getDeclarationFrame(MaterializedFrame frame, in

return parentFrame;
}

}
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.control.SequenceNode;
import org.jruby.truffle.nodes.core.BignumNodes;
import org.jruby.truffle.nodes.core.SetTopLevelBindingNode;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.exceptions.TopLevelRaiseHandler;
@@ -127,7 +128,7 @@ public RubyContext(Ruby runtime) {
this.runtime = runtime;

// JRuby+Truffle uses POSIX for all IO - we need the native version
posix = POSIXFactory.getPOSIX(new TrufflePOSIXHandler(this), true);
posix = POSIXFactory.getNativePOSIX(new TrufflePOSIXHandler(this));

warnings = new Warnings(this);

@@ -496,7 +497,7 @@ public Object toTruffle(IRubyObject object) {
} else if (object instanceof org.jruby.RubyBignum) {
final BigInteger value = ((org.jruby.RubyBignum) object).getBigIntegerValue();

return new RubyBignum(coreLibrary.getBignumClass(), value);
return BignumNodes.createRubyBignum(coreLibrary.getBignumClass(), value);
} else if (object instanceof org.jruby.RubyString) {
return toTruffle((org.jruby.RubyString) object);
} else if (object instanceof org.jruby.RubySymbol) {
Original file line number Diff line number Diff line change
@@ -252,7 +252,7 @@ public CoreLibrary(RubyContext context) {
floatClass = defineClass(numericClass, "Float");
integerClass = defineClass(numericClass, "Integer");
fixnumClass = defineClass(integerClass, "Fixnum");
bignumClass = defineClass(integerClass, "Bignum", new RubyBignum.BignumAllocator());
bignumClass = defineClass(integerClass, "Bignum", BignumNodes.createBigumAllocator(context.getEmptyShape()));
rationalClass = defineClass(numericClass, "Rational");

// Classes defined in Object
Original file line number Diff line number Diff line change
@@ -9,33 +9,12 @@
*/
package org.jruby.truffle.runtime.core;

import com.oracle.truffle.api.nodes.Node;
import org.jruby.truffle.nodes.core.BignumNodes;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;

import java.math.BigInteger;
import com.oracle.truffle.api.object.DynamicObject;

public class RubyBignum extends RubyBasicObject {

private final BigInteger value;

public RubyBignum(RubyClass rubyClass, BigInteger value) {
super(rubyClass);
this.value = value;
}

public BigInteger internalGetBigIntegerValue() {
return value;
}

public static class BignumAllocator implements Allocator {

@Override
public RubyBasicObject allocate(RubyContext context, RubyClass rubyClass, Node currentNode) {
return new RubyBignum(rubyClass, BigInteger.ZERO);
}

public RubyBignum(RubyClass rubyClass, DynamicObject dynamicObject) {
super(rubyClass, dynamicObject);
}

}
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.utilities.CyclicAssumption;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -521,6 +523,35 @@ public Iterator<RubyModule> iterator() {

public static interface MethodFilter {

public static final MethodFilter PUBLIC = new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PUBLIC;
}
};

public static final MethodFilter PUBLIC_PROTECTED = new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PUBLIC ||
method.getVisibility() == Visibility.PROTECTED;
}
};

public static final MethodFilter PROTECTED = new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PROTECTED;
}
};

public static final MethodFilter PRIVATE = new RubyModule.MethodFilter() {
@Override
public boolean filter(InternalMethod method) {
return method.getVisibility() == Visibility.PRIVATE;
}
};

boolean filter(InternalMethod method);

}
@@ -532,6 +563,30 @@ public Collection<RubySymbol> filterMethods(boolean includeAncestors, MethodFilt
} else {
allMethods = getMethods();
}
return filterMethods(allMethods, filter);
}

public Collection<RubySymbol> filterMethodsOnObject(boolean includeAncestors, MethodFilter filter) {
final Map<String, InternalMethod> allMethods;
if (includeAncestors) {
allMethods = ModuleOperations.getAllMethods(this);
} else {
allMethods = ModuleOperations.getMethodsUntilLogicalClass(this);
}
return filterMethods(allMethods, filter);
}

public Collection<RubySymbol> filterSingletonMethods(boolean includeAncestors, MethodFilter filter) {
final Map<String, InternalMethod> allMethods;
if (includeAncestors) {
allMethods = ModuleOperations.getMethodsBeforeLogicalClass(this);
} else {
allMethods = getMethods();
}
return filterMethods(allMethods, filter);
}

private Collection<RubySymbol> filterMethods(Map<String, InternalMethod> allMethods, MethodFilter filter) {
final Map<String, InternalMethod> methods = ModuleOperations.withoutUndefinedMethods(allMethods);

final Set<RubySymbol> filtered = new HashSet<>();
Loading

0 comments on commit c0d2d92

Please sign in to comment.