Skip to content

Commit

Permalink
[Truffle] Fix a Time MRI test regression.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed May 27, 2015
1 parent 8004916 commit 6c0982f
Showing 1 changed file with 16 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package org.jruby.truffle.nodes.rubinius;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.ExactMath;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand Down Expand Up @@ -69,7 +70,7 @@ public RubyTime timeSDup(RubyTime other) {

}

@RubiniusPrimitive(name = "time_s_specific", needsSelf = false, lowerFixnumParameters = { 0, 1 })
@RubiniusPrimitive(name = "time_s_specific", needsSelf = false, lowerFixnumParameters = { 1 })
public static abstract class TimeSSpecificPrimitiveNode extends RubiniusPrimitiveNode {

@Child private ReadTimeZoneNode readTimeZoneNode;
Expand All @@ -80,19 +81,29 @@ public TimeSSpecificPrimitiveNode(RubyContext context, SourceSection sourceSecti
}

@Specialization(guards = { "isTrue(isUTC)", "isNil(offset)" })
public RubyTime timeSSpecificUTC(int seconds, int nanoseconds, boolean isUTC, Object offset) {
public RubyTime timeSSpecificUTC(long seconds, int nanoseconds, boolean isUTC, Object offset) {
// TODO(CS): overflow checks needed?
final long milliseconds = seconds * 1_000L + (nanoseconds / 1_000_000);
final long milliseconds = getMillis(seconds, nanoseconds);
return new RubyTime(getContext().getCoreLibrary().getTimeClass(), time(milliseconds), nil());
}

@Specialization(guards = { "!isTrue(isUTC)", "isNil(offset)" })
public RubyTime timeSSpecific(VirtualFrame frame, int seconds, int nanoseconds, boolean isUTC, Object offset) {
public RubyTime timeSSpecific(VirtualFrame frame, long seconds, int nanoseconds, boolean isUTC, Object offset) {
// TODO(CS): overflow checks needed?
final long milliseconds = (long) seconds * 1_000 + ((long) nanoseconds / 1_000_000);
final long milliseconds = getMillis(seconds, nanoseconds);
return new RubyTime(getContext().getCoreLibrary().getTimeClass(), localtime(milliseconds, readTimeZoneNode.executeRubyString(frame)), offset);
}

private long getMillis(long seconds, int nanoseconds) {
try {
return ExactMath.addExact(ExactMath.multiplyExact(seconds, 1000L), (nanoseconds / 1_000_000));
} catch (ArithmeticException e) {
CompilerDirectives.transferToInterpreter();
String message = String.format("UNIX epoch + %d seconds out of range for Time (Joda-Time limitation)", seconds);
throw new RaiseException(getContext().getCoreLibrary().rangeError(message, this));
}
}

@TruffleBoundary
private DateTime time(long milliseconds) {
return new DateTime(milliseconds, DateTimeZone.UTC);
Expand Down

0 comments on commit 6c0982f

Please sign in to comment.