-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into truffle-head
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
Showing
42 changed files
with
3,900 additions
and
3,285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
java7: {name: oraclejdk, version: "8u66", platformspecific: true} | ||
|
||
common: { | ||
packages: { | ||
git : ">=1.8.3" | ||
maven : ">=3.3.9" | ||
ruby : ">=2.1.0" | ||
} | ||
|
||
downloads: { | ||
JAVA_HOME: ${java7} | ||
} | ||
|
||
environment: { | ||
PATH: "$JAVA_HOME/bin:$PATH" | ||
} | ||
|
||
setup: [ | ||
[ruby, "tool/jt.rb", build] | ||
] | ||
|
||
timelimit: "30:00" | ||
} | ||
|
||
gate_caps: { | ||
capabilities: [linux, amd64, gate] | ||
} | ||
|
||
jt: [ruby, "tool/jt.rb"] | ||
|
||
builds = [ | ||
{name: "ruby-test-fast"} ${common} ${gate_caps} {run: [${jt} [test, fast]]}, | ||
{name: "ruby-test-specs-command-line"} ${common} ${gate_caps} {run: [${jt} [test, specs, ":command_line"]]}, | ||
{name: "ruby-test-specs-language"} ${common} ${gate_caps} {run: [${jt} [test, specs, ":language"]]}, | ||
{name: "ruby-test-specs-core"} ${common} ${gate_caps} {run: [${jt} [test, specs, ":core"]]}, | ||
{name: "ruby-test-specs-library"} ${common} ${gate_caps} {run: [${jt} [test, specs, ":library"]]}, | ||
{name: "ruby-test-specs-truffle"} ${common} ${gate_caps} {run: [${jt} [test, specs, ":truffle"]]} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
#!/usr/bin/env ruby | ||
|
||
require_relative '../lib/runner.rb' | ||
require_relative '../lib/truffle/runner.rb' | ||
|
||
runner = JRubyTruffleRunner.new ARGV | ||
runner = Truffle::Runner.new ARGV | ||
exit runner.run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2,145 changes: 0 additions & 2,145 deletions
2,145
truffle/src/main/java/org/jruby/truffle/stdlib/BigDecimalNodes.java
This file was deleted.
Oops, something went wrong.
56 changes: 56 additions & 0 deletions
56
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/AbstractAddNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.core.Layouts; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.MathContext; | ||
|
||
public abstract class AbstractAddNode extends BigDecimalOpNode { | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private BigDecimal addBigDecimal(DynamicObject a, DynamicObject b, MathContext mathContext) { | ||
return Layouts.BIG_DECIMAL.getValue(a).add(Layouts.BIG_DECIMAL.getValue(b), mathContext); | ||
} | ||
|
||
protected Object add(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
return createBigDecimal(frame, addBigDecimal(a, b, new MathContext(precision, getRoundMode(frame)))); | ||
} | ||
|
||
protected Object addSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
final BigDecimalType aType = Layouts.BIG_DECIMAL.getType(a); | ||
final BigDecimalType bType = Layouts.BIG_DECIMAL.getType(b); | ||
|
||
if (aType == BigDecimalType.NAN || bType == BigDecimalType.NAN || | ||
(aType == BigDecimalType.POSITIVE_INFINITY && bType == BigDecimalType.NEGATIVE_INFINITY) || | ||
(aType == BigDecimalType.NEGATIVE_INFINITY && bType == BigDecimalType.POSITIVE_INFINITY)) { | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
|
||
if (aType == BigDecimalType.POSITIVE_INFINITY || bType == BigDecimalType.POSITIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
|
||
if (aType == BigDecimalType.NEGATIVE_INFINITY || bType == BigDecimalType.NEGATIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} | ||
|
||
// one is NEGATIVE_ZERO and second is NORMAL | ||
if (isNormal(a)) { | ||
return a; | ||
} else { | ||
return b; | ||
} | ||
} | ||
} |
149 changes: 149 additions & 0 deletions
149
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/AbstractDivNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.profiles.ConditionProfile; | ||
import org.jruby.truffle.core.Layouts; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.MathContext; | ||
|
||
public abstract class AbstractDivNode extends BigDecimalOpNode { | ||
|
||
private final ConditionProfile normalZero = ConditionProfile.createBinaryProfile(); | ||
|
||
private Object divBigDecimalWithProfile(DynamicObject a, DynamicObject b, MathContext mathContext) { | ||
final BigDecimal aBigDecimal = Layouts.BIG_DECIMAL.getValue(a); | ||
final BigDecimal bBigDecimal = Layouts.BIG_DECIMAL.getValue(b); | ||
if (normalZero.profile(bBigDecimal.signum() == 0)) { | ||
switch (aBigDecimal.signum()) { | ||
case 1: | ||
return BigDecimalType.POSITIVE_INFINITY; | ||
case 0: | ||
return BigDecimalType.NAN; | ||
case -1: | ||
return BigDecimalType.NEGATIVE_INFINITY; | ||
default: | ||
throw new UnsupportedOperationException("unreachable code branch for value: " + aBigDecimal.signum()); | ||
} | ||
} else { | ||
return divBigDecimal(aBigDecimal, bBigDecimal, mathContext); | ||
} | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private BigDecimal divBigDecimal(BigDecimal a, BigDecimal b, MathContext mathContext) { | ||
return a.divide(b, mathContext); | ||
} | ||
|
||
protected Object div(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
return createBigDecimal(frame, divBigDecimalWithProfile(a, b, new MathContext(precision, getRoundMode(frame)))); | ||
} | ||
|
||
protected Object divNormalSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
switch (Layouts.BIG_DECIMAL.getType(b)) { | ||
case NAN: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case NEGATIVE_ZERO: | ||
switch (Layouts.BIG_DECIMAL.getValue(a).signum()) { | ||
case 1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
case POSITIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(a).signum()) { | ||
case 1: | ||
case 0: | ||
return createBigDecimal(frame, BigDecimal.ZERO); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_ZERO); | ||
} | ||
case NEGATIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_ZERO); | ||
case 0: | ||
case -1: | ||
return createBigDecimal(frame, BigDecimal.ZERO); | ||
} | ||
default: | ||
throw new UnsupportedOperationException("unreachable code branch for value: " + Layouts.BIG_DECIMAL.getType(b)); | ||
} | ||
} | ||
|
||
protected Object divSpecialNormal(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
switch (Layouts.BIG_DECIMAL.getType(a)) { | ||
case NAN: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case NEGATIVE_ZERO: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_ZERO); | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimal.ZERO); | ||
} | ||
case POSITIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} | ||
case NEGATIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
default: | ||
throw new UnsupportedOperationException("unreachable code branch for value: " + Layouts.BIG_DECIMAL.getType(a)); | ||
} | ||
} | ||
|
||
protected Object divSpecialSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
final BigDecimalType aType = Layouts.BIG_DECIMAL.getType(a); | ||
final BigDecimalType bType = Layouts.BIG_DECIMAL.getType(b); | ||
|
||
if (aType == BigDecimalType.NAN || bType == BigDecimalType.NAN || | ||
(aType == BigDecimalType.NEGATIVE_ZERO && bType == BigDecimalType.NEGATIVE_ZERO)) { | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
|
||
if (aType == BigDecimalType.NEGATIVE_ZERO) { | ||
if (bType == BigDecimalType.POSITIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_ZERO); | ||
} else { | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
} | ||
|
||
if (bType == BigDecimalType.NEGATIVE_ZERO) { | ||
if (aType == BigDecimalType.POSITIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} else { | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
} | ||
|
||
// a and b are only +-Infinity | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
} |
108 changes: 108 additions & 0 deletions
108
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/AbstractMultNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.profiles.ConditionProfile; | ||
import org.jruby.truffle.core.Layouts; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.MathContext; | ||
|
||
public abstract class AbstractMultNode extends BigDecimalOpNode { | ||
|
||
private final ConditionProfile zeroNormal = ConditionProfile.createBinaryProfile(); | ||
|
||
private Object multBigDecimalWithProfile(DynamicObject a, DynamicObject b, MathContext mathContext) { | ||
final BigDecimal bBigDecimal = Layouts.BIG_DECIMAL.getValue(b); | ||
|
||
if (zeroNormal.profile(isNormalZero(a) && bBigDecimal.signum() == -1)) { | ||
return BigDecimalType.NEGATIVE_ZERO; | ||
} | ||
|
||
return multBigDecimal(Layouts.BIG_DECIMAL.getValue(a), bBigDecimal, mathContext); | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private Object multBigDecimal(BigDecimal a, BigDecimal b, MathContext mathContext) { | ||
return a.multiply(b, mathContext); | ||
} | ||
|
||
protected Object mult(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
return createBigDecimal(frame, multBigDecimalWithProfile(a, b, new MathContext(precision, getRoundMode(frame)))); | ||
} | ||
|
||
protected Object multNormalSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
return multSpecialNormal(frame, b, a, precision); | ||
} | ||
|
||
protected Object multSpecialNormal(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
switch (Layouts.BIG_DECIMAL.getType(a)) { | ||
case NAN: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case NEGATIVE_ZERO: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_ZERO); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimal.ZERO); | ||
} | ||
case POSITIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} | ||
case NEGATIVE_INFINITY: | ||
switch (Layouts.BIG_DECIMAL.getValue(b).signum()) { | ||
case 1: | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
case 0: | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
case -1: | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
default: | ||
throw new UnsupportedOperationException("unreachable code branch"); | ||
} | ||
} | ||
|
||
protected Object multSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
final BigDecimalType aType = Layouts.BIG_DECIMAL.getType(a); | ||
final BigDecimalType bType = Layouts.BIG_DECIMAL.getType(b); | ||
|
||
if (aType == BigDecimalType.NAN || bType == BigDecimalType.NAN) { | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
if (aType == BigDecimalType.NEGATIVE_ZERO && bType == BigDecimalType.NEGATIVE_ZERO) { | ||
return createBigDecimal(frame, BigDecimal.ZERO); | ||
} | ||
if (aType == BigDecimalType.NEGATIVE_ZERO || bType == BigDecimalType.NEGATIVE_ZERO) { | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
|
||
// a and b are only +-Infinity | ||
|
||
if (aType == BigDecimalType.POSITIVE_INFINITY) { | ||
return bType == BigDecimalType.POSITIVE_INFINITY ? a : createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} | ||
if (aType == BigDecimalType.NEGATIVE_INFINITY) { | ||
return bType == BigDecimalType.POSITIVE_INFINITY ? a : createBigDecimal(frame, (BigDecimalType.POSITIVE_INFINITY)); | ||
} | ||
|
||
throw new UnsupportedOperationException("unreachable code branch"); | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/AbstractSubNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import org.jruby.truffle.core.Layouts; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.MathContext; | ||
|
||
public abstract class AbstractSubNode extends BigDecimalOpNode { | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private BigDecimal subBigDecimal(DynamicObject a, DynamicObject b, MathContext mathContext) { | ||
return Layouts.BIG_DECIMAL.getValue(a).subtract(Layouts.BIG_DECIMAL.getValue(b), mathContext); | ||
} | ||
|
||
protected Object subNormal(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
return createBigDecimal(frame, subBigDecimal(a, b, new MathContext(precision, getRoundMode(frame)))); | ||
} | ||
|
||
protected Object subSpecial(VirtualFrame frame, DynamicObject a, DynamicObject b, int precision) { | ||
final BigDecimalType aType = Layouts.BIG_DECIMAL.getType(a); | ||
final BigDecimalType bType = Layouts.BIG_DECIMAL.getType(b); | ||
|
||
if (aType == BigDecimalType.NAN || bType == BigDecimalType.NAN || | ||
(aType == BigDecimalType.POSITIVE_INFINITY && bType == BigDecimalType.POSITIVE_INFINITY) || | ||
(aType == BigDecimalType.NEGATIVE_INFINITY && bType == BigDecimalType.NEGATIVE_INFINITY)) { | ||
return createBigDecimal(frame, BigDecimalType.NAN); | ||
} | ||
|
||
if (aType == BigDecimalType.POSITIVE_INFINITY || bType == BigDecimalType.NEGATIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.POSITIVE_INFINITY); | ||
} | ||
|
||
if (aType == BigDecimalType.NEGATIVE_INFINITY || bType == BigDecimalType.POSITIVE_INFINITY) { | ||
return createBigDecimal(frame, BigDecimalType.NEGATIVE_INFINITY); | ||
} | ||
|
||
// one is NEGATIVE_ZERO and second is NORMAL | ||
if (isNormal(a)) { | ||
return a; | ||
} else { | ||
return createBigDecimal(frame, Layouts.BIG_DECIMAL.getValue(b).negate()); | ||
} | ||
} | ||
} |
136 changes: 136 additions & 0 deletions
136
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalCastNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.dsl.Cached; | ||
import com.oracle.truffle.api.dsl.Fallback; | ||
import com.oracle.truffle.api.dsl.ImportStatic; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.RubyBignum; | ||
import org.jruby.RubyFixnum; | ||
import org.jruby.RubyRational; | ||
import org.jruby.ext.bigdecimal.RubyBigDecimal; | ||
import org.jruby.runtime.builtin.IRubyObject; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.Layouts; | ||
import org.jruby.truffle.language.RubyGuards; | ||
import org.jruby.truffle.language.RubyNode; | ||
import org.jruby.truffle.language.SnippetNode; | ||
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.RoundingMode; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = RubyNode.class), | ||
@NodeChild(value = "roundingMode", type = RubyNode.class) | ||
}) | ||
@ImportStatic(BigDecimalCoreMethodNode.class) | ||
public abstract class BigDecimalCastNode extends RubyNode { | ||
public BigDecimalCastNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public abstract BigDecimal executeBigDecimal(VirtualFrame frame, Object value, RoundingMode roundingMode); | ||
|
||
public abstract Object executeObject(VirtualFrame frame, Object value, RoundingMode roundingMode); | ||
|
||
@Specialization | ||
public BigDecimal doInt(long value, Object roundingMode) { | ||
return BigDecimal.valueOf(value); | ||
} | ||
|
||
@Specialization | ||
public BigDecimal doDouble(double value, Object roundingMode) { | ||
return BigDecimal.valueOf(value); | ||
} | ||
|
||
@Specialization(guards = "isRubyBignum(value)") | ||
public BigDecimal doBignum(DynamicObject value, Object roundingMode) { | ||
return new BigDecimal(Layouts.BIGNUM.getValue(value)); | ||
} | ||
|
||
@Specialization(guards = "isNormalRubyBigDecimal(value)") | ||
public BigDecimal doBigDecimal(DynamicObject value, Object roundingMode) { | ||
return Layouts.BIG_DECIMAL.getValue(value); | ||
} | ||
|
||
@Specialization(guards = {"!isRubyBignum(value)", "!isRubyBigDecimal(value)"}) | ||
public Object doOther( | ||
VirtualFrame frame, | ||
DynamicObject value, | ||
Object roundingMode, | ||
@Cached("new()") SnippetNode isRationalSnippet, | ||
@Cached("createMethodCall()") CallDispatchHeadNode numeratorCallNode, | ||
@Cached("createMethodCall()") CallDispatchHeadNode denominatorCallNode, | ||
@Cached("createMethodCall()") CallDispatchHeadNode toFCallNode) { | ||
if (roundingMode instanceof RoundingMode && (boolean) isRationalSnippet.execute(frame, "value.is_a?(Rational)", "value", value)) { | ||
|
||
final Object numerator = numeratorCallNode.call(frame, value, "numerator", null); | ||
|
||
final IRubyObject numeratorValue; | ||
|
||
if (numerator instanceof Integer) { | ||
numeratorValue = RubyFixnum.newFixnum(getContext().getJRubyRuntime(), (int) numerator); | ||
} else if (numerator instanceof Long) { | ||
numeratorValue = RubyFixnum.newFixnum(getContext().getJRubyRuntime(), (long) numerator); | ||
} else if (RubyGuards.isRubyBignum(numerator)) { | ||
numeratorValue = RubyBignum.newBignum(getContext().getJRubyRuntime(), Layouts.BIGNUM.getValue((DynamicObject) numerator)); | ||
} else { | ||
throw new UnsupportedOperationException(numerator.toString()); | ||
} | ||
|
||
final Object denominator = denominatorCallNode.call(frame, value, "denominator", null); | ||
|
||
final IRubyObject denominatorValue; | ||
|
||
if (denominator instanceof Integer) { | ||
denominatorValue = RubyFixnum.newFixnum(getContext().getJRubyRuntime(), (int) denominator); | ||
} else if (denominator instanceof Long) { | ||
denominatorValue = RubyFixnum.newFixnum(getContext().getJRubyRuntime(), (long) denominator); | ||
} else if (RubyGuards.isRubyBignum(denominator)) { | ||
denominatorValue = RubyBignum.newBignum(getContext().getJRubyRuntime(), Layouts.BIGNUM.getValue((DynamicObject) denominator)); | ||
} else { | ||
throw new UnsupportedOperationException(denominator.toString()); | ||
} | ||
|
||
final RubyRational rubyRationalValue = RubyRational.newRationalRaw(getContext().getJRubyRuntime(), numeratorValue, denominatorValue); | ||
|
||
final RubyBigDecimal rubyBigDecimalValue; | ||
|
||
try { | ||
rubyBigDecimalValue = RubyBigDecimal.getVpRubyObjectWithPrec19Inner(getContext().getJRubyRuntime().getCurrentContext(), rubyRationalValue, (RoundingMode) roundingMode); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
throw e; | ||
} | ||
|
||
return rubyBigDecimalValue.getBigDecimalValue(); | ||
} else { | ||
final Object result = toFCallNode.call(frame, value, "to_f", null); | ||
if (result != nil()) { | ||
return new BigDecimal((double) result); | ||
} else { | ||
return result; | ||
} | ||
} | ||
} | ||
|
||
@Fallback | ||
public Object doBigDecimalFallback(Object value, Object roundingMode) { | ||
return nil(); | ||
} | ||
// TODO (pitr 22-Jun-2015): How to better communicate failure without throwing | ||
} |
66 changes: 66 additions & 0 deletions
66
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalCoerceNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.language.RubyNode; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.RoundingMode; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = RubyNode.class), | ||
@NodeChild(value = "roundingMode", type = RoundModeNode.class), | ||
@NodeChild(value = "cast", type = BigDecimalCastNode.class, executeWith = {"value", "roundingMode"}) | ||
|
||
}) | ||
public abstract class BigDecimalCoerceNode extends RubyNode { | ||
@Child private CreateBigDecimalNode createBigDecimal; | ||
|
||
public static BigDecimalCoerceNode create(RubyContext context, SourceSection sourceSection, RubyNode value) { | ||
return BigDecimalCoerceNodeGen.create(value, | ||
RoundModeNodeFactory.create(), | ||
BigDecimalCastNodeGen.create(context, sourceSection, null, null)); | ||
} | ||
|
||
private void setupCreateBigDecimal() { | ||
if (createBigDecimal == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
createBigDecimal = insert(CreateBigDecimalNodeFactory.create(getContext(), getSourceSection(), null, null, null)); | ||
} | ||
} | ||
|
||
protected DynamicObject createBigDecimal(VirtualFrame frame, Object value) { | ||
setupCreateBigDecimal(); | ||
return createBigDecimal.executeCreate(frame, value); | ||
} | ||
|
||
public abstract DynamicObject executeBigDecimal(VirtualFrame frame, RoundingMode roundingMode, Object value); | ||
|
||
@Specialization | ||
public DynamicObject doBigDecimal(VirtualFrame frame, Object value, RoundingMode roundingMode, BigDecimal cast) { | ||
return createBigDecimal(frame, cast); | ||
} | ||
|
||
@Specialization(guards = { "isRubyBigDecimal(value)", "isNil(cast)" }) | ||
public Object doBigDecimal(DynamicObject value, RoundingMode roundingMode, DynamicObject cast) { | ||
return value; | ||
} | ||
|
||
// TODO (pitr 22-Jun-2015): deal with not-coerce-able values | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
...main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalCoreMethodArrayArgumentsNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.language.RubyNode; | ||
|
||
@NodeChild(value = "arguments", type = RubyNode[].class) | ||
public abstract class BigDecimalCoreMethodArrayArgumentsNode extends BigDecimalCoreMethodNode { | ||
|
||
public BigDecimalCoreMethodArrayArgumentsNode() { | ||
} | ||
|
||
public BigDecimalCoreMethodArrayArgumentsNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
} |
167 changes: 167 additions & 0 deletions
167
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalCoreMethodNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.CoreMethodNode; | ||
import org.jruby.truffle.core.Layouts; | ||
import org.jruby.truffle.core.cast.IntegerCastNode; | ||
import org.jruby.truffle.core.cast.IntegerCastNodeGen; | ||
import org.jruby.truffle.language.RubyGuards; | ||
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.RoundingMode; | ||
|
||
public abstract class BigDecimalCoreMethodNode extends CoreMethodNode { | ||
|
||
@Child | ||
private CreateBigDecimalNode createBigDecimal; | ||
@Child | ||
private CallDispatchHeadNode limitCall; | ||
@Child | ||
private IntegerCastNode limitIntegerCast; | ||
@Child | ||
private CallDispatchHeadNode roundModeCall; | ||
@Child | ||
private IntegerCastNode roundModeIntegerCast; | ||
|
||
public BigDecimalCoreMethodNode() { | ||
} | ||
|
||
public BigDecimalCoreMethodNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public static boolean isNormal(DynamicObject value) { | ||
return Layouts.BIG_DECIMAL.getType(value) == BigDecimalType.NORMAL; | ||
} | ||
|
||
public static boolean isNormalRubyBigDecimal(DynamicObject value) { | ||
return RubyGuards.isRubyBigDecimal(value) && Layouts.BIG_DECIMAL.getType(value) == BigDecimalType.NORMAL; | ||
} | ||
|
||
public static boolean isSpecialRubyBigDecimal(DynamicObject value) { | ||
return RubyGuards.isRubyBigDecimal(value) && Layouts.BIG_DECIMAL.getType(value) != BigDecimalType.NORMAL; | ||
} | ||
|
||
public static boolean isNormalZero(DynamicObject value) { | ||
return Layouts.BIG_DECIMAL.getValue(value).compareTo(BigDecimal.ZERO) == 0; | ||
} | ||
|
||
public static boolean isNan(DynamicObject value) { | ||
return Layouts.BIG_DECIMAL.getType(value) == BigDecimalType.NAN; | ||
} | ||
|
||
private void setupCreateBigDecimal() { | ||
if (createBigDecimal == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
createBigDecimal = insert(CreateBigDecimalNodeFactory.create(getContext(), getSourceSection(), null, null, null)); | ||
} | ||
} | ||
|
||
protected DynamicObject createBigDecimal(VirtualFrame frame, Object value) { | ||
setupCreateBigDecimal(); | ||
return createBigDecimal.executeCreate(frame, value); | ||
} | ||
|
||
protected DynamicObject initializeBigDecimal(VirtualFrame frame, Object value, DynamicObject self, Object digits) { | ||
setupCreateBigDecimal(); | ||
return createBigDecimal.executeInitialize(frame, value, self, digits); | ||
} | ||
|
||
private void setupLimitCall() { | ||
if (limitCall == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
limitCall = insert(DispatchHeadNodeFactory.createMethodCall(getContext())); | ||
} | ||
} | ||
|
||
private void setupLimitIntegerCast() { | ||
if (limitIntegerCast == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
limitIntegerCast = insert(IntegerCastNodeGen.create(getContext(), getSourceSection(), null)); | ||
} | ||
} | ||
|
||
protected int getLimit(VirtualFrame frame) { | ||
setupLimitCall(); | ||
setupLimitIntegerCast(); | ||
|
||
return limitIntegerCast.executeCastInt(limitCall.call(frame, getBigDecimalClass(), "limit", null)); | ||
} | ||
|
||
private void setupRoundModeCall() { | ||
if (roundModeCall == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
roundModeCall = insert(DispatchHeadNodeFactory.createMethodCall(getContext())); | ||
} | ||
} | ||
|
||
private void setupRoundModeIntegerCast() { | ||
if (roundModeIntegerCast == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
roundModeIntegerCast = insert(IntegerCastNodeGen.create(getContext(), getSourceSection(), null)); | ||
} | ||
} | ||
|
||
protected RoundingMode getRoundMode(VirtualFrame frame) { | ||
setupRoundModeCall(); | ||
setupRoundModeIntegerCast(); | ||
|
||
return toRoundingMode(roundModeIntegerCast.executeCastInt( | ||
// TODO (pitr 21-Jun-2015): read the actual constant | ||
roundModeCall.call(frame, getBigDecimalClass(), "mode", null, 256))); | ||
} | ||
|
||
protected DynamicObject getBigDecimalClass() { | ||
return coreLibrary().getBigDecimalClass(); | ||
} | ||
|
||
protected static RoundingMode toRoundingMode(int constValue) { | ||
switch (constValue) { | ||
case 1: | ||
return RoundingMode.UP; | ||
case 2: | ||
return RoundingMode.DOWN; | ||
case 3: | ||
return RoundingMode.HALF_UP; | ||
case 4: | ||
return RoundingMode.HALF_DOWN; | ||
case 5: | ||
return RoundingMode.CEILING; | ||
case 6: | ||
return RoundingMode.FLOOR; | ||
case 7: | ||
return RoundingMode.HALF_EVEN; | ||
default: | ||
throw new UnsupportedOperationException("unknown value: " + constValue); | ||
} | ||
} | ||
|
||
protected static int nearestBiggerMultipleOf4(int value) { | ||
return ((value / 4) + 1) * 4; | ||
} | ||
|
||
protected static int defaultDivisionPrecision(int precisionA, int precisionB, int limit) { | ||
final int combination = nearestBiggerMultipleOf4(precisionA + precisionB) * 4; | ||
return (limit > 0 && limit < combination) ? limit : combination; | ||
} | ||
|
||
protected static int defaultDivisionPrecision(BigDecimal a, BigDecimal b, int limit) { | ||
return defaultDivisionPrecision(a.precision(), b.precision(), limit); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1,396 changes: 1,396 additions & 0 deletions
1,396
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalNodes.java
Large diffs are not rendered by default.
Oops, something went wrong.
28 changes: 28 additions & 0 deletions
28
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalOpNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.dsl.CreateCast; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import org.jruby.truffle.language.RubyNode; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "a", type = RubyNode.class), | ||
@NodeChild(value = "b", type = RubyNode.class), | ||
}) | ||
public abstract class BigDecimalOpNode extends BigDecimalCoreMethodNode { | ||
|
||
@CreateCast("b") | ||
protected RubyNode castB(RubyNode b) { | ||
return BigDecimalCoerceNodeGen.create(null, null, b); | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/BigDecimalType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
public enum BigDecimalType { | ||
NEGATIVE_INFINITY("-Infinity"), | ||
POSITIVE_INFINITY("Infinity"), | ||
NAN("NaN"), | ||
NEGATIVE_ZERO("-0"), | ||
NORMAL(null); | ||
|
||
private final String representation; | ||
|
||
BigDecimalType(String representation) { | ||
this.representation = representation; | ||
} | ||
|
||
public String getRepresentation() { | ||
assert representation != null; | ||
return representation; | ||
} | ||
|
||
} |
285 changes: 285 additions & 0 deletions
285
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/CreateBigDecimalNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.ImportStatic; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.Layouts; | ||
import org.jruby.truffle.core.cast.BooleanCastNode; | ||
import org.jruby.truffle.core.cast.BooleanCastNodeGen; | ||
import org.jruby.truffle.language.NotProvided; | ||
import org.jruby.truffle.language.RubyNode; | ||
import org.jruby.truffle.language.control.RaiseException; | ||
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.BigInteger; | ||
import java.math.MathContext; | ||
import java.util.regex.MatchResult; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value = "value", type = RubyNode.class), | ||
@NodeChild(value = "self", type = RubyNode.class), | ||
@NodeChild(value = "digits", type = RubyNode.class) | ||
}) | ||
@ImportStatic(BigDecimalType.class) | ||
public abstract class CreateBigDecimalNode extends BigDecimalCoreMethodNode { | ||
|
||
private final static Pattern NUMBER_PATTERN; | ||
private final static Pattern ZERO_PATTERN; | ||
|
||
static { | ||
final String exponent = "([eE][+-]?)?(\\d*)"; | ||
NUMBER_PATTERN = Pattern.compile("^([+-]?\\d*\\.?\\d*" + exponent + ").*"); | ||
ZERO_PATTERN = Pattern.compile("^[+-]?0*\\.?0*" + exponent); | ||
} | ||
|
||
@Child | ||
private BigDecimalCastNode bigDecimalCast; | ||
@Child | ||
private CallDispatchHeadNode modeCall; | ||
@Child | ||
private GetIntegerConstantNode getIntegerConstant; | ||
@Child | ||
private BooleanCastNode booleanCast; | ||
@Child | ||
private CallDispatchHeadNode allocateNode; | ||
|
||
public CreateBigDecimalNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
bigDecimalCast = BigDecimalCastNodeGen.create(context, sourceSection, null, null); | ||
} | ||
|
||
private void setBigDecimalValue(DynamicObject bigdecimal, BigDecimal value) { | ||
Layouts.BIG_DECIMAL.setValue(bigdecimal, value); | ||
} | ||
|
||
private void setBigDecimalValue(DynamicObject bigdecimal, BigDecimalType type) { | ||
Layouts.BIG_DECIMAL.setType(bigdecimal, type); | ||
} | ||
|
||
public abstract DynamicObject executeInitialize(VirtualFrame frame, Object value, DynamicObject alreadyAllocatedSelf, Object digits); | ||
|
||
public final DynamicObject executeCreate(VirtualFrame frame, Object value) { | ||
if (allocateNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
allocateNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), true)); | ||
} | ||
|
||
DynamicObject rubyClass = (getBigDecimalClass()); | ||
return executeInitialize(frame, value, (DynamicObject) allocateNode.call(frame, rubyClass, "allocate", null), NotProvided.INSTANCE); | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, long value, DynamicObject self, NotProvided digits) { | ||
return create(frame, value, self, 0); | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, long value, DynamicObject self, int digits) { | ||
setBigDecimalValue(self, | ||
bigDecimalCast.executeBigDecimal(frame, value, getRoundMode(frame)).round(new MathContext(digits, getRoundMode(frame)))); | ||
return self; | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, double value, DynamicObject self, NotProvided digits) { | ||
CompilerDirectives.transferToInterpreter(); | ||
throw new RaiseException(coreExceptions().argumentError("can't omit precision for a Float.", this)); | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, double value, DynamicObject self, int digits) { | ||
setBigDecimalValue(self, | ||
bigDecimalCast.executeBigDecimal(frame, value, getRoundMode(frame)).round(new MathContext(digits, getRoundMode(frame)))); | ||
return self; | ||
} | ||
|
||
@Specialization(guards = "value == NEGATIVE_INFINITY || value == POSITIVE_INFINITY") | ||
public DynamicObject createInfinity(VirtualFrame frame, BigDecimalType value, DynamicObject self, Object digits) { | ||
return createWithMode(frame, value, self, "EXCEPTION_INFINITY", "Computation results to 'Infinity'"); | ||
} | ||
|
||
@Specialization(guards = "value == NAN") | ||
public DynamicObject createNaN(VirtualFrame frame, BigDecimalType value, DynamicObject self, Object digits) { | ||
return createWithMode(frame, value, self, "EXCEPTION_NaN", "Computation results to 'NaN'(Not a Number)"); | ||
} | ||
|
||
@Specialization(guards = "value == NEGATIVE_ZERO") | ||
public DynamicObject createNegativeZero(VirtualFrame frame, BigDecimalType value, DynamicObject self, Object digits) { | ||
setBigDecimalValue(self, value); | ||
return self; | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, BigDecimal value, DynamicObject self, NotProvided digits) { | ||
return create(frame, value, self, 0); | ||
} | ||
|
||
@Specialization | ||
public DynamicObject create(VirtualFrame frame, BigDecimal value, DynamicObject self, int digits) { | ||
setBigDecimalValue(self, value.round(new MathContext(digits, getRoundMode(frame)))); | ||
return self; | ||
} | ||
|
||
@Specialization(guards = "isRubyBignum(value)") | ||
public DynamicObject createBignum(VirtualFrame frame, DynamicObject value, DynamicObject self, NotProvided digits) { | ||
return createBignum(frame, value, self, 0); | ||
} | ||
|
||
@Specialization(guards = "isRubyBignum(value)") | ||
public DynamicObject createBignum(VirtualFrame frame, DynamicObject value, DynamicObject self, int digits) { | ||
setBigDecimalValue(self, | ||
new BigDecimal(Layouts.BIGNUM.getValue(value)).round(new MathContext(digits, getRoundMode(frame)))); | ||
return self; | ||
} | ||
|
||
@Specialization(guards = "isRubyBigDecimal(value)") | ||
public DynamicObject createBigDecimal(VirtualFrame frame, DynamicObject value, DynamicObject self, NotProvided digits) { | ||
return createBigDecimal(frame, value, self, 0); | ||
} | ||
|
||
@Specialization(guards = "isRubyBigDecimal(value)") | ||
public DynamicObject createBigDecimal(VirtualFrame frame, DynamicObject value, DynamicObject self, int digits) { | ||
setBigDecimalValue(self, | ||
Layouts.BIG_DECIMAL.getValue(value).round(new MathContext(digits, getRoundMode(frame)))); | ||
return self; | ||
} | ||
|
||
@Specialization(guards = "isRubyString(value)") | ||
public DynamicObject createString(VirtualFrame frame, DynamicObject value, DynamicObject self, NotProvided digits) { | ||
return createString(frame, value, self, 0); | ||
} | ||
|
||
@Specialization(guards = "isRubyString(value)") | ||
public DynamicObject createString(VirtualFrame frame, DynamicObject value, DynamicObject self, int digits) { | ||
return executeInitialize(frame, getValueFromString(value.toString(), digits), self, digits); | ||
} | ||
|
||
@Specialization(guards = {"!isRubyBignum(value)", "!isRubyBigDecimal(value)", "!isRubyString(value)"}) | ||
public DynamicObject create(VirtualFrame frame, DynamicObject value, DynamicObject self, int digits) { | ||
final Object castedValue = bigDecimalCast.executeObject(frame, value, getRoundMode(frame)); | ||
if (castedValue == nil()) { | ||
throw new RaiseException(coreExceptions().typeError("could not be casted to BigDecimal", this)); | ||
} | ||
|
||
setBigDecimalValue( | ||
self, | ||
((BigDecimal) castedValue).round(new MathContext(digits, getRoundMode(frame)))); | ||
|
||
return self; | ||
} | ||
|
||
// TODO (pitr 21-Jun-2015): raise on underflow | ||
|
||
private DynamicObject createWithMode(VirtualFrame frame, BigDecimalType value, DynamicObject self, | ||
String constantName, String errorMessage) { | ||
setupModeCall(); | ||
setupGetIntegerConstant(); | ||
setupBooleanCast(); | ||
|
||
final int exceptionConstant = getIntegerConstant.executeGetIntegerConstant(frame, getBigDecimalClass(), constantName); | ||
final boolean raise = booleanCast.executeBoolean(frame, | ||
modeCall.call(frame, getBigDecimalClass(), "boolean_mode", null, exceptionConstant)); | ||
if (raise) { | ||
CompilerDirectives.transferToInterpreter(); | ||
throw new RaiseException(coreExceptions().floatDomainError(errorMessage, this)); | ||
} | ||
|
||
setBigDecimalValue(self, value); | ||
return self; | ||
} | ||
|
||
private void setupBooleanCast() { | ||
if (booleanCast == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
booleanCast = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null)); | ||
} | ||
} | ||
|
||
private void setupGetIntegerConstant() { | ||
if (getIntegerConstant == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
getIntegerConstant = insert(GetIntegerConstantNodeGen.create(getContext(), getSourceSection(), null, null)); | ||
} | ||
} | ||
|
||
private void setupModeCall() { | ||
if (modeCall == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
modeCall = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), true)); | ||
} | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private Object getValueFromString(String string, int digits) { | ||
String strValue = string.trim(); | ||
|
||
// TODO (pitr 26-May-2015): create specialization without trims and other cleanups, use rewriteOn | ||
|
||
switch (strValue) { | ||
case "NaN": | ||
return BigDecimalType.NAN; | ||
case "Infinity": | ||
case "+Infinity": | ||
return BigDecimalType.POSITIVE_INFINITY; | ||
case "-Infinity": | ||
return BigDecimalType.NEGATIVE_INFINITY; | ||
case "-0": | ||
return BigDecimalType.NEGATIVE_ZERO; | ||
} | ||
|
||
// Convert String to Java understandable format (for BigDecimal). | ||
strValue = strValue.replaceFirst("[dD]", "E"); // 1. MRI allows d and D as exponent separators | ||
strValue = strValue.replaceAll("_", ""); // 2. MRI allows underscores anywhere | ||
|
||
final MatchResult result; | ||
{ | ||
final Matcher matcher = NUMBER_PATTERN.matcher(strValue); | ||
strValue = matcher.replaceFirst("$1"); // 3. MRI ignores the trailing junk | ||
result = matcher.toMatchResult(); | ||
} | ||
|
||
try { | ||
final BigDecimal value = new BigDecimal(strValue, new MathContext(digits)); | ||
if (value.compareTo(BigDecimal.ZERO) == 0 && strValue.startsWith("-")) { | ||
return BigDecimalType.NEGATIVE_ZERO; | ||
} else { | ||
return value; | ||
} | ||
|
||
} catch (NumberFormatException e) { | ||
if (ZERO_PATTERN.matcher(strValue).matches()) { | ||
return BigDecimal.ZERO; | ||
} | ||
|
||
final BigInteger exponent = new BigInteger(result.group(3)); | ||
if (exponent.signum() == 1) { | ||
return BigDecimalType.POSITIVE_INFINITY; | ||
} | ||
// TODO (pitr 21-Jun-2015): raise on underflow | ||
if (exponent.signum() == -1) { | ||
return BigDecimal.ZERO; | ||
} | ||
|
||
throw e; | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/GetIntegerConstantNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.RubyContext; | ||
import org.jruby.truffle.core.cast.IntegerCastNode; | ||
import org.jruby.truffle.core.cast.IntegerCastNodeGen; | ||
import org.jruby.truffle.core.cast.ToIntNode; | ||
import org.jruby.truffle.language.RubyNode; | ||
import org.jruby.truffle.language.constants.ReadConstantNode; | ||
|
||
@NodeChildren({@NodeChild("module"), @NodeChild("name")}) | ||
public abstract class GetIntegerConstantNode extends RubyNode { | ||
|
||
@Child | ||
ReadConstantNode readConstantNode; | ||
@Child | ||
ToIntNode toIntNode; | ||
@Child | ||
IntegerCastNode integerCastNode; | ||
|
||
public GetIntegerConstantNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
readConstantNode = new ReadConstantNode(context, sourceSection, false, false, null, null); | ||
toIntNode = ToIntNode.create(); | ||
integerCastNode = IntegerCastNodeGen.create(context, sourceSection, null); | ||
} | ||
|
||
public abstract int executeGetIntegerConstant(VirtualFrame frame, DynamicObject module, String name); | ||
|
||
@Specialization(guards = "isRubyModule(module)") | ||
public int doInteger(VirtualFrame frame, DynamicObject module, String name) { | ||
final Object value = readConstantNode.readConstant(frame, module, name); | ||
return integerCastNode.executeCastInt(toIntNode.executeIntOrLong(frame, value)); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
truffle/src/main/java/org/jruby/truffle/stdlib/bigdecimal/RoundModeNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* Copyright (c) 2013, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.stdlib.bigdecimal; | ||
|
||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
|
||
import java.math.RoundingMode; | ||
|
||
public abstract class RoundModeNode extends BigDecimalCoreMethodNode { | ||
|
||
@Specialization | ||
public RoundingMode doGetRoundMode(VirtualFrame frame) { | ||
return getRoundMode(frame); | ||
} | ||
|
||
} |
265 changes: 156 additions & 109 deletions
265
truffle/src/main/java/org/jruby/truffle/stdlib/psych/PsychEmitterNodes.java
Large diffs are not rendered by default.
Oops, something went wrong.
363 changes: 198 additions & 165 deletions
363
truffle/src/main/java/org/jruby/truffle/stdlib/psych/PsychParserNodes.java
Large diffs are not rendered by default.
Oops, something went wrong.
62 changes: 62 additions & 0 deletions
62
truffle/src/main/java/org/jruby/truffle/stdlib/psych/YAMLEncoding.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
* | ||
* This code is modified from the Psych JRuby extension module | ||
* implementation with the following header: | ||
* | ||
* Version: EPL 1.0/GPL 2.0/LGPL 2.1 | ||
* | ||
* The contents of this file are subject to the Eclipse Public | ||
* License Version 1.0 (the "License"); you may not use this file | ||
* except in compliance with the License. You may obtain a copy of | ||
* the License at http://www.eclipse.org/legal/epl-v10.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. | ||
* | ||
* Copyright (C) 2010 Charles O Nutter <headius@headius.com> | ||
* | ||
* 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. | ||
*/ | ||
package org.jruby.truffle.stdlib.psych; | ||
|
||
import org.jcodings.Encoding; | ||
import org.jcodings.specific.UTF16BEEncoding; | ||
import org.jcodings.specific.UTF16LEEncoding; | ||
import org.jcodings.specific.UTF8Encoding; | ||
|
||
public enum YAMLEncoding { | ||
YAML_ANY_ENCODING(UTF8Encoding.INSTANCE), | ||
YAML_UTF8_ENCODING(UTF8Encoding.INSTANCE), | ||
YAML_UTF16LE_ENCODING(UTF16LEEncoding.INSTANCE), | ||
YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE); | ||
|
||
YAMLEncoding(Encoding encoding) { | ||
this.encoding = encoding; | ||
} | ||
|
||
private final Encoding encoding; | ||
|
||
public Encoding getEncoding() { | ||
return encoding; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters