Skip to content

Commit

Permalink
Showing 6,528 changed files with 117,827 additions and 78,904 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -52,8 +52,13 @@ lib/native
lib/ruby/cext/
lib/ruby/gems
lib/ruby/stdlib/*.jar
lib/ruby/stdlib/ant*
lib/ruby/stdlib/cmath.rb
lib/ruby/stdlib/csv.rb
lib/ruby/stdlib/did_you_mean*
lib/ruby/stdlib/fileutils.rb
lib/ruby/stdlib/gauntlet_rdoc.rb
lib/ruby/stdlib/ipaddr*
lib/ruby/stdlib/jar*
lib/ruby/stdlib/jline
lib/ruby/stdlib/jopenssl*
@@ -73,6 +78,8 @@ lib/ruby/stdlib/readline*
lib/ruby/stdlib/minitest*
lib/ruby/stdlib/power_assert*
lib/ruby/stdlib/psych*
lib/ruby/stdlib/scanf.rb
lib/ruby/stdlib/webrick*
lib/ruby/stdlib/**/maven-metadata-local.xml
release.properties
share
@@ -81,7 +88,7 @@ target
test/pom.xml
test/prawn
test/rails
test/testapp/testapp
test/jruby/testapp/testapp
tool/nailgun/Makefile
tool/nailgun/config.log
tool/nailgun/config.status
2 changes: 1 addition & 1 deletion .mvn/extensions.xml
Original file line number Diff line number Diff line change
@@ -3,6 +3,6 @@
<extension>
<groupId>io.takari.polyglot</groupId>
<artifactId>polyglot-ruby</artifactId>
<version>0.1.15</version>
<version>0.3.0</version>
</extension>
</extensions>
63 changes: 42 additions & 21 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -2,45 +2,47 @@ language: java

sudo: false

dist: trusty

cache:
directories:
- $HOME/.m2

before_install:
- unset _JAVA_OPTIONS
- rm ~/.m2/settings.xml
- export MAVEN_SKIP_RC=true
- mvn -Xmx32M -v | grep 1.7.0; if [ $? = 0 ]; then export MAVEN_OPTS="-XX:MaxPermSize=180M"; else export MAVEN_OPTS="-XX:MaxMetaspaceSize=180M -XX:CompressedClassSpaceSize=180M"; fi
- export MAVEN_OPTS="-Xmx500M $MAVEN_OPTS"
- export MAVEN_OPTS="-Xmn64M -Xmx512M -XX:CompressedClassSpaceSize=96M"
- export JAVA_OPTS="$JAVA_OPTS -XX:CompressedClassSpaceSize=96M"

before_script:
- unset GEM_PATH GEM_HOME IRBRC JRUBY_OPTS
- unset _JAVA_OPTIONS # travis/travis#8408
- export PATH="`pwd`/bin:$PATH"
- echo $HOME
- echo $JAVA_OPTS
- echo $MAVEN_OPTS

jdk:
- openjdk7
# - oraclejdk8
- oraclejdk8

os:
- linux

env:
global:
- JAVA_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xmn36M -Xmx512M"
- JAVA_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xms48M -Xmx640M -XX:InitialCodeCacheSize=40M -XX:ReservedCodeCacheSize=120M -Djava.security.egd=file:/dev/./urandom"
- MALLOC_ARENA_MAX=2
matrix:
- PHASE='-Ptest'
- PHASE='-Prake -Dtask=test:jruby'
- PHASE='-Prake -Dtask=test:jruby:fullint'
#- PHASE='-Prake -Dtask=test:jruby:fullint' # included with OpenJDK bellow
- PHASE='-Prake -Dtask=test:jruby:jit'
- PHASE='-Prake -Dtask=test:jruby:aot'
- PHASE='-Prake -Dtask=test:mri'
- PHASE='-Prake -Dtask=test:mri:fullint'
- PHASE='-Prake -Dtask=test:mri:jit'
- PHASE='-Prake -Dtask=test:slow_suites'
- PHASE='-Prake -Dtask=test:tracing'
- PHASE='-Prake -Dtask=spec:ji'
- PHASE='-Prake -Dtask=spec:compiler'
- PHASE='-Prake -Dtask=spec:compiler' JRUBY_OPTS=-Xcompile.invokedynamic
@@ -53,20 +55,23 @@ env:

matrix:
include:
- env: PHASE='-Ptest'
jdk: openjdk8
- env: PHASE='-Prake -Dtask=test:jruby:fullint'
jdk: openjdk8
# these profile do no need to run for all JDKs
- env: PHASE='-Pdist'
jdk: oraclejdk8
jdk: openjdk8
- env: PHASE='-Pjruby-jars'
jdk: openjdk7
jdk: openjdk8
- env: PHASE='-Pmain'
jdk: oraclejdk8
- env: PHASE='-Pcomplete'
jdk: oraclejdk8
- env: PHASE='-Posgi'
jdk: openjdk7
jdk: oraclejdk8
- env: PHASE='-Pj2ee'
jdk: oraclejdk7
# These next two started crashing on JDK7 in March 2015, possibly due to JVM issues on Travis's Docker-based env
jdk: oraclejdk8
- env: PHASE='-Pjruby-jars,test -Dinvoker.test=extended'
jdk: oraclejdk8
- env: PHASE='-Pmain,test -Dinvoker.test=extended'
@@ -75,17 +80,26 @@ matrix:
jdk: oraclejdk8
- env: COMMAND=test/check_versions.sh
jdk: oraclejdk8
- env: PHASE='-Prake -Dtask=test:jruby:jit'
jdk: oraclejdk9
- env: PHASE='-Prake -Dtask=test:mri:jit'
jdk: oraclejdk9
- env: PHASE='-Prake -Dtask=spec:ruby:fast'
jdk: oraclejdk9
- env: PHASE='-Pmain'
jdk: oraclejdk9
- env: PHASE='-Pcomplete'
jdk: oraclejdk9
allow_failures:
#- env: PHASE='-Pj2ee'
# jdk: oraclejdk7
# NOTE: build seems to never start (waited for any to finish for more than a day) - probably a travis-ci bug
#- env: PHASE='-Pmain'
# sudo: required
# dist: trusty
# group: edge
# jdk: oraclejdk9
- env: PHASE='-Prake -Dtask=test:jruby:jit'
jdk: oraclejdk9
- env: PHASE='-Prake -Dtask=test:mri:jit'
jdk: oraclejdk9
- env: PHASE='-Prake -Dtask=spec:ruby:fast'
jdk: oraclejdk9

install: tool/travis-install.sh
install:
- ./mvnw $MAVEN_CLI_OPTS package -B -Dinvoker.skip -Dmaven.test.skip
script: tool/travis-script.sh

notifications:
@@ -104,3 +118,10 @@ notifications:

services:
- redis-server
- haveged

addons:
apt:
packages:
# - oracle-java9-installer
- haveged
65 changes: 33 additions & 32 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ verify that JRuby is still fully functional.

### Hacking the Build System

for a general overview of the different directories and maven artifacts see [JRuby Build)](https://github.com/jruby/jruby/wiki/JRuby-Build----Some-Inside-Info)
for a general overview of the different directories and maven artifacts see [JRuby Build](https://github.com/jruby/jruby/wiki/JRuby-Build----Some-Inside-Info)

For this only the ***pom.rb*** needs to edited. using mvn-3.3.x or the maven wrapper `./mvnw` will generate the pom.xml file where needed. For the jar files of the build those pom.xml will be generated for some use-cases, i.e. some IDEs need them.

@@ -123,19 +123,21 @@ from MRI's tests (under test/mri), use one of the following commands:
The MRI suite (under `test/mri`) has a runner script in `test/mri/runner.rb` that sets up
an appropriate test environment. Many of the MRI tests will need to be run via this script.
```
jruby -r ./test/mri_test_env.rb test/mri/runner.rb test/mri/<path to test>
jruby test/mri/runner.rb test/mri/<path to test>
```

You can pass `-v` to the runner for verbose output or `-n test_method_name` to only run a single test method. If you are interested in all failures you can exlude the -r option (of mri_test_env.rb). Some excluded tests are inherent limitations of JRuby and some are just problems we have not gotten to yet.
You can pass `-v` to the runner for verbose output or `-n test_method_name` to only run a single test method.

#### Run a test file with known-failing tests excluded

The runner script provides a mechanism for "excluding" known failing tests. Ruby scripts under `test/mri/exclude`, named based on the name of the test case's class, exclude with comment tests known to fail.
The runner script provides a mechanism for "excluding" known failing tests. These are usually features that JRuby has not yet implemented or can't implement on the JVM.

To run a given test with these excludes enabled, you can use the EXCLUDES environment variable:
Excludes are in the form of Ruby scripts under `test/mri/exclude`, named based on the name of the test case's class, exclude with comment tests known to fail.

To run a given test with these excludes enabled, you can use the --excludes flag:

```
EXCLUDES=test/mri/excludes bin/jruby test/mri/runner.rb <test file>
bin/jruby test/mri/runner.rb --excludes=test/mri/excludes <test file>
```

#### Run a single Ruby spec
@@ -149,7 +151,7 @@ jruby spec/mspec/bin/mspec ci spec/ruby/<path to spec>
If `ci` is omitted or replaced with `run` you will see any specs known to fail. The `ci` command
avoids running those specs.

#### Run JRuby with with remote debugging
#### Run JRuby with remote debugging

If you are familiar with Java debuggers, you can attach one to a JRuby process using the JDWP agent.
The exact flag may vary with debugger and platform:
@@ -180,9 +182,9 @@ mvn -Pdist -Dinvoker.skip=false

JRuby runs CI tests on TravisCI. See [.travis.yml](https://github.com/jruby/jruby/blob/master/.travis.yml).

#### maven integration tests - -Pjruby-complete or -Pmain
#### Maven integration tests - -Pjruby-complete or -Pmain

maven integration test will use the packed maven artifact to run the tests in a forked maven instance. these maven projects are locatated in
maven integration tests will use the packed maven artifact to run the tests in a forked maven instance. These maven projects are locatated in

```
maven/jruby/src/it
@@ -191,7 +193,7 @@ maven/jruby-jars/src/it
maven/jruby-dist/src/it
```

to trigger the tests with the build:
To trigger the tests with the build:

```
mvn -Pmain -Dinvoker.skip=false
@@ -200,8 +202,7 @@ mvn -Pdist -Dinvoker.skip=false
mvn -Pjruby-jars -Dinvoker.skip=false
```

to pick a particular test add the name of the directory inside the respective *src/it* folder, like (wildcards are possible):

To pick a particular test, add the name of the directory inside the respective *src/it* folder, like (wildcards are possible):

```
mvn -Pmain -Dinvoker.skip=false -Dinvoker.test=integrity
@@ -212,21 +213,21 @@ mvn -Pmain -Dinvoker.skip=false -Dinvoker.test=osgi*
Clean Build
-----------

To clean the build it is important to use the same profile for the clean as what you want to build. the best way to clean build something is, i.e. jruby-jars
To clean the build it is important to use the same profile for the clean as what you want to build. The best way to clean build something is, i.e. jruby-jars

```
mvn clean install -Pjruby-jars
```

this first cleans everything and then starts the new build in one go !
This first cleans everything and then starts the new build in one go!

Cleaning the build may be necessary after switching to a different
version of JRuby (for example, after switching git branches) to ensure
that everything is rebuilt properly.

NOTE: ```mvn clean``` just cleans the **jruby-core** artifact and the **./lib/jruby.jar** !
NOTE: ```mvn clean``` just cleans the **jruby-core** artifact and the **./lib/jruby.jar**!

clean everything:
Clean everything:

```
mvn -Pclean
@@ -235,67 +236,67 @@ mvn -Pclean
Distribution Packages
---------------------

all distribution packages need maven-3.3.x or the use of supplied maven wrapper. all examples below will show the use of the maven wrapper.
All distribution packages need maven-3.3.x or the use of supplied maven wrapper. All examples below will show the use of the maven wrapper.

###the tar.gz and zip distribution packages###
### The tar.gz and zip distribution packages

```
./mvnw -Pdist
```

the files will be found in ./maven/jruby-dist/target
The files will be in `./maven/jruby-dist/target`.

###jruby-complete.jar###
### `jruby-complete.jar`

```
./mvnw -Pcomplete
```

the file will be in ./maven/jruby-complete/target
The file will be in `./maven/jruby-complete/target`.

###jruby maven artifacts###
### jruby maven artifacts

```
./mvnw -Pmain
```

and those files will be installed in you maven local-repository ready to use with maven, ivy, buildr, etc
And those files will be installed in your maven local-repository ready to use with maven, ivy, buildr, etc.

###jruby jars gem###
### jruby jars gem

```
./mvnw -Pjruby-jars
```

the gem will be in ./maven/jruby-jars/pkg
The gem will be in `./maven/jruby-jars/pkg`.

### building ALL packages ###
### Building ALL packages

```
./mvnw -Pall
```

### cleaning the build ###
### Cleaning the build

this will also clean the **ext** directories, i.e. a new build will then use the latest code from there for **lib/ruby**
This will also clean the **ext** directories, i.e. a new build will then use the latest code from there for **lib/ruby**.

```
./mvnw -Pclean
```

## release ##
## Release

first set the new version in the file *VERSION* inside the root directory and then to deploy the maven artifact to sonatype oss execute:
First set the new version in the file *VERSION* inside the root directory and then to deploy the maven artifact to sonatype oss execute:

```
./mvnw clean deploy -Psonatype-oss-release
```

go to oss.sonatype.org and close the deployment which will check if all 'required' files are in place and then finally push the release to maven central and . . .
Go to https://oss.sonatype.org/ and close the deployment, which will check if all 'required' files are in place and then finally push the release to Maven Central and . . .

### Start a new version

After the release set the new development version in *VERSION* and generate the pom.xml files
After the release, set the new development version in *VERSION* and generate the `pom.xml` files:

```
./mvnw
851 changes: 220 additions & 631 deletions COPYING

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# JRuby - an implementation of the Ruby language on the JVM

Master: [![Build Status](https://travis-ci.org/jruby/jruby.svg?branch=master)](https://travis-ci.org/jruby/jruby)
9.1 branch: [![Build Status](https://travis-ci.org/jruby/jruby.svg?branch=jruby-9.1)](https://travis-ci.org/jruby/jruby/branches)
1.7 branch: [![Build Status](https://travis-ci.org/jruby/jruby.svg?branch=jruby-1_7)](https://travis-ci.org/jruby/jruby/branches)

## About
@@ -37,7 +38,16 @@ An alternative is to use one of the [Ruby version managers](https://www.ruby-lan

For [`rbenv`](https://github.com/sstephenson/rbenv) you will need the
[`ruby-build`](https://github.com/sstephenson/ruby-build) plugin. You may find that your system
package manager can provide these. Then you can run:
package manager can provide these. To see which versions of JRuby are available you should run:

```
$ rbenv install jruby
```

Note: if you do not regularly git update rbenv this list of versions may be out of date.

We recommend always selecting the latest version of JRuby from the list. The you can install that particular version (9.1.10.0 is just for illustration):


```
$ rbenv install jruby-9.1.10.0
@@ -76,6 +86,6 @@ Project Contact: Thomas E Enebo <tom.enebo@gmail.com>

## License

JRuby is licensed to you under three licenses - the EPL 1.0, GPL 2 and LGPL 2.1.
JRuby is licensed to you under three licenses - the EPL 2.0, GPL 2 and LGPL 2.1.
Some components have other licenses and copyright. See the [COPYING](COPYING)
file for more specifics.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.1.11.0-SNAPSHOT
9.2.0.0-SNAPSHOT
55 changes: 55 additions & 0 deletions bench/pom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
version = ENV['JRUBY_VERSION'] ||
File.read(File.join(basedir, '..', 'VERSION')).strip

project 'JRuby Benchmark' do

model_version '4.0.0'
inherit 'org.jruby:jruby-parent', version
id 'org.jruby:jruby-benchmark'

properties('polyglot.dump.pom' => 'pom.xml',
'polyglot.dump.readonly' => true,
'maven.build.timestamp.format' => 'yyyy-MM-dd',
'maven.test.skip' => 'true',
'build.date' => '${maven.build.timestamp}',
'main.basedir' => '${project.parent.basedir}',
'jruby.basedir' => '${basedir}/..',
'jmh.version' => '1.19'
)

IO.foreach(File.join(basedir, '..', 'default.build.properties')) do |line|
line.chomp!
# skip comments
next if line =~ /(^\W*#|^$)/
# build const name
name, value = line.split('=', 2)
properties name => value
end

jar 'org.jruby:jruby-core:${project.version}'
jar 'org.openjdk.jmh:jmh-core:${jmh.version}'
jar 'org.openjdk.jmh:jmh-generator-annprocess:${jmh.version}'
jar 'org.openjdk.jmh:jmh-core-benchmarks:${jmh.version}'

plugin(:compiler,
'encoding' => 'utf-8',
'debug' => 'true',
'verbose' => 'true',
'fork' => 'true',
'compilerArgs' => { 'arg' => '-J-Xmx1G' },
'showWarnings' => 'true',
'showDeprecation' => 'true',
'source' => ['${base.java.version}', '1.7'],
'target' => ['${base.javac.version}', '1.7'],
'useIncrementalCompilation' => 'false')

plugin :shade do
execute_goals('shade',
:id => 'create jruby-benchmark.jar',
:phase => 'package',
'outputFile' => '${project.build.directory}/jruby-benchmark.jar',
'transformers' => [{ '@implementation' => 'org.apache.maven.plugins.shade.resource.ManifestResourceTransformer',
'mainClass' => 'org.openjdk.jmh.Main' }]
)
end
end
128 changes: 128 additions & 0 deletions bench/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
DO NOT MODIFIY - GENERATED CODE
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jruby</groupId>
<artifactId>jruby-parent</artifactId>
<version>9.2.0.0-SNAPSHOT</version>
</parent>
<artifactId>jruby-benchmark</artifactId>
<name>JRuby Benchmark</name>
<properties>
<version.ruby>2.4.1</version.ruby>
<prawn.dir>${test.dir}/prawn</prawn.dir>
<spec.tags.dir>${spec.dir}/tags</spec.tags.dir>
<polyglot.dump.pom>pom.xml</polyglot.dump.pom>
<pkg.dir>${build.dir}/pkg</pkg.dir>
<spec.dir>spec</spec.dir>
<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
<installer.gems>${jruby.win32ole.gem}</installer.gems>
<prawn.git.repo>git://github.com/sandal/prawn.git</prawn.git.repo>
<version.ruby.minor>1</version.ruby.minor>
<install4j.executable>/Applications/install4j 4/bin/install4jc</install4j.executable>
<jay.bin>jay</jay.bin>
<polyglot.dump.readonly>true</polyglot.dump.readonly>
<dest.lib.dir>${lib.dir}</dest.lib.dir>
<rails.git.repo>git://github.com/rails/rails.git</rails.git.repo>
<build.dir>target</build.dir>
<maven.test.skip>true</maven.test.skip>
<rubyspec.1.8.dir>${rubyspec.dir}/1.8</rubyspec.1.8.dir>
<jruby.launch.memory>1024M</jruby.launch.memory>
<version.ruby.major>2.4</version.ruby.major>
<release.dir>release</release.dir>
<lib.dir>lib</lib.dir>
<rails.dir>${test.dir}/rails</rails.dir>
<parser.dir>core/src/main/java/org/jruby/parser</parser.dir>
<jruby.basedir>${basedir}/..</jruby.basedir>
<rubyspec.dir>${spec.dir}/ruby</rubyspec.dir>
<version.ruby.revision>58053</version.ruby.revision>
<mspec.dir>${spec.dir}/mspec</mspec.dir>
<build.date>${maven.build.timestamp}</build.date>
<main.basedir>${project.parent.basedir}</main.basedir>
<test.results.dir>${build.dir}/test-results</test.results.dir>
<prawn.stable.version>0.4.1</prawn.stable.version>
<mspec.tar.file>${build.dir}/mspec.tgz</mspec.tar.file>
<build.lib.dir>test/target</build.lib.dir>
<jmh.version>1.19</jmh.version>
<rake.args></rake.args>
<test.dir>test</test.dir>
<jflex.bin>jflex</jflex.bin>
<jruby.win32ole.gem>jruby-win32ole</jruby.win32ole.gem>
<mspec.bin>${mspec.dir}/bin/mspec</mspec.bin>
<jruby.gem.home>lib/ruby/gems/shared</jruby.gem.home>
<test.classes.dir>${test.dir}/target/test-classes</test.classes.dir>
</properties>
<dependencies>
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core-benchmarks</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>utf-8</encoding>
<debug>true</debug>
<verbose>true</verbose>
<fork>true</fork>
<compilerArgs>
<arg>-J-Xmx1G</arg>
</compilerArgs>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
<source>${base.java.version}</source>
<source>1.7</source>
<target>${base.javac.version}</target>
<target>1.7</target>
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>create jruby-benchmark.jar</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<outputFile>${project.build.directory}/jruby-benchmark.jar</outputFile>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
127 changes: 127 additions & 0 deletions bench/src/main/java/org/jruby/benchmark/ArrayCopyBenchmark.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.jruby.benchmark;

import java.util.concurrent.TimeUnit;
import org.jruby.util.ArraySupport;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class ArrayCopyBenchmark {

private static final int INVOCATIONS = 100_000_000;

private static final String[] arr0 = new String[0];
private static final Object[] arr1 = {"obj"};
private static final Object[] arr2 = {1, 2};
private static final Object[] arr3 = {1, 2, null};
private static final Object[] arr4 = {1, 2, 3, 4};
private static final Object[] arr5 = {1, 2, null, 4, null};

private static final String[] dst0 = {};
private static final Object[] dst1 = new Object[1];
private static final Object[] dst2 = new Object[3];
private static final Object[] dst3 = {1, 2, null};
private static final Object[] dst4 = {1, 2, null, 4, null};

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy0() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr0, 0, dst0, 0, arr0.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy1() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr1, 0, dst1, 0, arr1.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy2() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr2, 0, dst2, 0, arr2.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy3() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr3, 0, dst3, 0, arr3.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy4() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr4, 0, dst4, 0, arr4.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchSystemCopy5() {
for (int i = 0; i < INVOCATIONS; i++) {
System.arraycopy(arr5, 0, new Object[6], 1, arr5.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchUtilsCopy0() {
for (int i = 0; i < INVOCATIONS; i++) {
ArraySupport.copy(arr0, dst0, 0, arr0.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchUtilsCopy1() {
for (int i = 0; i < INVOCATIONS; i++) {
ArraySupport.copy(arr1, dst1, 0, arr1.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchUtilsCopy2() {
for (int i = 0; i < INVOCATIONS; i++) {
ArraySupport.copy(arr2, dst2, 0, arr2.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchUtilsCopy3() {
for (int i = 0; i < INVOCATIONS; i++) {
ArraySupport.copy(arr3, dst3, 0, arr3.length);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchUtilsCopy4() {
for (int i = 0; i < INVOCATIONS; i++) {
ArraySupport.copy(arr4, dst4, 0, arr4.length);
}
}

}
139 changes: 139 additions & 0 deletions bench/src/main/java/org/jruby/benchmark/EventHookBenchmark.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.jruby.benchmark;

import java.util.concurrent.TimeUnit;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.runtime.Binding;
import org.jruby.runtime.EventHook;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@Warmup(iterations = 3, time = 3)
@Measurement(iterations = 10, time = 3)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
public class EventHookBenchmark {

private static final int INVOCATIONS = 10;

private static final String BOOT_SCRIPT =
"def fib(a) \n if a.send :<, \n 2 \n a \n else \n fib(a.send :-, 1).send :+, \n fib(a.send :-, 2) \n end \n end";

private static final String RUN_SCRIPT = "fib(30)";

private static final Ruby RUNTIME = initRuntime();
private static final Ruby INTERP_RUNTIME = initInterpRuntime();
private static final Ruby TRACED_RUNTIME = initTracedRuntime();
private static final Ruby HOOKED_RUNTIME_ONE = initHookedRuntime(
new EventHook() {
@Override
public void eventHandler(final ThreadContext context, final String eventName,
final String file, final int line, final String name, final IRubyObject type) {
// do nothing
}

@Override
public boolean isInterestedInEvent(final RubyEvent event) {
// want everything
return true;
}
});
private static final Ruby HOOKED_RUNTIME_TWO = initHookedRuntime(
new EventHook() {
@Override
public void eventHandler(final ThreadContext context, final String eventName,
final String file, final int line, final String name, final IRubyObject type) {
// get binding
final Binding binding = context.currentBinding();
}

@Override
public boolean isInterestedInEvent(final RubyEvent event) {
// want everything
return true;
}
}
);

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchControl() {
for (int i = 0; i < INVOCATIONS; i++) {
RUNTIME.evalScriptlet(RUN_SCRIPT);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchInterp() {
for (int i = 0; i < INVOCATIONS; i++) {
INTERP_RUNTIME.evalScriptlet(RUN_SCRIPT);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchTraced() {
for (int i = 0; i < INVOCATIONS; i++) {
TRACED_RUNTIME.evalScriptlet(RUN_SCRIPT);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchHooked1() {
for (int i = 0; i < INVOCATIONS; i++) {
HOOKED_RUNTIME_ONE.evalScriptlet(RUN_SCRIPT);
}
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchHooked2() {
for (int i = 0; i < INVOCATIONS; i++) {
HOOKED_RUNTIME_TWO.evalScriptlet(RUN_SCRIPT);
}
}

private static Ruby initRuntime() {
final RubyInstanceConfig config = new RubyInstanceConfig();
config.setCompileMode(RubyInstanceConfig.CompileMode.OFF);
config.setObjectSpaceEnabled(true);
final Ruby runtime = Ruby.newInstance(config);
runtime.evalScriptlet(BOOT_SCRIPT);
return runtime;
}

private static Ruby initInterpRuntime() {
final Ruby runtime = Ruby.newInstance(new RubyInstanceConfig());
runtime.evalScriptlet(BOOT_SCRIPT);
return runtime;
}

private static Ruby initTracedRuntime() {
final RubyInstanceConfig config = new RubyInstanceConfig();
RubyInstanceConfig.FULL_TRACE_ENABLED = true;
final Ruby runtime = Ruby.newInstance(config);
runtime.evalScriptlet(BOOT_SCRIPT);
return runtime;
}

private static Ruby initHookedRuntime(final EventHook hook) {
final Ruby runtime = initTracedRuntime();
runtime.addEventHook(hook);
return runtime;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.jruby.benchmark;

import java.util.concurrent.TimeUnit;
import org.jruby.Ruby;
import org.jruby.RubyFixnum;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 20, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class FixnumCreationBenchmark {

private static final int INVOCATIONS = 1_000_000;

private static final Ruby RUBY = Ruby.newInstance();

private static final RubyFixnum ONE = RubyFixnum.newFixnum(RUBY, 1L);

private static final RubyFixnum TWO = RubyFixnum.newFixnum(RUBY, 2L);

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchFixnumCreation(final Blackhole blackhole) {
final long time = System.currentTimeMillis();
final Ruby ruby = RUBY;
for (int i = 0; i < INVOCATIONS; i++) {
blackhole.consume(RubyFixnum.newFixnum(ruby, time));
}
}

@Benchmark
@OutputTimeUnit(TimeUnit.SECONDS)
public void benchStaticFib(final Blackhole blackhole) {
final Ruby ruby = RUBY;
final ThreadContext context = ruby.getCurrentContext();
blackhole.consume(fib(context, RubyFixnum.newFixnum(ruby, 30L)));
}

private static IRubyObject fib(final ThreadContext context, final IRubyObject object) {
final RubyFixnum value = (RubyFixnum) object;
if (value.op_lt(context, TWO).isTrue()) {
return value;
}
return ((RubyFixnum) fib(context, value.op_minus(context, TWO)))
.op_plus(context, fib(context, value.op_minus(context, ONE)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.jruby.benchmark;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.jruby.Ruby;
import org.jruby.RubyFixnum;
import org.jruby.RubyInstanceConfig;
import org.jruby.runtime.builtin.IRubyObject;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class JavaInterfaceBenchmark {

private static final int INVOCATIONS = 200_000_000;

private static final Ruby RUBY = initRuby();

private static final RubyFixnum LEFT = RUBY.newFixnum(ThreadLocalRandom.current().nextInt());

private static final RubyFixnum RIGHT = RUBY.newFixnum(ThreadLocalRandom.current().nextInt());

private static final JavaInterfaceBenchmark.Summation JAVA_SUMMER =
new JavaInterfaceBenchmark.Summation() {
@Override
public IRubyObject sum(final RubyFixnum left, final RubyFixnum right) {
return left.op_plus(RUBY.getCurrentContext(), right);
}
};

public interface Summation {
IRubyObject sum(RubyFixnum left, RubyFixnum right);
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchHalfRubyVersion(final Blackhole blackhole) {
blackhole.consume(
RUBY.executeScript(
"org.jruby.benchmark.JavaInterfaceBenchmark.doRun(RubySummation.new)"
,"benchHalfRubyVersion")
);
}

@Benchmark
@OperationsPerInvocation(INVOCATIONS)
public void benchJavaVersion(final Blackhole blackhole) {
blackhole.consume(doRun(JAVA_SUMMER));
}

public static IRubyObject doRun(final JavaInterfaceBenchmark.Summation summer) {
IRubyObject sum = null;
for (int i = 0; i < INVOCATIONS; ++i) {
sum = summer.sum(LEFT, RIGHT);
}
return sum;
}

private static Ruby initRuby() {
final RubyInstanceConfig config = new RubyInstanceConfig();
config.setCompileMode(RubyInstanceConfig.CompileMode.FORCE);
final Ruby ruby = Ruby.newInstance(config);
ruby.executeScript(
new StringBuilder()
.append("class RubySummation\n")
.append("\tinclude org.jruby.benchmark.JavaInterfaceBenchmark::Summation\n")
.append('\n')
.append("\tdef sum(a, b)\n")
.append("\t\ta + b\n")
.append("\tend\n")
.append("end")
.toString(), "initRuby"
);
return ruby;
}
}
2 changes: 1 addition & 1 deletion bin/jgem
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ require 'rubygems/exceptions'
required_version = Gem::Requirement.new ">= 1.8.7"

unless required_version.satisfied_by? Gem.ruby_version then
abort "Expected Ruby Version #{required_version}, is #{Gem.ruby_version}"
abort "Expected Ruby version #{required_version}, is #{Gem.ruby_version}"
end

args = ARGV.clone
41 changes: 29 additions & 12 deletions bin/jruby.bash
Original file line number Diff line number Diff line change
@@ -20,6 +20,14 @@ case "`uname`" in
MINGW*) jruby.exe "$@"; exit $?;;
esac

# ----- Determine how to call expr (jruby/jruby#5091) -------------------------
# On Alpine linux, expr takes no -- arguments, and 'expr --' echoes '--'.
_expr_dashed=$(expr -- 2>/dev/null)
if [ "$_expr_dashed" != '--' ] ; then
alias expr="expr --"
fi
unset _expr_dashed

# ----- Verify and Set Required Environment Variables -------------------------
if [ -z "$JAVA_VM" ]; then
JAVA_VM=-client
@@ -180,6 +188,14 @@ fi
# ----- Execute The Requested Command -----------------------------------------
JAVA_ENCODING=""

if [ -r "/dev/urandom" ]; then
# OpenJDK tries really hard to prevent you from using urandom.
# See https://bugs.openjdk.java.net/browse/JDK-6202721
# Non-file URL causes fallback to slow threaded SeedGenerator.
# See https://bz.apache.org/bugzilla/show_bug.cgi?id=56139
JAVA_SECURITY_EGD="file:/dev/urandom"
fi

declare -a java_args
declare -a ruby_args
mode=""
@@ -219,23 +235,16 @@ do
CP="$CP$CP_DELIMITER$2"
CLASSPATH=""
shift
elif [ "${val:0:3}" = "-G:" ]; then # Graal options
opt=${val:3}
case $opt in
+*)
opt="${opt:1}=true" ;;
-*)
opt="${opt:1}=false" ;;
esac
echo "$1 is deprecated - use -J-Dgraal.$opt instead" >&2
java_args=("${java_args[@]}" "-Dgraal.$opt")
else
if [ "${val:0:3}" = "-ea" ]; then
VERIFY_JRUBY="yes"
elif [ "${val:0:16}" = "-Dfile.encoding=" ]; then
JAVA_ENCODING=$val
JAVA_ENCODING=$val${val:16}
elif [ "${val:0:20}" = "-Djava.security.egd=" ]; then
JAVA_SECURITY_EGD=${val:20}
else
java_args=("${java_args[@]}" "${1:2}")
fi
java_args=("${java_args[@]}" "${1:2}")
fi
;;
# Pass -X... and -X? search options through
@@ -313,6 +322,14 @@ done
# Force file.encoding to UTF-8 when on Mac, since Apple JDK defaults to MacRoman (JRUBY-3576)
if [[ $darwin && -z "$JAVA_ENCODING" ]]; then
java_args=("${java_args[@]}" "-Dfile.encoding=UTF-8")
elif [[ -n "$JAVA_ENCODING" ]]; then
java_args=("${java_args[@]}" "-Dfile.encoding=$JAVA_ENCODING")
fi

# Force OpenJDK-based JVMs to use /dev/urandom for random number generation
# See https://github.com/jruby/jruby/issues/4685 among others.
if [[ -n "$JAVA_SECURITY_EGD" ]]; then
java_args=("${java_args[@]}" "-Djava.security.egd=$JAVA_SECURITY_EGD")
fi

# Append the rest of the arguments
8 changes: 4 additions & 4 deletions bin/jruby.sh
Original file line number Diff line number Diff line change
@@ -26,9 +26,9 @@ progname=`basename "$0"`

while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '.*/.*' > /dev/null; then
if expr "$link" : '/' > /dev/null; then
link=`expr -- "$ls" : '.*-> \(.*\)$'`
if expr -- "$link" : '.*/.*' > /dev/null; then
if expr -- "$link" : '/' > /dev/null; then
PRG="$link"
else
PRG="`dirname ${PRG}`/${link}"
@@ -202,7 +202,7 @@ do
# Match -Xa.b.c=d to translate to -Da.b.c=d as a java option
-X*)
val=${1:2}
if expr "$val" : '.*[.]' > /dev/null; then
if expr -- "$val" : '.*[.]' > /dev/null; then
java_args="${java_args} -Djruby.${val}"
else
ruby_args="${ruby_args} -X${val}"
5 changes: 5 additions & 0 deletions bin/rake
Original file line number Diff line number Diff line change
@@ -19,4 +19,9 @@ if ARGV.first
end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('rake', 'rake', version)
else
gem "rake", version
load Gem.bin_path("rake", "rake", version)
end
45 changes: 28 additions & 17 deletions core/pom.rb
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@

'jruby.basedir' => '${basedir}/..',
'jruby.test.memory' => '3G',
'jruby.test.memory.permgen' => '2G',
'jruby.compile.memory' => '2G',

'create.sources.jar' => false )
@@ -43,23 +42,22 @@

# exclude jnr-ffi to avoid problems with shading and relocation of the asm packages
jar 'com.github.jnr:jnr-netdb:1.1.6', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-enxio:0.16', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-enxio:0.17', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-x86asm:1.0.2', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.17', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-posix:3.0.41', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-unixsocket:0.19', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-posix:3.0.45', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-constants:0.9.9', :exclusions => ['com.github.jnr:jnr-ffi']
jar 'com.github.jnr:jnr-ffi:2.1.6'
jar 'com.github.jnr:jnr-ffi:2.1.8'
jar 'com.github.jnr:jffi:${jffi.version}'
jar 'com.github.jnr:jffi:${jffi.version}:native'

jar 'org.jruby.joni:joni:2.1.11'
jar 'org.jruby.joni:joni:2.1.16'
jar 'org.jruby.extras:bytelist:1.0.15'
jar 'org.jruby.jcodings:jcodings:1.0.18'
jar 'org.jruby.jcodings:jcodings:1.0.30'
jar 'org.jruby:dirgra:0.3'

jar 'com.headius:invokebinder:1.7'
jar 'com.headius:invokebinder:1.11'
jar 'com.headius:options:1.4'
jar 'com.headius:unsafe-fences:1.0'

jar 'bsf:bsf:2.4.0', :scope => 'provided'
jar 'com.jcraft:jzlib:1.1.3'
@@ -78,6 +76,8 @@

jar 'me.qmx.jitescript:jitescript:0.4.1', :exclusions => ['org.ow2.asm:asm-all']

jar 'com.headius:modulator:1.0'

plugin_management do
plugin( 'org.eclipse.m2e:lifecycle-mapping:1.0.0',
'lifecycleMappingMetadata' => {
@@ -166,8 +166,8 @@
'compilerArgs' => { 'arg' => '-J-Xmx1G' },
'showWarnings' => 'true',
'showDeprecation' => 'true',
'source' => [ '${base.java.version}', '1.7' ],
'target' => [ '${base.javac.version}', '1.7' ],
'source' => [ '${base.java.version}', '1.8' ],
'target' => [ '${base.javac.version}', '1.8' ],
'useIncrementalCompilation' => 'false' ) do
execute_goals( 'compile',
:id => 'anno',
@@ -183,6 +183,7 @@
execute_goals( 'compile',
:id => 'default-compile',
:phase => 'compile',
'debug' => 'true',
'annotationProcessors' => [ 'org.jruby.anno.AnnotationBinder' ],
'generatedSourcesDirectory' => 'target/generated-sources',
'compilerArgs' => [ '-XDignore.symbol.file=true',
@@ -192,6 +193,7 @@
execute_goals( 'compile',
:id => 'populators',
:phase => 'process-classes',
'debug' => 'true',
'compilerArgs' => [ '-XDignore.symbol.file=true',
'-J-Duser.language=en',
'-J-Dfile.encoding=UTF-8',
@@ -223,7 +225,7 @@
'systemProperties' => {
'jruby.home' => '${basedir}/..'
},
'argLine' => '-Xmx${jruby.test.memory} -XX:MaxPermSize=${jruby.test.memory.permgen} -Dfile.encoding=UTF-8 -Djava.awt.headless=true',
'argLine' => '-Xmx${jruby.test.memory} -Dfile.encoding=UTF-8 -Djava.awt.headless=true',
'includes' => [ 'org/jruby/test/MainTestSuite.java',
'org/jruby/embed/**/*Test*.java',
'org/jruby/util/**/*Test*.java',
@@ -262,12 +264,16 @@
execute_goals( 'shade',
:id => 'create lib/jruby.jar',
:phase => 'package',
'relocations' => [ { 'pattern' => 'org.objectweb',
'shadedPattern' => 'org.jruby.org.objectweb' } ],
relocations: [
{pattern: 'org.objectweb', shadedPattern: 'org.jruby.org.objectweb' },
],
'outputFile' => '${jruby.basedir}/lib/jruby.jar',
'transformers' => [ { '@implementation' => 'org.apache.maven.plugins.shade.resource.ManifestResourceTransformer',
'mainClass' => 'org.jruby.Main' } ],
'createSourcesJar' => '${create.sources.jar}' )
'createSourcesJar' => '${create.sources.jar}',
filters:
{filter: {artifact: 'com.headius:invokebinder', excludes: {exclude: '**/module-info.class'}}}
)
end

[:all, :release, :main, :osgi, :j2ee, :complete, :dist, :'jruby_complete_jar_extended', :'jruby-jars' ].each do |name|
@@ -286,8 +292,13 @@
'me.qmx.jitescript:jitescript',
'org.ow2.asm:*' ]
},
'relocations' => [ { 'pattern' => 'org.objectweb',
'shadedPattern' => 'org.jruby.org.objectweb' } ] )
relocations: [
{pattern: 'org.objectweb', shadedPattern: 'org.jruby.org.objectweb' },
{pattern: 'me.qmx.jitescript', shadedPattern: 'org.jruby.me.qmx.jitescript'},
],
filters:
{filter: {artifact: 'com.headius:invokebinder', excludes: {exclude: '**/module-info.class'}}}
)
end
end
end
161 changes: 139 additions & 22 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -12,24 +12,23 @@ DO NOT MODIFIY - GENERATED CODE
<parent>
<groupId>org.jruby</groupId>
<artifactId>jruby-parent</artifactId>
<version>9.1.11.0-SNAPSHOT</version>
<version>9.2.0.0-SNAPSHOT</version>
</parent>
<artifactId>jruby-core</artifactId>
<name>JRuby Core</name>
<properties>
<version.ruby>2.3.3</version.ruby>
<version.ruby>2.5.0</version.ruby>
<prawn.dir>${test.dir}/prawn</prawn.dir>
<spec.tags.dir>${spec.dir}/tags</spec.tags.dir>
<polyglot.dump.pom>pom.xml</polyglot.dump.pom>
<pkg.dir>${build.dir}/pkg</pkg.dir>
<spec.dir>spec</spec.dir>
<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
<jruby.test.memory.permgen>2G</jruby.test.memory.permgen>
<installer.gems>${jruby.win32ole.gem}</installer.gems>
<prawn.git.repo>git://github.com/sandal/prawn.git</prawn.git.repo>
<version.ruby.minor>3</version.ruby.minor>
<version.ruby.minor>0</version.ruby.minor>
<tzdata.version>2013d</tzdata.version>
<install4j.executable>/Applications/install4j 4/bin/install4jc</install4j.executable>
<install4j.executable>/Applications/install4j7/bin/install4jc</install4j.executable>
<jay.bin>jay</jay.bin>
<polyglot.dump.readonly>true</polyglot.dump.readonly>
<dest.lib.dir>${lib.dir}</dest.lib.dir>
@@ -39,15 +38,15 @@ DO NOT MODIFIY - GENERATED CODE
<rubyspec.1.8.dir>${rubyspec.dir}/1.8</rubyspec.1.8.dir>
<jruby.launch.memory>1024M</jruby.launch.memory>
<jruby.compile.memory>2G</jruby.compile.memory>
<version.ruby.major>2.3</version.ruby.major>
<version.ruby.major>2.5</version.ruby.major>
<release.dir>release</release.dir>
<create.sources.jar>false</create.sources.jar>
<lib.dir>lib</lib.dir>
<rails.dir>${test.dir}/rails</rails.dir>
<parser.dir>core/src/main/java/org/jruby/parser</parser.dir>
<jruby.basedir>${basedir}/..</jruby.basedir>
<rubyspec.dir>${spec.dir}/ruby</rubyspec.dir>
<version.ruby.revision>56859</version.ruby.revision>
<version.ruby.revision>60928</version.ruby.revision>
<jruby.test.memory>3G</jruby.test.memory>
<mspec.dir>${spec.dir}/mspec</mspec.dir>
<build.date>${maven.build.timestamp}</build.date>
@@ -102,7 +101,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-enxio</artifactId>
<version>0.16</version>
<version>0.17</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
@@ -124,7 +123,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-unixsocket</artifactId>
<version>0.17</version>
<version>0.19</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
@@ -135,7 +134,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-posix</artifactId>
<version>3.0.41</version>
<version>3.0.45</version>
<exclusions>
<exclusion>
<artifactId>jnr-ffi</artifactId>
@@ -157,7 +156,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-ffi</artifactId>
<version>2.1.6</version>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
@@ -173,7 +172,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>org.jruby.joni</groupId>
<artifactId>joni</artifactId>
<version>2.1.11</version>
<version>2.1.16</version>
</dependency>
<dependency>
<groupId>org.jruby.extras</groupId>
@@ -183,7 +182,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>org.jruby.jcodings</groupId>
<artifactId>jcodings</artifactId>
<version>1.0.18</version>
<version>1.0.30</version>
</dependency>
<dependency>
<groupId>org.jruby</groupId>
@@ -193,18 +192,13 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>com.headius</groupId>
<artifactId>invokebinder</artifactId>
<version>1.7</version>
<version>1.11</version>
</dependency>
<dependency>
<groupId>com.headius</groupId>
<artifactId>options</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.headius</groupId>
<artifactId>unsafe-fences</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>bsf</groupId>
<artifactId>bsf</artifactId>
@@ -273,6 +267,11 @@ DO NOT MODIFIY - GENERATED CODE
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.headius</groupId>
<artifactId>modulator</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<defaultGoal>package</defaultGoal>
@@ -479,6 +478,7 @@ DO NOT MODIFIY - GENERATED CODE
<goal>compile</goal>
</goals>
<configuration>
<debug>true</debug>
<annotationProcessors>
<annotationProcessor>org.jruby.anno.AnnotationBinder</annotationProcessor>
</annotationProcessors>
@@ -498,6 +498,7 @@ DO NOT MODIFIY - GENERATED CODE
<goal>compile</goal>
</goals>
<configuration>
<debug>true</debug>
<compilerArgs>
<compilerArg>-XDignore.symbol.file=true</compilerArg>
<compilerArg>-J-Duser.language=en</compilerArg>
@@ -534,9 +535,9 @@ DO NOT MODIFIY - GENERATED CODE
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
<source>${base.java.version}</source>
<source>1.7</source>
<source>1.8</source>
<target>${base.javac.version}</target>
<target>1.7</target>
<target>1.8</target>
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
@@ -583,7 +584,7 @@ DO NOT MODIFIY - GENERATED CODE
<systemProperties>
<jruby.home>${basedir}/..</jruby.home>
</systemProperties>
<argLine>-Xmx${jruby.test.memory} -XX:MaxPermSize=${jruby.test.memory.permgen} -Dfile.encoding=UTF-8 -Djava.awt.headless=true</argLine>
<argLine>-Xmx${jruby.test.memory} -Dfile.encoding=UTF-8 -Djava.awt.headless=true</argLine>
<includes>
<include>org/jruby/test/MainTestSuite.java</include>
<include>org/jruby/embed/**/*Test*.java</include>
@@ -618,6 +619,14 @@ DO NOT MODIFIY - GENERATED CODE
</transformer>
</transformers>
<createSourcesJar>${create.sources.jar}</createSourcesJar>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -677,7 +686,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -711,7 +732,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -745,7 +778,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -779,7 +824,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -813,7 +870,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -847,7 +916,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -881,7 +962,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -915,7 +1008,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -949,7 +1054,19 @@ DO NOT MODIFIY - GENERATED CODE
<pattern>org.objectweb</pattern>
<shadedPattern>org.jruby.org.objectweb</shadedPattern>
</relocation>
<relocation>
<pattern>me.qmx.jitescript</pattern>
<shadedPattern>org.jruby.me.qmx.jitescript</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>com.headius:invokebinder</artifact>
<excludes>
<exclude>**/module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
30 changes: 30 additions & 0 deletions core/src/main/java/Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import org.jruby.Ruby;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import java.io.IOException;

public class Test {
public static void main(String[] args) throws InterruptedException, ScriptException, ClassNotFoundException, IOException {
for (int i = 0; i < 100; i++) blah();

System.gc();
System.gc();
Thread.sleep(5000);

System.out.println(Ruby.getGlobalRuntime().getFilenoUtil().getNumberOfWrappers());

}

private static void blah() throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
final ScriptEngine engine = scriptEngineManager.getEngineByName("jruby");
final ScriptContext scriptContext = new SimpleScriptContext();
scriptContext.setAttribute("org.jruby.embed.termination", true, ScriptContext.ENGINE_SCOPE);

engine.eval("print 'test\n'", scriptContext);
}
}
51 changes: 33 additions & 18 deletions core/src/main/java/org/jruby/AbstractRubyMethod.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -29,9 +29,11 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jruby.anno.JRubyMethod;
import org.jruby.internal.runtime.methods.AliasMethod;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.IRMethodArgs;
import org.jruby.internal.runtime.methods.UndefinedMethod;
@@ -41,15 +43,9 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.marshal.DataType;

/**
* The RubyMethod class represents a RubyMethod object.
*
* You can get such a method by calling the "method" method of an object.
*
* Note: This was renamed from Method.java
*
* @author jpetersen
* @since 0.2.3
/**
* @see RubyMethod
* @see RubyUnboundMethod
*/
public abstract class AbstractRubyMethod extends RubyObject implements DataType {
protected RubyModule implementationModule;
@@ -82,9 +78,19 @@ public RubyFixnum arity() {
return getRuntime().newFixnum(value);
}

@Deprecated
public final IRubyObject op_eql19(ThreadContext context, IRubyObject other) {
return op_eql(context, other);
}

@JRubyMethod(name = "eql?", required = 1)
public IRubyObject op_eql19(ThreadContext context, IRubyObject other) {
return op_equal(context, other);
public IRubyObject op_eql(ThreadContext context, IRubyObject other) {
return context.runtime.newBoolean( equals(other) );
}

@Override
public boolean equals(Object other) {
return this == other;
}

public abstract AbstractRubyMethod rbClone();
@@ -100,7 +106,7 @@ public String getMethodName() {

@JRubyMethod(name = "owner")
public IRubyObject owner(ThreadContext context) {
return method.getDefinedClass();
return implementationModule;
}

@JRubyMethod(name = "source_location")
@@ -112,7 +118,7 @@ public IRubyObject source_location(ThreadContext context) {
return runtime.newArray(runtime.newString(filename), runtime.newFixnum(getLine()));
}

return context.runtime.getNil();
return context.nil;
}

public String getFilename() {
@@ -139,16 +145,25 @@ public IRubyObject parameters(ThreadContext context) {
}

protected IRubyObject super_method(ThreadContext context, IRubyObject receiver, RubyModule superClass) {
if (superClass == null) return context.runtime.getNil();
if (superClass == null) return context.nil;

DynamicMethod newMethod = superClass.searchMethod(methodName);
if (newMethod == UndefinedMethod.INSTANCE) return context.runtime.getNil();
if (newMethod == UndefinedMethod.INSTANCE) return context.nil;

if (receiver == null) {
return RubyUnboundMethod.newUnboundMethod(superClass, methodName, superClass, originName, newMethod);
} else {
return RubyMethod.newMethod(superClass, methodName, superClass, originName, newMethod, receiver);
}
}

@JRubyMethod
public IRubyObject original_name(ThreadContext context) {
if (method instanceof AliasMethod) {
return context.runtime.newSymbol(((AliasMethod) method).getOldName());
}

return context.runtime.newSymbol(method.getName());
}
}

14 changes: 9 additions & 5 deletions core/src/main/java/org/jruby/BasicObjectStub.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -25,6 +25,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.util.Collections;
@@ -41,6 +42,8 @@

import static org.jruby.runtime.invokedynamic.MethodNames.INSPECT;
import static org.jruby.runtime.Helpers.invokedynamic;
import static org.jruby.util.RubyStringBuilder.str;

import org.jruby.util.TypeConverter;

public final class BasicObjectStub {
@@ -145,8 +148,9 @@ public static Class getJavaClass(IRubyObject self) {

public static String asJavaString(IRubyObject self) {
IRubyObject asString = checkStringType(self);
if(!asString.isNil()) return ((RubyString)asString).asJavaString();
throw getRuntime(self).newTypeError(inspect(self).toString() + " is not a string");
if(!asString.isNil()) return asString.asJavaString();
Ruby runtime = getRuntime(self);
throw runtime.newTypeError(str(runtime, "", inspect(self), " is not a string"));
}

public static RubyString asString(IRubyObject self) {
7 changes: 6 additions & 1 deletion core/src/main/java/org/jruby/CompatVersion.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.jruby;

@Deprecated
public enum CompatVersion {

@Deprecated RUBY1_8,
@@ -8,14 +9,17 @@ public enum CompatVersion {
@Deprecated RUBY2_1,
@Deprecated BOTH;

@Deprecated
public boolean is1_9() {
return this == RUBY1_9 || this == RUBY2_0 || this == RUBY2_1;
}

@Deprecated
public boolean is2_0() {
return this == RUBY2_0 || this == RUBY2_1;
}

@Deprecated
public static CompatVersion getVersionFromString(String compatString) {
if (compatString.equalsIgnoreCase("RUBY1_8")) {
return CompatVersion.RUBY1_8;
@@ -37,7 +41,8 @@ public static CompatVersion getVersionFromString(String compatString) {
return null;
}
}


@Deprecated
public static boolean shouldBindMethod(CompatVersion runtimeVersion, CompatVersion methodVersion) {
if (runtimeVersion == RUBY1_8) return methodVersion == RUBY1_8 || methodVersion == BOTH;
if (runtimeVersion == RUBY1_9) return methodVersion == RUBY1_9 || methodVersion == BOTH;
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/Finalizable.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -25,6 +25,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

/**
4 changes: 0 additions & 4 deletions core/src/main/java/org/jruby/IncludedModule.java
Original file line number Diff line number Diff line change
@@ -34,10 +34,6 @@ public void setMetaClass(RubyClass newRubyClass) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

public void setMethods(Map newMethods) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

@Override
public String getName() {
return origin.getName();
35 changes: 24 additions & 11 deletions core/src/main/java/org/jruby/IncludedModuleWrapper.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -30,13 +30,16 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.builtin.Variable;

@@ -79,11 +82,7 @@ public IncludedModuleWrapper newIncludeClass(RubyClass superClass) {
}

@Override
public void addMethod(String name, DynamicMethod method) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

public void setMethods(Map newMethods) {
public void addMethod(String id, DynamicMethod method) {
throw new UnsupportedOperationException("An included class is only a wrapper for a module");
}

@@ -209,20 +208,34 @@ protected IRubyObject getAutoloadConstant(String name, boolean forceLoad) {
}

@Override
protected DynamicMethod searchMethodCommon(String name) {
protected DynamicMethod searchMethodCommon(String id) {
// IncludedModuleWrapper needs to search prepended modules too, so search until we find methodLocation
RubyModule module = origin;
RubyModule methodLoc = origin.getMethodLocation();

for (; module != methodLoc; module = module.getSuperClass()) {
DynamicMethod method = module.getMethods().get(name);
DynamicMethod method = module.getMethods().get(id);
if (method != null) return method.isNull() ? null : method;
}

// one last search for method location
DynamicMethod method = module.getMethods().get(name);
DynamicMethod method = module.getMethods().get(id);
if (method != null) return method.isNull() ? null : method;

return null;
}

@Override
protected void addMethodSymbols(Ruby runtime, Set<String> seen, RubyArray ary, boolean not, Visibility visibility) {
// IncludedModuleWrapper needs to search prepended modules too, so search until we find methodLocation
RubyModule module = origin;
RubyModule methodLoc = origin.getMethodLocation();

for (; module != methodLoc; module = module.getSuperClass()) {
module.addMethodSymbols(runtime, seen, ary, not, visibility);
}

// one last add for method location
module.addMethodSymbols(runtime, seen, ary, not, visibility);
}
}
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/JarBootstrapMain.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
20 changes: 12 additions & 8 deletions core/src/main/java/org/jruby/Main.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -35,11 +35,13 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jruby.exceptions.MainExitException;
import org.jruby.exceptions.JumpException;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.SignalException;
import org.jruby.exceptions.ThreadKill;
import org.jruby.main.DripMain;
import org.jruby.platform.Platform;
@@ -354,11 +356,7 @@ private Status handleOutOfMemory(OutOfMemoryError ex) {
boolean heapError = false;

if (oomeMessage != null) {
if (oomeMessage.contains("PermGen")) {
// report permgen memory error
config.getError().println("Error: Your application exhausted PermGen area of the heap.");
config.getError().println("Specify -J-XX:MaxPermSize=###M to increase it (### = PermGen size in MB).");
} else if (oomeMessage.contains("unable to create new native thread")) {
if (oomeMessage.contains("unable to create new native thread")) {
// report thread exhaustion error
config.getError().println("Error: Your application demanded too many live threads, perhaps for Fiber or Enumerator.");
config.getError().println("Ensure your old Fibers and Enumerators are being cleaned up.");
@@ -533,6 +531,12 @@ protected static int handleRaiseException(final RaiseException ex) {
return RubyNumeric.fix2int(status);
}
return 0;
} else if ( runtime.getSignalException().isInstance(raisedException) ) {
IRubyObject status = raisedException.callMethod(runtime.getCurrentContext(), "signo");
if (status != null && ! status.isNil()) {
return RubyNumeric.fix2int(status) + 128;
}
return 0;
}
System.err.print(runtime.getInstanceConfig().getTraceType().printBacktrace(raisedException, runtime.getPosix().isatty(FileDescriptor.err)));
return 1;
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/MetaClass.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -27,6 +27,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jruby.runtime.builtin.IRubyObject;
46 changes: 32 additions & 14 deletions core/src/main/java/org/jruby/NativeException.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -25,16 +25,22 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.lang.reflect.Member;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import org.jruby.javasupport.Java;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.builtin.IRubyObject;

@Deprecated
@JRubyClass(name = "NativeException", parent = "RuntimeError")
public class NativeException extends RubyException {

@@ -43,40 +49,52 @@ public class NativeException extends RubyException {
public static final String CLASS_NAME = "NativeException";

public NativeException(Ruby runtime, RubyClass rubyClass, Throwable cause) {
super(runtime, rubyClass);
this(runtime, rubyClass, cause, buildMessage(cause));
}

private NativeException(Ruby runtime, RubyClass rubyClass, Throwable cause, String message) {
super(runtime, rubyClass, message);
this.cause = cause;
this.messageAsJavaString = cause.getClass().getName() + ": " + searchStackMessage(cause);
String s = buildMessage(cause);
this.messageAsJavaString = message;
}


private static String buildMessage(Throwable cause) {
return cause.getClass().getName() + ": " + searchStackMessage(cause);
}

private NativeException(Ruby runtime, RubyClass rubyClass) {
super(runtime, rubyClass, null);
this.cause = new Throwable();
this.messageAsJavaString = null;
}

private static ObjectAllocator NATIVE_EXCEPTION_ALLOCATOR = new ObjectAllocator() {
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
NativeException instance = new NativeException(runtime, klazz);
instance.setMetaClass(klazz);
return instance;
}
};
private static ObjectAllocator NATIVE_EXCEPTION_ALLOCATOR = (runtime, klazz) -> new NativeException(runtime, klazz);

public static RubyClass createClass(Ruby runtime, RubyClass baseClass) {
RubyClass exceptionClass = runtime.defineClass(CLASS_NAME, baseClass, NATIVE_EXCEPTION_ALLOCATOR);
runtime.getObject().deprecateConstant(runtime, CLASS_NAME);

exceptionClass.defineAnnotatedMethods(NativeException.class);

return exceptionClass;
}

@Override
public void prepareBacktrace(ThreadContext context) {
// if it's null, use cause's trace to build a raw stack trace
if (backtraceData == null) {
backtraceData = TraceType.Gather.RAW.getBacktraceData(getRuntime().getCurrentContext(), cause.getStackTrace());
}
}

@JRubyMethod
public final IRubyObject cause() {
return Java.getInstance(getRuntime(), getCause());
}

@Deprecated
public IRubyObject cause(Block unusedBlock) {
public final IRubyObject cause(Block unusedBlock) {
return cause();
}

1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/ObjectFlags.java
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ public interface ObjectFlags {
int NEEDSIMPL_F = registry.newFlag(RubyModule.class);
int REFINED_MODULE_F = registry.newFlag(RubyModule.class);
int IS_OVERLAID_F = registry.newFlag(RubyModule.class);
int OMOD_SHARED = registry.newFlag(RubyModule.class);

int CR_7BIT_F = registry.newFlag(RubyString.class);
int CR_VALID_F = registry.newFlag(RubyString.class);
15 changes: 11 additions & 4 deletions core/src/main/java/org/jruby/PrependedModule.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -26,6 +26,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.util.Map;
@@ -44,7 +45,7 @@ public class PrependedModule extends IncludedModule {
public PrependedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
super(runtime, superClass, origin);
methods = origin.methods;
origin.methods = new ConcurrentHashMap<String, DynamicMethod>(0, 0.9f, 1);
origin.methods = new ConcurrentHashMap<>(0, 0.9f, 1);
origin.methodLocation = this;
for (Map.Entry<String, DynamicMethod> entry : methods.entrySet()) {
DynamicMethod method = entry.getValue();
@@ -53,6 +54,12 @@ public PrependedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
}
}

@Override
public void addMethod(String id, DynamicMethod method) {
super.addMethod(id, method);
method.setDefinedClass(origin);
}

@Override
public boolean isPrepended() {
return true;
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/Profile.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -25,6 +25,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

/**
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/ReifiedRubyObject.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -24,6 +24,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

/**
665 changes: 416 additions & 249 deletions core/src/main/java/org/jruby/Ruby.java

Large diffs are not rendered by default.

47 changes: 38 additions & 9 deletions core/src/main/java/org/jruby/RubyArgsFile.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -30,6 +30,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.io.File;
@@ -46,7 +47,9 @@
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.GlobalVariable;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.IAccessor;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -444,14 +447,36 @@ public static IRubyObject each_charCommon(ThreadContext context, IRubyObject rec
return recv;
}

@JRubyMethod
public static IRubyObject each_codepoint(ThreadContext context, IRubyObject recv, Block block) {
if (!block.isGiven()) return RubyEnumerator.enumeratorize(context.runtime, recv, "each_line");
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

CallSite each_codepoint = sites(context).each_codepoint;
while (data.next_argv(context)) {
each_codepoint.call(context, recv, data.currentFile, block);
}

return context.nil;
}

@JRubyMethod
public static IRubyObject codepoints(ThreadContext context, IRubyObject recv, Block block) {
context.runtime.getWarnings().warn("ARGF#codepoints is deprecated; use #each_codepoint instead");

if (!block.isGiven()) return RubyEnumerator.enumeratorize(context.runtime, recv, "each_line");

return each_codepoint(context, recv, block);
}

/** Invoke a block for each line.
*
*/
public static IRubyObject each_line(ThreadContext context, IRubyObject recv, IRubyObject[] args, Block block) {
if (!block.isGiven()) return RubyEnumerator.enumeratorize(context.runtime, recv, "each_line");
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

if (!data.next_argv(context)) return context.runtime.getNil();
if (!data.next_argv(context)) return context.nil;

if (!(data.currentFile instanceof RubyIO)) {
if (!data.next_argv(context)) return recv;
@@ -506,7 +531,7 @@ public static IRubyObject skip(IRubyObject recv) {

public static void argf_close(ThreadContext context, IRubyObject file) {
if(file instanceof RubyIO) {
((RubyIO)file).rbIoClose(context.runtime);
((RubyIO) file).rbIoClose(context);
} else {
file.callMethod(context, "close");
}
@@ -590,7 +615,7 @@ public static IRubyObject rewind(ThreadContext context, IRubyObject recv) {
public static IRubyObject eof(ThreadContext context, IRubyObject recv) {
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

if (!data.inited) return context.runtime.getTrue();
if (!data.inited) return context.tru;

if (!(data.currentFile instanceof RubyIO)) {
return data.currentFile.callMethod(context, "eof");
@@ -603,7 +628,7 @@ public static IRubyObject eof(ThreadContext context, IRubyObject recv) {
public static IRubyObject eof_p(ThreadContext context, IRubyObject recv) {
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

if (!data.inited) return context.runtime.getTrue();
if (!data.inited) return context.tru;

if (!(data.currentFile instanceof RubyIO)) {
return data.currentFile.callMethod(context, "eof?");
@@ -636,7 +661,7 @@ public static IRubyObject getbyte(ThreadContext context, IRubyObject recv) {
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

while(true) {
if (!data.next_argv(context)) return context.runtime.getNil();
if (!data.next_argv(context)) return context.nil;

IRubyObject bt;
if (!(data.currentFile instanceof RubyFile)) {
@@ -718,7 +743,7 @@ public static IRubyObject getc(ThreadContext context, IRubyObject recv) {
ArgsFileData data = ArgsFileData.getArgsFileData(context.runtime);

while(true) {
if (!data.next_argv(context)) return context.runtime.getNil();
if (!data.next_argv(context)) return context.nil;

IRubyObject bt;
if (!(data.currentFile instanceof RubyFile)) {
@@ -809,4 +834,8 @@ private static RubyIO getCurrentDataFile(ThreadContext context, String errorMess

return (RubyIO) data.currentFile;
}

private static JavaSites.ArgfSites sites(ThreadContext context) {
return context.sites.Argf;
}
}
58 changes: 58 additions & 0 deletions core/src/main/java/org/jruby/RubyArgumentError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jruby.anno.JRubyClass;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.ArgumentError;

/**
* The Java representation of a Ruby ArgumentError.
*
* @see ArgumentError
*/
@JRubyClass(name="ArgumentError", parent="StandardError")
public class RubyArgumentError extends RubyStandardError {
protected RubyArgumentError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

protected RubyArgumentError(Ruby runtime, RubyClass exceptionClass, String message) {
super(runtime, exceptionClass, message);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass) {
RubyClass argumentErrorClass = runtime.defineClass("ArgumentError", exceptionClass, (r, klass) -> new RubyArgumentError(runtime, klass));

return argumentErrorClass;
}

@Override
protected RaiseException constructThrowable(String message) {
return new ArgumentError(message, this);
}
}
1,043 changes: 723 additions & 320 deletions core/src/main/java/org/jruby/RubyArray.java

Large diffs are not rendered by default.

508 changes: 303 additions & 205 deletions core/src/main/java/org/jruby/RubyBasicObject.java

Large diffs are not rendered by default.

805 changes: 555 additions & 250 deletions core/src/main/java/org/jruby/RubyBignum.java

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/RubyBinding.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -31,6 +31,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.util.HashSet;
52 changes: 32 additions & 20 deletions core/src/main/java/org/jruby/RubyBoolean.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -30,8 +30,10 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.compiler.Constantizable;
@@ -41,6 +43,7 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.marshal.MarshalStream;
import org.jruby.runtime.opto.OptoFactory;
import org.jruby.util.ByteList;

/**
*
@@ -129,7 +132,9 @@ public static RubyClass createTrueClass(Ruby runtime) {
public static RubyBoolean newBoolean(Ruby runtime, boolean value) {
return value ? runtime.getTrue() : runtime.getFalse();
}


static final ByteList FALSE_BYTES = new ByteList(new byte[] { 'f','a','l','s','e' }, USASCIIEncoding.INSTANCE);

public static class False extends RubyBoolean {
False(Ruby runtime) {
super(runtime,
@@ -154,11 +159,21 @@ public static IRubyObject false_xor(IRubyObject f, IRubyObject oth) {
}

@JRubyMethod(name = "to_s", alias = "inspect")
public static IRubyObject false_to_s(IRubyObject f) {
return RubyString.newUSASCIIString(f.getRuntime(), "false");
public static RubyString false_to_s(IRubyObject f) {
return RubyString.newStringShared(f.getRuntime(), FALSE_BYTES);
}

@Override
public <T> T toJava(Class<T> target) {
if (target.isAssignableFrom(Boolean.class) || target == boolean.class) {
return (T) Boolean.FALSE;
}
return super.toJava(target);
}
}


static final ByteList TRUE_BYTES = new ByteList(new byte[] { 't','r','u','e' }, USASCIIEncoding.INSTANCE);

public static class True extends RubyBoolean {
True(Ruby runtime) {
super(runtime,
@@ -183,8 +198,16 @@ public static IRubyObject true_xor(IRubyObject t, IRubyObject oth) {
}

@JRubyMethod(name = "to_s", alias = "inspect")
public static IRubyObject true_to_s(IRubyObject t) {
return RubyString.newUSASCIIString(t.getRuntime(), "true");
public static RubyString true_to_s(IRubyObject t) {
return RubyString.newStringShared(t.getRuntime(), TRUE_BYTES);
}

@Override
public <T> T toJava(Class<T> target) {
if (target.isAssignableFrom(Boolean.class) || target == boolean.class) {
return (T) Boolean.TRUE;
}
return super.toJava(target);
}
}

@@ -215,16 +238,5 @@ public IRubyObject taint(ThreadContext context) {
public void marshalTo(MarshalStream output) throws java.io.IOException {
output.write(isTrue() ? 'T' : 'F');
}

@Override
public Object toJava(Class target) {
if (target.isAssignableFrom(Boolean.class) || target.equals(boolean.class)) {
if (isFalse()) return Boolean.FALSE;

return Boolean.TRUE;
} else {
return super.toJava(target);
}
}
}

171 changes: 92 additions & 79 deletions core/src/main/java/org/jruby/RubyClass.java

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/RubyClassPathVariable.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -25,6 +25,7 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import java.io.File;
46 changes: 37 additions & 9 deletions core/src/main/java/org/jruby/RubyComparable.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
* Version: EPL 2.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* License Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
* the License at http://www.eclipse.org/legal/epl-v20.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -31,19 +31,17 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/

package org.jruby;

import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyModule;
import org.jruby.runtime.CallSite;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.JavaSites.ComparableSites;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.RespondToCallSite;

import static org.jruby.runtime.Helpers.invokedynamic;
import static org.jruby.runtime.invokedynamic.MethodNames.OP_CMP;

/** Implementation of the Comparable module.
*
@@ -86,7 +84,6 @@ public static int cmpint(ThreadContext context, CallSite op_gt, CallSite op_lt,

RubyFixnum zero = RubyFixnum.zero(context.runtime);

ComparableSites sites = sites(context);
if (op_gt.call(context, val, val, zero).isTrue()) return 1;
if (op_lt.call(context, val, val, zero).isTrue()) return -1;

@@ -98,6 +95,16 @@ public static int cmpint(ThreadContext context, IRubyObject val, IRubyObject a,
return cmpint(context, sites.op_gt, sites.op_lt, val, a, b);
}

public static int cmpAndCmpint(ThreadContext context, IRubyObject a, IRubyObject b) {
IRubyObject cmpResult = sites(context).op_cmp.call(context, a, a, b);
return cmpint(context, cmpResult, a, b);
}

public static int cmpAndCmpint(ThreadContext context, CallSite op_cmp, CallSite op_gt, CallSite op_lt, IRubyObject a, IRubyObject b) {
IRubyObject cmpResult = op_cmp.call(context, a, a, b);
return cmpint(context, op_gt, op_lt, cmpResult, a, b);
}

/** rb_cmperr
*
*/
@@ -122,7 +129,7 @@ public static IRubyObject invcmp(final ThreadContext context, final IRubyObject
private static final ThreadContext.RecursiveFunctionEx DEFAULT_INVCMP = new ThreadContext.RecursiveFunctionEx<IRubyObject>() {
@Override
public IRubyObject call(ThreadContext context, IRubyObject recv, IRubyObject other, boolean recur) {
if (recur || !sites(context).respond_to_op_cmp.respondsTo(context, other, other)) return context.runtime.getNil();
if (recur || !sites(context).respond_to_op_cmp.respondsTo(context, other, other)) return context.nil;
return sites(context).op_cmp.call(context, other, other, recv);
}
};
@@ -147,7 +154,7 @@ public static IRubyObject invcmp(final ThreadContext context, ThreadContext.Recu
*/
@JRubyMethod(name = "==", required = 1)
public static IRubyObject op_equal(ThreadContext context, IRubyObject recv, IRubyObject other) {
return callCmpMethod(context, recv, other, context.runtime.getFalse());
return callCmpMethod(context, recv, other, context.fals);
}

@Deprecated
@@ -233,6 +240,27 @@ public static RubyBoolean between_p(ThreadContext context, IRubyObject recv, IRu
return context.runtime.newBoolean(op_lt(context, recv, first).isFalse() && op_gt(context, recv, second).isFalse());
}

@JRubyMethod(name = "clamp")
public static IRubyObject clamp(ThreadContext context, IRubyObject recv, IRubyObject min, IRubyObject max) {
int c;

ComparableSites sites = sites(context);
CallSite op_gt = sites.op_gt;
CallSite op_lt = sites.op_lt;
CallSite op_cmp = sites.op_cmp;

if (cmpAndCmpint(context, op_cmp, op_gt, op_lt, min, max) > 0) {
throw context.runtime.newArgumentError("min argument must be smaller than max argument");
}

c = cmpAndCmpint(context, op_cmp, op_gt, op_lt, recv, min);
if (c == 0) return recv;
if (c < 0) return min;
c = cmpAndCmpint(context, op_cmp, op_gt, op_lt, recv, max);
if (c > 0) return max;
return recv;
}

private static ComparableSites sites(ThreadContext context) {
return context.sites.Comparable;
}
Loading

0 comments on commit 39a76a3

Please sign in to comment.