Skip to content

Commit

Permalink
Showing 6 changed files with 45 additions and 182 deletions.
Original file line number Diff line number Diff line change
@@ -14,13 +14,14 @@
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.NodeUtil;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.nodes.arguments.*;
import org.jruby.truffle.nodes.cast.TaintResultNode;
import org.jruby.truffle.nodes.control.SequenceNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNodeGen;
import org.jruby.truffle.nodes.methods.ExceptionTranslatingNode;
import org.jruby.truffle.nodes.objects.SelfNode;
import org.jruby.truffle.nodes.objects.SingletonClassNode;
@@ -170,7 +171,7 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
RubyNode readSelfNode = new SelfNode(context, sourceSection);

if (method.lowerFixnumSelf()) {
readSelfNode = new FixnumLowerNode(readSelfNode);
readSelfNode = FixnumLowerNodeGen.create(context, sourceSection, readSelfNode);
}

if (method.raiseIfFrozenSelf()) {
@@ -187,7 +188,7 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
RubyNode readArgumentNode = new ReadPreArgumentNode(context, sourceSection, n, MissingArgumentBehaviour.UNDEFINED);

if (ArrayUtils.contains(method.lowerFixnumParameters(), n)) {
readArgumentNode = new FixnumLowerNode(readArgumentNode);
readArgumentNode = FixnumLowerNodeGen.create(context, sourceSection, readArgumentNode);
}

if (ArrayUtils.contains(method.raiseIfFrozenParameters(), n)) {
Original file line number Diff line number Diff line change
@@ -34,7 +34,9 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;

import jnr.posix.POSIX;

import org.jcodings.Encoding;
import org.jcodings.exception.EncodingException;
import org.jcodings.specific.ASCIIEncoding;
@@ -52,7 +54,7 @@
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
import org.jruby.truffle.nodes.core.array.ArrayCoreMethodNode;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.objects.Allocator;
@@ -1780,11 +1782,13 @@ public SetByteNode(RubyContext context, SourceSection sourceSection) {
}

@CreateCast("index") public RubyNode coerceIndexToInt(RubyNode index) {
return new FixnumLowerNode(ToIntNodeGen.create(getContext(), getSourceSection(), index));
return FixnumLowerNodeGen.create(getContext(), getSourceSection(),
ToIntNodeGen.create(getContext(), getSourceSection(), index));
}

@CreateCast("value") public RubyNode coerceValueToInt(RubyNode value) {
return new FixnumLowerNode(ToIntNodeGen.create(getContext(), getSourceSection(), value));
return FixnumLowerNodeGen.create(getContext(), getSourceSection(),
ToIntNodeGen.create(getContext(), getSourceSection(), value));
}

@Specialization
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;

import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.truffle.nodes.RubyGuards;
@@ -31,7 +32,7 @@
import org.jruby.truffle.nodes.coerce.ToIntNode;
import org.jruby.truffle.nodes.coerce.ToIntNodeGen;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
@@ -1028,7 +1029,8 @@ public AtNode(RubyContext context, SourceSection sourceSection) {
}

@CreateCast("index") public RubyNode coerceOtherToInt(RubyNode index) {
return new FixnumLowerNode(ToIntNodeGen.create(getContext(), getSourceSection(), index));
return FixnumLowerNodeGen.create(getContext(), getSourceSection(),
ToIntNodeGen.create(getContext(), getSourceSection(), index));
}

@Specialization

This file was deleted.

Original file line number Diff line number Diff line change
@@ -9,144 +9,50 @@
*/
package org.jruby.truffle.nodes.core.fixnum;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.CoreLibrary;
import org.jruby.truffle.runtime.core.RubyRange;

public class FixnumLowerNode extends RubyNode {
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;

@Child private RubyNode child;

@CompilationFinal private boolean hasSeenInteger = false;
@CompilationFinal private boolean hasSeenLong = false;
@CompilationFinal private boolean hasSeenIntegerRange = false;
@CompilationFinal private boolean hasSeenLongRange = false;
@CompilationFinal private boolean hasSeenUndefined = false;

@CompilationFinal private boolean hasNeededToLowerLongFixnum = false;
/**
* Passes through {@code int} values unmodified, but will convert a {@code long} value to an {@code int}, if it fits
* within the range of an {@code int}. Leaves all other values unmodified. Used where a specialization only accepts
* {@code int}, such as Java array indexing, but we would like to also handle {@code long} if they also fit within an
* {@code int}.
*/
@NodeChild(value = "value", type = RubyNode.class)
public abstract class FixnumLowerNode extends RubyNode {

public FixnumLowerNode(RubyNode child) {
super(child.getContext(), child.getEncapsulatingSourceSection());
this.child = child;
public FixnumLowerNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Override
public Object execute(VirtualFrame frame) {
final Object value = child.execute(frame);

if (hasSeenInteger && value instanceof Integer) {
return value;
}

if (hasSeenLong && value instanceof Long) {
if (canLower((long) value)) {
return lower((long) value);
} else {
return value;
}
}

if (hasSeenIntegerRange && value instanceof RubyRange.IntegerFixnumRange) {
return value;
}

if (hasSeenLongRange && value instanceof RubyRange.LongFixnumRange) {
return value;
}

if (hasSeenUndefined && value instanceof NotProvided) {
return value;
}

CompilerDirectives.transferToInterpreterAndInvalidate();

if (value instanceof Integer) {
hasSeenInteger = true;
return value;
}

if (value instanceof Long) {
hasSeenLong = true;
if (canLower((long) value)) {
return lower((long) value);
} else {
return value;
}
}

if (value instanceof RubyRange.IntegerFixnumRange) {
hasSeenIntegerRange = true;
return value;
}

if (value instanceof RubyRange.LongFixnumRange) {
hasSeenLongRange = true;
return value;
}

if (value instanceof NotProvided) {
hasSeenUndefined = true;
return value;
}

@Specialization
public int lower(int value) {
return value;
}

@Override
public int executeInteger(VirtualFrame frame) throws UnexpectedResultException {
try {
if (hasNeededToLowerLongFixnum) {
final long value = super.executeLong(frame);

if (canLower(value)) {
return lower(value);
} else {
throw new UnexpectedResultException(value);
}
} else {
return super.executeInteger(frame);
}
} catch (UnexpectedResultException e) {
if (e.getResult() instanceof Long && canLower((long) e.getResult())) {
hasNeededToLowerLongFixnum = true;
return lower((long) e.getResult());
} else {
throw e;
}
}
@Specialization(guards = "canLower(value)")
public int lower(long value) {
return (int) value;
}

@Override
public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
throw new RuntimeException();
@Specialization(guards = "!canLower(value)")
public long lowerFails(long value) {
return value;
}

@Override
public NotProvided executeNotProvided(VirtualFrame frame) throws UnexpectedResultException {
try {
return super.executeNotProvided(frame);
} catch (UnexpectedResultException e) {
if (e.getResult() instanceof Long && canLower((long) e.getResult())) {
hasNeededToLowerLongFixnum = true;
throw new UnexpectedResultException(lower((long) e.getResult()));
} else {
throw e;
}
}
@Specialization(guards = { "!isInteger(value)", "!isLong(value)" })
public Object passThrough(Object value) {
return value;
}

private static boolean canLower(long value) {
protected static boolean canLower(long value) {
return CoreLibrary.fitsIntoInteger(value);
}

private static int lower(long value) {
assert canLower(value);
return (int) value;
}

}

Original file line number Diff line number Diff line change
@@ -11,10 +11,11 @@

import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.arguments.MissingArgumentBehaviour;
import org.jruby.truffle.nodes.arguments.ReadPreArgumentNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNode;
import org.jruby.truffle.nodes.core.fixnum.FixnumLowerNodeGen;
import org.jruby.truffle.nodes.objects.SelfNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayUtils;
@@ -67,7 +68,7 @@ public RubyNode createInvokePrimitiveNode(RubyContext context, SourceSection sou

private RubyNode transformArgument(RubyNode argument, int n) {
if (ArrayUtils.contains(annotation.lowerFixnumParameters(), n)) {
return new FixnumLowerNode(argument);
return FixnumLowerNodeGen.create(argument.getContext(), argument.getSourceSection(), argument);
} else {
return argument;
}

0 comments on commit 5c8c448

Please sign in to comment.