Skip to content

Commit

Permalink
Merge branch 'master' into psych_3_update
Browse files Browse the repository at this point in the history
headius committed Apr 27, 2018
2 parents 7390d5a + f848082 commit f02bf17
Showing 6,296 changed files with 108,530 additions and 58,349 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -52,8 +52,10 @@ lib/native
lib/ruby/cext/
lib/ruby/gems
lib/ruby/stdlib/*.jar
lib/ruby/stdlib/ant*
lib/ruby/stdlib/did_you_mean*
lib/ruby/stdlib/gauntlet_rdoc.rb
lib/ruby/stdlib/ipaddr*
lib/ruby/stdlib/jar*
lib/ruby/stdlib/jline
lib/ruby/stdlib/jopenssl*
30 changes: 16 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ language: java

sudo: false

dist: trusty

cache:
directories:
- $HOME/.m2
@@ -10,10 +12,8 @@ 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=160M"; else export MAVEN_OPTS="-XX:MaxMetaspaceSize=144M -XX:CompressedClassSpaceSize=96M"; fi
- export MAVEN_OPTS="-Xms64M -Xmx512M $MAVEN_OPTS"
- export JAVA_OPTS="$JAVA_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
@@ -24,7 +24,7 @@ before_script:
- echo $MAVEN_OPTS

jdk:
- openjdk7
- oraclejdk8

os:
- linux
@@ -36,7 +36,7 @@ env:
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'
@@ -56,22 +56,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
- env: PHASE='-Pj2ee'
jdk: oraclejdk8
- env: PHASE='-Prake -Dtask=test:mri'
- env: PHASE='-Pj2ee'
jdk: oraclejdk8
# These next two started crashing on JDK7 in March 2015, possibly due to JVM issues on Travis's Docker-based env
- env: PHASE='-Pjruby-jars,test -Dinvoker.test=extended'
jdk: oraclejdk8
- env: PHASE='-Pmain,test -Dinvoker.test=extended'
@@ -98,7 +99,8 @@ matrix:
- 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:
@@ -122,5 +124,5 @@ services:
addons:
apt:
packages:
- oracle-java9-installer
# - oracle-java9-installer
- haveged
53 changes: 26 additions & 27 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.

@@ -151,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:
@@ -182,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
@@ -193,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
@@ -202,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
@@ -214,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
@@ -237,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
6 changes: 3 additions & 3 deletions COPYING
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
JRuby is Copyright (c) 2007-2017 The JRuby project, and is released
JRuby is Copyright (c) 2007-2018 The JRuby project, and is released
under a tri EPL/GPL/LGPL license. You can use it, redistribute it
and/or modify it under the terms of the:

@@ -13,7 +13,7 @@ jnr-posix (https://github.com/jnr/jnr-posix),
jruby-openssl (https://github.com/jruby/jruby-openssl),
jruby-readline (https://github.com/jruby/jruby-readline),
psych (https://github.com/ruby/psych),
yydebug (http://svn.codehaus.org/jruby/trunk/jay/yydebug)
yydebug (https://github.com/jruby/jay-yydebug/)
are released under the same copyright/license.

Some additional libraries distributed with JRuby are not covered by
@@ -50,7 +50,7 @@ below. Also see LICENSE.RUBY for most files found in lib/ruby/stdlib.

Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.

The "rake" library (http://rake.rubyforge.org/) is distributed under
The "rake" library (https://github.com/ruby/rake) is distributed under
the MIT license, and has the following copyright:

Copyright (c) 2003, 2004 Jim Weirich
12 changes: 11 additions & 1 deletion 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
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.1.17.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
16 changes: 8 additions & 8 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 )
@@ -52,14 +51,13 @@
jar 'com.github.jnr:jffi:${jffi.version}'
jar 'com.github.jnr:jffi:${jffi.version}:native'

jar 'org.jruby.joni:joni:2.1.15'
jar 'org.jruby.joni:joni:2.1.16'
jar 'org.jruby.extras:bytelist:1.0.15'
jar 'org.jruby.jcodings:jcodings:1.0.27'
jar 'org.jruby.jcodings:jcodings:1.0.30'
jar 'org.jruby:dirgra:0.3'

jar 'com.headius:invokebinder:1.10'
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'
@@ -168,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',
@@ -185,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',
@@ -194,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',
@@ -225,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',
30 changes: 13 additions & 17 deletions core/pom.xml
Original file line number Diff line number Diff line change
@@ -12,22 +12,21 @@ DO NOT MODIFIY - GENERATED CODE
<parent>
<groupId>org.jruby</groupId>
<artifactId>jruby-parent</artifactId>
<version>9.1.17.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/install4j7/bin/install4jc</install4j.executable>
<jay.bin>jay</jay.bin>
@@ -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>
@@ -173,7 +172,7 @@ DO NOT MODIFIY - GENERATED CODE
<dependency>
<groupId>org.jruby.joni</groupId>
<artifactId>joni</artifactId>
<version>2.1.15</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.27</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.10</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>
@@ -484,6 +478,7 @@ DO NOT MODIFIY - GENERATED CODE
<goal>compile</goal>
</goals>
<configuration>
<debug>true</debug>
<annotationProcessors>
<annotationProcessor>org.jruby.anno.AnnotationBinder</annotationProcessor>
</annotationProcessors>
@@ -503,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>
@@ -539,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>
@@ -588,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>
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);
}
}
45 changes: 30 additions & 15 deletions core/src/main/java/org/jruby/AbstractRubyMethod.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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();
@@ -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());
}
}

10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/BasicObjectStub.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/Finalizable.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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();
15 changes: 6 additions & 9 deletions core/src/main/java/org/jruby/IncludedModuleWrapper.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* 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-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.util.Collection;
@@ -81,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");
}

@@ -211,18 +208,18 @@ 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;
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/JarBootstrapMain.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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
16 changes: 10 additions & 6 deletions core/src/main/java/org/jruby/Main.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* 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-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;
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/MetaClass.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;
42 changes: 30 additions & 12 deletions core/src/main/java/org/jruby/NativeException.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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();
}

9 changes: 5 additions & 4 deletions core/src/main/java/org/jruby/PrependedModule.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* 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-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();
@@ -54,8 +55,8 @@ public PrependedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
}

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

3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/Profile.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;

/**
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/ReifiedRubyObject.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* 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-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;

/**
523 changes: 340 additions & 183 deletions core/src/main/java/org/jruby/Ruby.java

Large diffs are not rendered by default.

43 changes: 36 additions & 7 deletions core/src/main/java/org/jruby/RubyArgsFile.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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,003 changes: 701 additions & 302 deletions core/src/main/java/org/jruby/RubyArray.java

Large diffs are not rendered by default.

484 changes: 294 additions & 190 deletions core/src/main/java/org/jruby/RubyBasicObject.java

Large diffs are not rendered by default.

797 changes: 551 additions & 246 deletions core/src/main/java/org/jruby/RubyBignum.java

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyBinding.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;
48 changes: 30 additions & 18 deletions core/src/main/java/org/jruby/RubyBoolean.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
* 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-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);
}
}
}

72 changes: 37 additions & 35 deletions core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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
@@ -28,6 +28,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.javasupport.JavaClass;
@@ -198,8 +199,9 @@ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
* constructor (Ruby, RubyClass) on the given class via a static
* __allocate__ method intermediate.
*
* @param clazz The class from which to grab a standard Ruby __allocate__
* method.
* @param clazz The class from which to grab a standard Ruby __allocate__ method.
*
* @note Used with `jrubyc --java` generated (interoperability) class files.
*/
public void setRubyStaticAllocator(final Class<?> clazz) {
try {
@@ -1229,7 +1231,7 @@ public final RubyClass getRealClass() {

@JRubyMethod(name = "inherited", required = 1, visibility = PRIVATE)
public IRubyObject inherited(ThreadContext context, IRubyObject arg) {
return runtime.getNil();
return context.nil;
}

/** rb_class_inherited (reversed semantics!)
@@ -1253,15 +1255,15 @@ public IRubyObject superclass(ThreadContext context) {
RubyClass superClazz = superClass;

if (superClazz == null) {
if (metaClass == runtime.getBasicObject().getMetaClass()) return runtime.getNil();
if (metaClass == runtime.getBasicObject().getMetaClass()) return context.nil;
throw runtime.newTypeError("uninitialized class");
}

while (superClazz != null && (superClazz.isIncluded() || superClazz.isPrepended())) {
superClazz = superClazz.superClass;
}

return superClazz != null ? superClazz : runtime.getNil();
return superClazz != null ? superClazz : context.nil;
}

private void checkNotInitialized() {
@@ -1555,19 +1557,19 @@ byte[] reify(final String javaName, final String javaPath) {
final Set<String> instanceMethods = new HashSet<String>(getMethods().size());

// define instance methods
for (Map.Entry<String,DynamicMethod> methodEntry : getMethods().entrySet()) {
final String methodName = methodEntry.getKey();
for (Map.Entry<String, DynamicMethod> methodEntry : getMethods().entrySet()) {
final String id = methodEntry.getKey();

if ( ! JavaNameMangler.willMethodMangleOk(methodName) ) {
LOG.debug("{} method: '{}' won't be part of reified Java class", getName(), methodName);
if (!JavaNameMangler.willMethodMangleOk(id)) {
LOG.debug("{} method: '{}' won't be part of reified Java class", getName(), id);
continue;
}

String javaMethodName = JavaNameMangler.mangleMethodName(methodName);
String javaMethodName = JavaNameMangler.mangleMethodName(id);

Map<Class,Map<String,Object>> methodAnnos = getMethodAnnotations().get(methodName);
List<Map<Class,Map<String,Object>>> parameterAnnos = getParameterAnnotations().get(methodName);
Class[] methodSignature = getMethodSignatures().get(methodName);
Map<Class,Map<String,Object>> methodAnnos = getMethodAnnotations().get(id);
List<Map<Class,Map<String,Object>>> parameterAnnos = getParameterAnnotations().get(id);
Class[] methodSignature = getMethodSignatures().get(id);

final String signature;
if (methodSignature == null) { // non-signature signature with just IRubyObject
@@ -1579,7 +1581,7 @@ byte[] reify(final String javaName, final String javaPath) {
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.aload(0);
m.ldc(methodName);
m.ldc(id);
m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class));
break;
case 1:
@@ -1588,7 +1590,7 @@ byte[] reify(final String javaName, final String javaPath) {
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.aload(0);
m.ldc(methodName);
m.ldc(id);
m.aload(1); // IRubyObject arg1
m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class, IRubyObject.class));
break;
@@ -1606,7 +1608,7 @@ byte[] reify(final String javaName, final String javaPath) {
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.aload(0);
m.ldc(methodName);
m.ldc(id);

// generate an IRubyObject[] for the method arguments :
m.pushInt(paramCount);
@@ -1625,7 +1627,7 @@ byte[] reify(final String javaName, final String javaPath) {
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.aload(0);
m.ldc(methodName);
m.ldc(id);
m.aload(1); // IRubyObject[] arg1
}
m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));
@@ -1642,39 +1644,39 @@ byte[] reify(final String javaName, final String javaPath) {

signature = sig(methodSignature[0], params);
int mod = ACC_PUBLIC;
if ( isVarArgsSignature(methodName, methodSignature) ) mod |= ACC_VARARGS;
if ( isVarArgsSignature(id, methodSignature) ) mod |= ACC_VARARGS;
m = new SkinnyMethodAdapter(cw, mod, javaMethodName, signature, null, null);
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.getstatic(javaPath, "ruby", ci(Ruby.class));
m.astore(rubyIndex);

m.aload(0); // self
m.ldc(methodName); // method name
m.ldc(id); // method name
RealClassGenerator.coerceArgumentsToRuby(m, params, rubyIndex);
m.invokevirtual(javaPath, "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));

RealClassGenerator.coerceResultAndReturn(m, methodSignature[0]);
}

if (DEBUG_REIFY) LOG.debug("defining {}#{} as {}#{}", getName(), methodName, javaName, javaMethodName + signature);
if (DEBUG_REIFY) LOG.debug("defining {}#{} as {}#{}", getName(), id, javaName, javaMethodName + signature);

instanceMethods.add(javaMethodName + signature);

m.end();
}

// define class/static methods
for (Map.Entry<String,DynamicMethod> methodEntry : getMetaClass().getMethods().entrySet()) {
String methodName = methodEntry.getKey();
for (Map.Entry<String, DynamicMethod> methodEntry : getMetaClass().getMethods().entrySet()) {
String id = methodEntry.getKey();

if (!JavaNameMangler.willMethodMangleOk(methodName)) continue;
if (!JavaNameMangler.willMethodMangleOk(id)) continue;

String javaMethodName = JavaNameMangler.mangleMethodName(methodName);
String javaMethodName = JavaNameMangler.mangleMethodName(id);

Map<Class,Map<String,Object>> methodAnnos = getMetaClass().getMethodAnnotations().get(methodName);
List<Map<Class,Map<String,Object>>> parameterAnnos = getMetaClass().getParameterAnnotations().get(methodName);
Class[] methodSignature = getMetaClass().getMethodSignatures().get(methodName);
Map<Class,Map<String,Object>> methodAnnos = getMetaClass().getMethodAnnotations().get(id);
List<Map<Class,Map<String,Object>>> parameterAnnos = getMetaClass().getParameterAnnotations().get(id);
Class[] methodSignature = getMetaClass().getMethodSignatures().get(id);

String signature;
if (methodSignature == null) {
@@ -1689,7 +1691,7 @@ byte[] reify(final String javaName, final String javaPath) {

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
//m.invokevirtual("org/jruby/RubyClass", "getMetaClass", sig(RubyClass.class) );
m.ldc(methodName);
m.ldc(id);
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class) );
break;
default:
@@ -1699,7 +1701,7 @@ byte[] reify(final String javaName, final String javaPath) {
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
m.ldc(methodName);
m.ldc(id);
m.aload(0);
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class) );
}
@@ -1723,14 +1725,14 @@ byte[] reify(final String javaName, final String javaPath) {

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));

m.ldc(methodName); // method name
m.ldc(id); // method name
RealClassGenerator.coerceArgumentsToRuby(m, params, rubyIndex);
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));

RealClassGenerator.coerceResultAndReturn(m, methodSignature[0]);
}

if (DEBUG_REIFY) LOG.debug("defining {}.{} as {}.{}", getName(), methodName, javaName, javaMethodName + signature);
if (DEBUG_REIFY) LOG.debug("defining {}.{} as {}.{}", getName(), id, javaName, javaMethodName + signature);

m.end();
}
@@ -1887,7 +1889,7 @@ public synchronized void addClassAnnotation(Class annotation, Map fields) {
}

@Override
public Object toJava(final Class target) {
public <T> T toJava(Class<T> target) {
if (target == Class.class) {
if (reifiedClass == null) reifyWithAncestors(); // possibly auto-reify
// Class requested; try java_class or else return nearest reified class
@@ -1896,13 +1898,13 @@ public Object toJava(final Class target) {
if ( ! javaClass.isNil() ) return javaClass.toJava(target);

Class reifiedClass = nearestReifiedClass(this);
if ( reifiedClass != null ) return reifiedClass;
if ( reifiedClass != null ) return target.cast(reifiedClass);
// should never fall through, since RubyObject has a reified class
}

if (target.isAssignableFrom(RubyClass.class)) {
// they're asking for something RubyClass extends, give them that
return this;
return target.cast(this);
}

return defaultToJava(target);
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyClassPathVariable.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;
42 changes: 35 additions & 7 deletions core/src/main/java/org/jruby/RubyComparable.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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;
}
432 changes: 245 additions & 187 deletions core/src/main/java/org/jruby/RubyComplex.java

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions core/src/main/java/org/jruby/RubyConcurrencyError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***** 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.ConcurrencyError;

/**
* The Java representation of a Ruby ConcurrencyError.
*
* @see ConcurrencyError
*/
@JRubyClass(name="ConcurrencyError", parent="ThreadError")
public class RubyConcurrencyError extends RubyThreadError {
protected RubyConcurrencyError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass) {
RubyClass concurrencyErrorClass = runtime.defineClass("ConcurrencyError", exceptionClass, (r, klass) -> new RubyConcurrencyError(runtime, klass));

return concurrencyErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new ConcurrencyError(message, this);
}
}
5 changes: 3 additions & 2 deletions core/src/main/java/org/jruby/RubyContinuation.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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 org.jruby.anno.JRubyMethod;
@@ -108,7 +109,7 @@ public IRubyObject enter(ThreadContext context, IRubyObject yielded, Block block
} catch (Continuation c) {
if (c == continuation) {
if (continuation.args.length == 0) {
return context.runtime.getNil();
return context.nil;
} else if (continuation.args.length == 1) {
return continuation.args[0];
} else {
22 changes: 18 additions & 4 deletions core/src/main/java/org/jruby/RubyConverter.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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
@@ -23,11 +23,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.jcodings.Encoding;
import org.jcodings.EncodingDB;
import org.jcodings.Ptr;
import org.jcodings.specific.ISO8859_1Encoding;
import org.jcodings.specific.UTF16BEEncoding;
import org.jcodings.specific.UTF16LEEncoding;
import org.jcodings.specific.UTF32BEEncoding;
@@ -95,13 +97,25 @@ public class RubyConverter extends RubyObject {
NONASCII_TO_ASCII.put(UTF16LEEncoding.INSTANCE, UTF8Encoding.INSTANCE);
NONASCII_TO_ASCII.put(UTF32BEEncoding.INSTANCE, UTF8Encoding.INSTANCE);
NONASCII_TO_ASCII.put(UTF32LEEncoding.INSTANCE, UTF8Encoding.INSTANCE);
NONASCII_TO_ASCII.put(
EncodingDB.getEncodings().get("CP50220".getBytes()).getEncoding(),
EncodingDB.getEncodings().get("CP51932".getBytes()).getEncoding());
NONASCII_TO_ASCII.put(
EncodingDB.getEncodings().get("CP50221".getBytes()).getEncoding(),
EncodingDB.getEncodings().get("CP51932".getBytes()).getEncoding());
NONASCII_TO_ASCII.put(EncodingDB.getEncodings().get("IBM037".getBytes()).getEncoding(), ISO8859_1Encoding.INSTANCE);
NONASCII_TO_ASCII.put(EncodingDB.getEncodings().get("UTF-16".getBytes()).getEncoding(), UTF8Encoding.INSTANCE);
NONASCII_TO_ASCII.put(EncodingDB.getEncodings().get("UTF-32".getBytes()).getEncoding(), UTF8Encoding.INSTANCE);
NONASCII_TO_ASCII.put(
EncodingDB.getEncodings().get("ISO-2022-JP".getBytes()).getEncoding(),
EncodingDB.getEncodings().get("stateless-ISO-2022-JP".getBytes()).getEncoding());
NONASCII_TO_ASCII.put(
EncodingDB.getEncodings().get("ISO-2022-JP-KDDI".getBytes()).getEncoding(),
EncodingDB.getEncodings().get("stateless-ISO-2022-JP-KDDI".getBytes()).getEncoding());
}

public static RubyClass createConverterClass(Ruby runtime) {
RubyClass converterc = runtime.defineClassUnder("Converter", runtime.getClass("Data"), CONVERTER_ALLOCATOR, runtime.getEncoding());
RubyClass converterc = runtime.defineClassUnder("Converter", runtime.getData(), CONVERTER_ALLOCATOR, runtime.getEncoding());
runtime.setConverter(converterc);
converterc.setClassIndex(ClassIndex.CONVERTER);
converterc.setReifiedClass(RubyConverter.class);
@@ -366,7 +380,7 @@ public IRubyObject convert(ThreadContext context, IRubyObject srcBuffer) {

if (ret instanceof RubySymbol) {
RubySymbol retSym = (RubySymbol)ret;
String retStr = retSym.toString();
String retStr = retSym.asJavaString(); // 7bit comparison

if (retStr.equals(EConvResult.InvalidByteSequence.symbolicName()) ||
retStr.equals(EConvResult.UndefinedConversion.symbolicName()) ||
@@ -405,7 +419,7 @@ public IRubyObject finish(ThreadContext context) {

if (ret instanceof RubySymbol) {
RubySymbol retSym = (RubySymbol)ret;
String retStr = retSym.toString();
String retStr = retSym.asJavaString(); // 7 bit comparison

if (retStr.equals(EConvResult.InvalidByteSequence.symbolicName()) ||
retStr.equals(EConvResult.UndefinedConversion.symbolicName()) ||
261 changes: 221 additions & 40 deletions core/src/main/java/org/jruby/RubyDir.java

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions core/src/main/java/org/jruby/RubyDomainError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/***** 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.DomainError;
import org.jruby.exceptions.RaiseException;

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

static RubyClass define(Ruby runtime, RubyClass superClass, RubyModule under) {
return under.defineClassUnder("DomainError", superClass, (runtime1, klass) -> new RubyDomainError(runtime1, klass));
}

@Override
protected RaiseException constructThrowable(String message) {
return new DomainError(message, this);
}

}
53 changes: 53 additions & 0 deletions core/src/main/java/org/jruby/RubyEOFError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***** 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.EOFError;
import org.jruby.exceptions.RaiseException;

/**
* The Java representation of a Ruby EOFError.
*
* @see EOFError
*/
@JRubyClass(name="EOFError", parent="IOError")
public class RubyEOFError extends RubyIOError {
protected RubyEOFError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass) {
RubyClass eofErrorClass = runtime.defineClass("EOFError", exceptionClass, (r, klass) -> new RubyEOFError(runtime, klass));

return eofErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new EOFError(message, this);
}
}
26 changes: 15 additions & 11 deletions core/src/main/java/org/jruby/RubyEncoding.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* 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-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
@@ -23,10 +23,12 @@
* 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.ref.SoftReference;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
@@ -280,14 +282,15 @@ public final byte[] encode(CharSequence cs) {
if (cs.length() > CHAR_THRESHOLD) {
buffer = UTF8.encode(CharBuffer.wrap(cs));
} else {
buffer = byteBuffer;
Buffer buf = buffer = byteBuffer;
CharBuffer cbuffer = charBuffer;
buffer.clear();
cbuffer.clear();
Buffer cbuf = cbuffer;
buf.clear();
cbuf.clear();
cbuffer.put(cs.toString());
cbuffer.flip();
cbuf.flip();
encoder.encode(cbuffer, buffer, true);
buffer.flip();
buf.flip();
}

byte[] bytes = new byte[buffer.limit()];
@@ -300,14 +303,15 @@ public final String decode(byte[] bytes, int start, int length) {
if (length > CHAR_THRESHOLD) {
cbuffer = UTF8.decode(ByteBuffer.wrap(bytes, start, length));
} else {
cbuffer = charBuffer;
Buffer cbuf = cbuffer = charBuffer;
ByteBuffer buffer = byteBuffer;
cbuffer.clear();
buffer.clear();
Buffer buf = buffer;
cbuf.clear();
buf.clear();
buffer.put(bytes, start, length);
buffer.flip();
buf.flip();
decoder.decode(buffer, cbuffer, true);
cbuffer.flip();
cbuf.flip();
}

return cbuffer.toString();
125 changes: 125 additions & 0 deletions core/src/main/java/org/jruby/RubyEncodingError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/***** 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.EncodingError;

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

static RubyClass define(Ruby runtime, RubyClass exceptionClass) {
RubyClass encodingErrorClass = runtime.defineClass("EncodingError", exceptionClass, (r, klass) -> new RubyEncodingError(runtime, klass));

return encodingErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new EncodingError(message, this);
}

@JRubyClass(name="CompatibilityError", parent="EncodingError")
public static class RubyCompatibilityError extends RubyEncodingError {
protected RubyCompatibilityError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass, RubyModule under) {
return under.defineClassUnder("CompatibilityError", exceptionClass, (r, klass) -> new RubyCompatibilityError(runtime, klass));
}

protected RaiseException constructThrowable(String message) {
return new EncodingError.CompatibilityError(message, this);
}
}

@JRubyClass(name="InvalidByteSequenceError", parent="EncodingError")
public static class RubyInvalidByteSequenceError extends RubyEncodingError {
protected RubyInvalidByteSequenceError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass, RubyModule under) {
RubyClass invalidByteSequenceErrorClass = under.defineClassUnder("InvalidByteSequenceError", exceptionClass, (r, klass) -> new RubyInvalidByteSequenceError(runtime, klass));

invalidByteSequenceErrorClass.defineAnnotatedMethods(RubyConverter.EncodingErrorMethods.class);
invalidByteSequenceErrorClass.defineAnnotatedMethods(RubyConverter.InvalidByteSequenceErrorMethods.class);

return invalidByteSequenceErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new EncodingError.InvalidByteSequenceError(message, this);
}
}

@JRubyClass(name="UndefinedConversionError", parent="EncodingError")
public static class RubyUndefinedConversionError extends RubyEncodingError {
protected RubyUndefinedConversionError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass, RubyModule under) {
RubyClass undefinedConversionErrorClass = under.defineClassUnder("UndefinedConversionError", exceptionClass, (r, klass) -> new RubyUndefinedConversionError(runtime, klass));

undefinedConversionErrorClass.defineAnnotatedMethods(RubyConverter.EncodingErrorMethods.class);
undefinedConversionErrorClass.defineAnnotatedMethods(RubyConverter.UndefinedConversionErrorMethods.class);

return undefinedConversionErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new EncodingError.UndefinedConversionError(message, this);
}
}

@JRubyClass(name="ConverterNotFoundError", parent="EncodingError")
public static class RubyConverterNotFoundError extends RubyEncodingError {
protected RubyConverterNotFoundError(Ruby runtime, RubyClass exceptionClass) {
super(runtime, exceptionClass);
}

static RubyClass define(Ruby runtime, RubyClass exceptionClass, RubyModule under) {
RubyClass converterNotFoundErrorClass = under.defineClassUnder("ConverterNotFoundError", exceptionClass, (r, klass) -> new RubyConverterNotFoundError(runtime, klass));

return converterNotFoundErrorClass;
}

protected RaiseException constructThrowable(String message) {
return new EncodingError.ConverterNotFoundError(message, this);
}
}
}
Loading

0 comments on commit f02bf17

Please sign in to comment.