-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
- 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
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
- 9.0.1.0
- 9.0.0.0
- 9.0.0.0.rc2
- 9.0.0.0.rc1
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import com.oracle.truffle.api.utilities.ConditionProfile; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.control.ReturnException; | ||
|
||
/** | ||
* Node which wraps a {@link RubiniusPrimitiveNode}, providing the implicit control flow that you get with calls to | ||
* Rubinius primitives. | ||
*/ | ||
public class CallRubiniusPrimitiveNode extends RubyNode { | ||
|
||
@Child protected RubyNode primitive; | ||
private final long returnID; | ||
|
||
private final ConditionProfile primitiveSucceededCondition = ConditionProfile.createBinaryProfile(); | ||
|
||
public CallRubiniusPrimitiveNode(RubyContext context, SourceSection sourceSection, RubyNode primitive, long returnID) { | ||
super(context, sourceSection); | ||
this.primitive = primitive; | ||
this.returnID = returnID; | ||
} | ||
|
||
@Override | ||
public void executeVoid(VirtualFrame frame) { | ||
final Object value = primitive.execute(frame); | ||
|
||
if (primitiveSucceededCondition.profile(value != null)) { | ||
// If the primitive didn't fail its value is returned in the calling method | ||
|
||
throw new ReturnException(returnID, value); | ||
} | ||
|
||
// Primitives may return null to indicate that they have failed, in which case we continue with the fallback | ||
} | ||
|
||
@Override | ||
public Object execute(VirtualFrame frame) { | ||
executeVoid(frame); | ||
return getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface RubiniusPrimitive { | ||
|
||
String name(); | ||
|
||
boolean needsSelf() default true; | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.dsl.NodeFactory; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
|
||
/** | ||
* Packages up the original {@link RubiniusPrimitive annotation} with the {@link NodeFactory}. | ||
*/ | ||
public class RubiniusPrimitiveConstructor { | ||
|
||
private final RubiniusPrimitive annotation; | ||
private final NodeFactory<? extends RubyNode> factory; | ||
|
||
public RubiniusPrimitiveConstructor(RubiniusPrimitive annotation, NodeFactory<? extends RubyNode> factory) { | ||
this.annotation = annotation; | ||
this.factory = factory; | ||
} | ||
|
||
public RubiniusPrimitive getAnnotation() { | ||
return annotation; | ||
} | ||
|
||
public NodeFactory<? extends RubyNode> getFactory() { | ||
return factory; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.dsl.GeneratedBy; | ||
import com.oracle.truffle.api.dsl.NodeFactory; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Manages the available Rubinius primitive calls. | ||
*/ | ||
public class RubiniusPrimitiveManager { | ||
|
||
private final Map<String, RubiniusPrimitiveConstructor> primitives; | ||
|
||
private RubiniusPrimitiveManager(Map<String, RubiniusPrimitiveConstructor> primitives) { | ||
this.primitives = primitives; | ||
} | ||
|
||
public RubiniusPrimitiveConstructor getPrimitive(String name) { | ||
final RubiniusPrimitiveConstructor constructor = primitives.get(name); | ||
|
||
if (constructor == null) { | ||
throw new RuntimeException(String.format("Rubinius primitive %s not found", name)); | ||
} | ||
|
||
return constructor; | ||
} | ||
|
||
public static RubiniusPrimitiveManager create() { | ||
final List<NodeFactory<? extends RubyNode>> nodeFactories = new ArrayList<>(); | ||
|
||
nodeFactories.addAll(TimePrimitiveNodesFactory.getFactories()); | ||
nodeFactories.addAll(TypePrimitiveNodesFactory.getFactories()); | ||
nodeFactories.addAll(StringPrimitiveNodesFactory.getFactories()); | ||
|
||
final Map<String, RubiniusPrimitiveConstructor> primitives = new HashMap<>(); | ||
|
||
for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) { | ||
final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class); | ||
final Class<?> nodeClass = generatedBy.value(); | ||
final RubiniusPrimitive annotation = nodeClass.getAnnotation(RubiniusPrimitive.class); | ||
primitives.put(annotation.name(), new RubiniusPrimitiveConstructor(annotation, nodeFactory)); | ||
} | ||
|
||
return new RubiniusPrimitiveManager(primitives); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2013, 2014 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
|
||
@NodeChild(value = "arguments", type = RubyNode[].class) | ||
public abstract class RubiniusPrimitiveNode extends RubyNode { | ||
|
||
public RubiniusPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public RubiniusPrimitiveNode(RubiniusPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.nodes.Node; | ||
import com.oracle.truffle.api.nodes.UnexpectedResultException; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.joda.time.DateTime; | ||
import org.joda.time.DateTimeZone; | ||
import org.jruby.truffle.nodes.cast.BooleanCastNode; | ||
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory; | ||
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyTime; | ||
import org.jruby.truffle.runtime.core.TimeOperations; | ||
|
||
/** | ||
* Supports {@link TimePrimitiveNodes} by converting a {@link RubyTime} to a {@link DateTime}. We use a node because | ||
* doing this requires accessing instance variables, which we want to use an inline cache for. | ||
*/ | ||
class RubyTimeToDateTimeNode extends Node { | ||
|
||
private final RubyContext context; | ||
|
||
@Child protected ReadHeadObjectFieldNode readIsGMTNode = new ReadHeadObjectFieldNode("@is_gmt"); | ||
@Child protected ReadHeadObjectFieldNode readOffsetNode = new ReadHeadObjectFieldNode("@offset"); | ||
|
||
public RubyTimeToDateTimeNode(RubyContext context, SourceSection sourceSection) { | ||
this.context = context; | ||
} | ||
|
||
public DateTime toDateTime(VirtualFrame frame, RubyTime time) { | ||
final Object isGMTObject = readIsGMTNode.execute(time); | ||
|
||
// The @is_gmt instance variable is only for internal use so we don't need a full cast here | ||
|
||
final boolean isGMT; | ||
|
||
if (isGMTObject instanceof Boolean && ((boolean) isGMTObject)) { | ||
isGMT = true; | ||
} else { | ||
isGMT = false; | ||
} | ||
|
||
return toDateTime(time.getSeconds(), | ||
time.getNanoseconds(), | ||
isGMT, | ||
readOffsetNode.execute(time)); | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
private DateTime toDateTime(long seconds, long nanoseconds, boolean isGMT, Object offset) { | ||
final DateTimeZone dateTimeZone; | ||
|
||
if (isGMT) { | ||
dateTimeZone = DateTimeZone.UTC; | ||
} else { | ||
dateTimeZone = org.jruby.RubyTime.getLocalTimeZone(context.getRuntime()); | ||
} | ||
|
||
return new DateTime(TimeOperations.secondsAndNanosecondsToMiliseconds(seconds, nanoseconds), dateTimeZone); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import com.oracle.truffle.api.utilities.ConditionProfile; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.*; | ||
|
||
/** | ||
* Rubinius primitives associated with the Ruby {@code String} class. | ||
*/ | ||
public abstract class StringPrimitiveNodes { | ||
|
||
@RubiniusPrimitive(name = "string_check_null_safe", needsSelf = false) | ||
public static abstract class StringCheckNullSafePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
private final ConditionProfile nullByteProfile = ConditionProfile.createBinaryProfile(); | ||
|
||
public StringCheckNullSafePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public StringCheckNullSafePrimitiveNode(StringCheckNullSafePrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public boolean stringCheckNullSafe(RubyString string) { | ||
for (byte b : string.getBytes().unsafeBytes()) { | ||
if (nullByteProfile.profile(b == 0)) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "string_to_f", needsSelf = false) | ||
public static abstract class StringToFPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public StringToFPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public StringToFPrimitiveNode(StringToFPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public RubyString stringToF(RubyString string) { | ||
throw new UnsupportedOperationException("string_to_f"); | ||
} | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,316 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.joda.time.DateTime; | ||
import org.jruby.truffle.nodes.objectstorage.ReadHeadObjectFieldNode; | ||
import org.jruby.truffle.nodes.objectstorage.WriteHeadObjectFieldNode; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.*; | ||
import org.jruby.util.ByteList; | ||
import org.jruby.util.RubyDateFormatter; | ||
|
||
/** | ||
* Rubinius primitives associated with the Ruby {@code Time} class. | ||
* <p> | ||
* Also see {@link RubyTime}. | ||
*/ | ||
public abstract class TimePrimitiveNodes { | ||
|
||
@RubiniusPrimitive(name = "time_s_now") | ||
public static abstract class TimeSNowPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeSNowPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSNowPrimitiveNode(TimeSNowPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSNow(RubyClass timeClass) { | ||
final long milliseconds = System.currentTimeMillis(); | ||
return new RubyTime(timeClass, | ||
TimeOperations.millisecondsToSeconds(milliseconds), | ||
TimeOperations.millisecondsToNanoseconds(TimeOperations.millisecondsInCurrentSecond(milliseconds))); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_s_dup", needsSelf = false) | ||
public static abstract class TimeSDupPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected ReadHeadObjectFieldNode readIsGMTNode = new ReadHeadObjectFieldNode("@is_gmt"); | ||
@Child protected ReadHeadObjectFieldNode readOffsetNode = new ReadHeadObjectFieldNode("@offset"); | ||
|
||
@Child protected WriteHeadObjectFieldNode writeIsGMTNode = new WriteHeadObjectFieldNode("@is_gmt"); | ||
@Child protected WriteHeadObjectFieldNode writeOffsetNode = new WriteHeadObjectFieldNode("@offset"); | ||
|
||
public TimeSDupPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSDupPrimitiveNode(TimeSDupPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSDup(RubyTime other) { | ||
final RubyTime time = new RubyTime(getContext().getCoreLibrary().getTimeClass(), other.getSeconds(), other.getNanoseconds()); | ||
writeIsGMTNode.execute(time, readIsGMTNode.execute(other)); | ||
writeOffsetNode.execute(time, readOffsetNode.execute(other)); | ||
return time; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_s_specific", needsSelf = false) | ||
public static abstract class TimeSSpecificPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected WriteHeadObjectFieldNode writeIsGMTNode = new WriteHeadObjectFieldNode("@is_gmt"); | ||
@Child protected WriteHeadObjectFieldNode writeOffsetNode = new WriteHeadObjectFieldNode("@offset"); | ||
|
||
public TimeSSpecificPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSSpecificPrimitiveNode(TimeSSpecificPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSSpecific(int seconds, int nanoseconds, Object isGMT, Object offset) { | ||
return timeSSpecific((long) seconds, (long) nanoseconds, isGMT, offset); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSSpecific(long seconds, int nanoseconds, Object isGMT, Object offset) { | ||
return timeSSpecific(seconds, (long) nanoseconds, isGMT, offset); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSSpecific(int seconds, long nanoseconds, Object isGMT, Object offset) { | ||
return timeSSpecific((long) seconds, nanoseconds, isGMT, offset); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSSpecific(long seconds, long nanoseconds, Object isGMT, Object offset) { | ||
// TODO(CS): overflow checks here in Rbx | ||
final RubyTime time = new RubyTime(getContext().getCoreLibrary().getTimeClass(), seconds, nanoseconds); | ||
writeIsGMTNode.execute(time, isGMT); | ||
writeOffsetNode.execute(time, offset); | ||
return time; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_seconds") | ||
public static abstract class TimeSecondsPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeSecondsPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSecondsPrimitiveNode(TimeSecondsPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public long timeSeconds(RubyTime time) { | ||
return time.getSeconds(); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_useconds") | ||
public static abstract class TimeUSecondsPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeUSecondsPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeUSecondsPrimitiveNode(TimeUSecondsPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public long timeUSeconds(RubyTime time) { | ||
return time.getNanoseconds(); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_decompose") | ||
public static abstract class TimeDecomposePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected RubyTimeToDateTimeNode toDateTimeNode; | ||
|
||
public TimeDecomposePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
toDateTimeNode = new RubyTimeToDateTimeNode(context, sourceSection); | ||
} | ||
|
||
public TimeDecomposePrimitiveNode(TimeDecomposePrimitiveNode prev) { | ||
super(prev); | ||
toDateTimeNode = prev.toDateTimeNode; | ||
} | ||
|
||
@Specialization | ||
public RubyArray timeDecompose(VirtualFrame frame, RubyTime time) { | ||
final DateTime dateTime = toDateTimeNode.toDateTime(frame, time); | ||
final Object[] decomposed = decompose(dateTime); | ||
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), decomposed, decomposed.length); | ||
} | ||
|
||
@CompilerDirectives.TruffleBoundary | ||
public Object[] decompose(DateTime dateTime) { | ||
final int sec = dateTime.getSecondOfMinute(); | ||
final int min = dateTime.getMinuteOfDay(); | ||
final int hour = dateTime.getHourOfDay(); | ||
final int day = dateTime.getDayOfMonth(); | ||
final int month = dateTime.getMonthOfYear(); | ||
final int year = dateTime.getYear(); | ||
final int wday = dateTime.getDayOfWeek(); | ||
final int yday = dateTime.getDayOfYear(); | ||
final Object isdst = getContext().getCoreLibrary().getNilObject(); | ||
final Object zone = getContext().getCoreLibrary().getNilObject(); | ||
return new Object[]{sec, min, hour, day, month, year, wday, yday, isdst, zone}; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_strftime") | ||
public static abstract class TimeStrftimePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected RubyTimeToDateTimeNode toDateTimeNode; | ||
|
||
public TimeStrftimePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
toDateTimeNode = new RubyTimeToDateTimeNode(context, sourceSection); | ||
} | ||
|
||
public TimeStrftimePrimitiveNode(TimeStrftimePrimitiveNode prev) { | ||
super(prev); | ||
toDateTimeNode = prev.toDateTimeNode; | ||
} | ||
|
||
@Specialization | ||
public RubyString timeStrftime(VirtualFrame frame, RubyTime time, RubyString format) { | ||
return getContext().makeString(format(toDateTimeNode.toDateTime(frame, time), time.getNanoseconds(), format.getBytes())); | ||
} | ||
|
||
|
||
@CompilerDirectives.TruffleBoundary | ||
public ByteList format(DateTime time, long nanoseconds, ByteList format) { | ||
// TODO: converts everything to JRuby objects and back - should find a more direct way using ByteList | ||
final RubyDateFormatter rdf = getContext().getRuntime().getCurrentContext().getRubyDateFormatter(); | ||
return rdf.compileAndFormat(org.jruby.RubyString.newString(getContext().getRuntime(), format), false, time, nanoseconds, null).getByteList(); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_s_from_array", needsSelf = false) | ||
public static abstract class TimeSFromArrayPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeSFromArrayPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSFromArrayPrimitiveNode(TimeSFromArrayPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public RubyTime timeSFromArray(Object sec, Object min, Object hour, Object mday, Object month, Object year, | ||
Object nsec, Object isdst, Object fromgmt, Object utcoffset) { | ||
throw new UnsupportedOperationException("time_s_from_array"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_nseconds") | ||
public static abstract class TimeNSecondsPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeNSecondsPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeNSecondsPrimitiveNode(TimeNSecondsPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public long timeNSeconds(RubyTime time) { | ||
return time.getNanoseconds(); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_set_nseconds") | ||
public static abstract class TimeSetNSecondsPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeSetNSecondsPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeSetNSecondsPrimitiveNode(TimeSetNSecondsPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public long timeSetNSeconds(RubyTime time, long nanoseconds) { | ||
time.setNanoseconds(nanoseconds); | ||
return nanoseconds; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_env_zone") | ||
public static abstract class TimeEnvZonePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeEnvZonePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeEnvZonePrimitiveNode(TimeEnvZonePrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object timeEnvZone(RubyTime time) { | ||
throw new UnsupportedOperationException("time_env_zone"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "time_utc_offset") | ||
public static abstract class TimeUTCOffsetPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public TimeUTCOffsetPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public TimeUTCOffsetPrimitiveNode(TimeUTCOffsetPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object timeUTCOffset(RubyTime time) { | ||
throw new UnsupportedOperationException("time_utc_offset"); | ||
} | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
/* | ||
* Copyright (c) 2015 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.nodes.rubinius; | ||
|
||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.nodes.core.KernelNodes; | ||
import org.jruby.truffle.nodes.core.KernelNodesFactory; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.*; | ||
|
||
/** | ||
* Rubinius primitives associated with types and objects. | ||
*/ | ||
public abstract class TypePrimitiveNodes { | ||
|
||
@RubiniusPrimitive(name = "vm_object_kind_of", needsSelf = false) | ||
public static abstract class VMObjectKindOfPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected KernelNodes.IsANode isANode; | ||
|
||
public VMObjectKindOfPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
isANode = KernelNodesFactory.IsANodeFactory.create(context, sourceSection, new RubyNode[]{null, null}); | ||
} | ||
|
||
public VMObjectKindOfPrimitiveNode(VMObjectKindOfPrimitiveNode prev) { | ||
super(prev); | ||
isANode = prev.isANode; | ||
} | ||
|
||
@Specialization | ||
public boolean vmObjectKindOf(Object object, RubyClass rubyClass) { | ||
return isANode.executeBoolean(object, rubyClass); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_object_class", needsSelf = false) | ||
public static abstract class VMObjectClassPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected KernelNodes.ClassNode classNode; | ||
|
||
public VMObjectClassPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
classNode = KernelNodesFactory.ClassNodeFactory.create(context, sourceSection, new RubyNode[]{null}); | ||
} | ||
|
||
public VMObjectClassPrimitiveNode(VMObjectClassPrimitiveNode prev) { | ||
super(prev); | ||
classNode = prev.classNode; | ||
} | ||
|
||
@Specialization | ||
public RubyClass vmObjectClass(Object object) { | ||
return classNode.executeGetClass(object); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_object_singleton_class", needsSelf = false) | ||
public static abstract class VMObjectSingletonClassPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected KernelNodes.SingletonClassMethodNode singletonClassNode; | ||
|
||
public VMObjectSingletonClassPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
singletonClassNode = KernelNodesFactory.SingletonClassMethodNodeFactory.create(context, sourceSection, new RubyNode[]{null}); | ||
} | ||
|
||
public VMObjectSingletonClassPrimitiveNode(VMObjectSingletonClassPrimitiveNode prev) { | ||
super(prev); | ||
singletonClassNode = prev.singletonClassNode; | ||
} | ||
|
||
@Specialization | ||
public Object vmObjectClass(Object object) { | ||
return singletonClassNode.singletonClass(object); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_singleton_class_object", needsSelf = false) | ||
public static abstract class VMObjectSingletonClassObjectPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public VMObjectSingletonClassObjectPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public VMObjectSingletonClassObjectPrimitiveNode(VMObjectSingletonClassObjectPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object vmSingletonClassObject(Object object) { | ||
throw new UnsupportedOperationException("vm_singleton_class_object"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_object_respond_to", needsSelf = false) | ||
public static abstract class VMObjectRespondToPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
@Child protected KernelNodes.RespondToNode respondToNode; | ||
|
||
public VMObjectRespondToPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
respondToNode = KernelNodesFactory.RespondToNodeFactory.create(context, sourceSection, new RubyNode[]{null, null, null}); | ||
} | ||
|
||
public VMObjectRespondToPrimitiveNode(VMObjectRespondToPrimitiveNode prev) { | ||
super(prev); | ||
respondToNode = prev.respondToNode; | ||
} | ||
|
||
@Specialization | ||
public boolean vmObjectRespondTo(VirtualFrame frame, Object object, Object name, boolean includePrivate) { | ||
return respondToNode.executeDoesRespondTo(frame, object, name, includePrivate); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_object_equal", needsSelf = false) | ||
public static abstract class VMObjectEqualPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public VMObjectEqualPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public VMObjectEqualPrimitiveNode(VMObjectEqualPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object vmObjectEqual(Object a, Object b) { | ||
throw new UnsupportedOperationException("vm_object_equal"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_get_module_name", needsSelf = false) | ||
public static abstract class VMGetModuleNamePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public VMGetModuleNamePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public VMGetModuleNamePrimitiveNode(VMGetModuleNamePrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object vmGetModuleName(Object object) { | ||
throw new UnsupportedOperationException("vm_get_module_name"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "vm_set_module_name", needsSelf = false) | ||
public static abstract class VMSetModuleNamePrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public VMSetModuleNamePrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public VMSetModuleNamePrimitiveNode(VMSetModuleNamePrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object vmSetModuleName(Object object) { | ||
throw new UnsupportedOperationException("vm_set_module_name"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "encoding_get_object_encoding", needsSelf = false) | ||
public static abstract class EncodingGetObjectEncodingPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public EncodingGetObjectEncodingPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public EncodingGetObjectEncodingPrimitiveNode(EncodingGetObjectEncodingPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object encodingGetObjectEncoding(Object object) { | ||
throw new UnsupportedOperationException("encoding_get_object_encoding"); | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "object_infect", needsSelf = false) | ||
public static abstract class ObjectInfectPrimitiveNode extends RubiniusPrimitiveNode { | ||
|
||
public ObjectInfectPrimitiveNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public ObjectInfectPrimitiveNode(ObjectInfectPrimitiveNode prev) { | ||
super(prev); | ||
} | ||
|
||
@Specialization | ||
public Object objectInfect(Object object) { | ||
throw new UnsupportedOperationException("object_infect"); | ||
} | ||
|
||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) 2015 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.runtime.core; | ||
|
||
public abstract class TimeOperations { | ||
|
||
public static long secondsAndNanosecondsToMiliseconds(long seconds, long nanoseconds) { | ||
return secondsToMiliseconds(seconds) + nanosecondsToMilliseconds(nanoseconds); | ||
} | ||
|
||
public static long secondsToMiliseconds(long seconds) { | ||
return seconds * 1_000; | ||
} | ||
|
||
public static long nanosecondsToMilliseconds(long nanoseconds) { | ||
return nanoseconds * 1_000_000; | ||
} | ||
|
||
public static long millisecondsToSeconds(long milliseconds) { | ||
return milliseconds / 1_000; | ||
} | ||
|
||
public static long millisecondsInCurrentSecond(long milliseconds) { | ||
return milliseconds % 1_000; | ||
} | ||
|
||
public static long millisecondsToNanoseconds(long milliseconds) { | ||
return milliseconds * 1_000_000; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,5 @@ | |
|
||
# TODO(CS): isn't this vulnerable to naming conflicts? | ||
|
||
LookupTable = Hash | ||
class LookupTable < Hash | ||
end |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# Copyright (c) 2007-2014, Evan Phoenix and contributors | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# * Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# * Redistributions in binary form must reproduce the above copyright notice | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# * Neither the name of Rubinius nor the names of its contributors | ||
# may be used to endorse or promote products derived from this software | ||
# without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# The Type module provides facilities for accessing various "type" related | ||
# data about an object, as well as providing type coercion methods. These | ||
# facilities are independent of the object and thus are more robust in the | ||
# face of ad hoc monkeypatching. | ||
module Rubinius | ||
module Type | ||
# Performs a direct kind_of? check on the object bypassing any method | ||
# overrides. | ||
def self.object_kind_of?(obj, cls) | ||
Rubinius.primitive :vm_object_kind_of | ||
raise PrimitiveFailure, "Rubinius::Type.object_kind_of? primitive failed" | ||
end | ||
|
||
def self.object_class(obj) | ||
Rubinius.primitive :vm_object_class | ||
raise PrimitiveFailure, "Rubinius::Type.object_class primitive failed" | ||
end | ||
|
||
def self.object_singleton_class(obj) | ||
Rubinius.primitive :vm_object_singleton_class | ||
raise TypeError, "no singleton class available for a #{Type.object_class(obj)}" | ||
end | ||
|
||
def self.singleton_class_object(mod) | ||
Rubinius.primitive :vm_singleton_class_object | ||
raise PrimitiveFailure, "Rubinius::Type.singleton_class_object primitive failed" | ||
end | ||
|
||
def self.object_instance_of?(obj, cls) | ||
object_class(obj) == cls | ||
end | ||
|
||
def self.object_respond_to?(obj, name, include_private = false) | ||
Rubinius.invoke_primitive :vm_object_respond_to, obj, name, include_private | ||
end | ||
|
||
def self.object_equal(a, b) | ||
Rubinius.primitive :vm_object_equal | ||
raise PrimitiveFailure, "Rubinius::Type.object_equal primitive failed" | ||
end | ||
|
||
def self.module_name(mod) | ||
Rubinius.primitive :vm_get_module_name | ||
raise PrimitiveFailure, "Rubinius::Type.module_name primitive failed" | ||
end | ||
|
||
def self.module_inspect(mod) | ||
sc = singleton_class_object mod | ||
|
||
if sc | ||
case sc | ||
when Class, Module | ||
name = "#<Class:#{module_inspect(sc)}>" | ||
else | ||
cls = object_class sc | ||
name = "#<Class:#<#{module_name(cls)}:0x#{sc.object_id.to_s(16)}>>" | ||
end | ||
else | ||
name = module_name mod | ||
if !name or name == "" | ||
name = "#<#{object_class(mod)}:0x#{mod.object_id.to_s(16)}>" | ||
end | ||
end | ||
|
||
name | ||
end | ||
|
||
def self.set_module_name(mod, name, under) | ||
Rubinius.primitive :vm_set_module_name | ||
raise PrimitiveFailure, "Rubinius::Type.set_module_name primitive failed" | ||
end | ||
|
||
def self.coerce_string_to_float(string, strict) | ||
value = Rubinius.invoke_primitive :string_to_f, string, strict | ||
raise ArgumentError, "invalid string for Float" if value.nil? | ||
value | ||
end | ||
|
||
def self.coerce_to_array(obj) | ||
return [obj] unless obj | ||
|
||
return Rubinius.privately { obj.to_a } if object_respond_to?(obj, :to_a, true) | ||
return obj.to_ary if obj.respond_to?(:to_ary) | ||
|
||
# On 1.9, #to_a is not defined on all objects, so wrap the object in a | ||
# literal array. | ||
return [obj] | ||
end | ||
|
||
def self.coerce_to_float(obj, strict=true, must_be_numeric=true) | ||
if !must_be_numeric && object_kind_of?(obj, String) | ||
return coerce_string_to_float(obj, strict) | ||
end | ||
|
||
case obj | ||
when Float | ||
obj | ||
when Numeric | ||
coerce_to obj, Float, :to_f | ||
when nil, true, false | ||
raise TypeError, "can't convert #{obj.inspect} into Float" | ||
else | ||
raise TypeError, "can't convert #{obj.class} into Float" | ||
end | ||
end | ||
|
||
def self.coerce_object_to_float(obj) | ||
case obj | ||
when Float | ||
obj | ||
when nil | ||
raise TypeError, "can't convert nil into Float" | ||
when Complex | ||
if obj.respond_to?(:imag) && obj.imag.equal?(0) | ||
coerce_to obj, Float, :to_f | ||
else | ||
raise RangeError, "can't convert #{obj} into Float" | ||
end | ||
else | ||
coerce_to obj, Float, :to_f | ||
end | ||
end | ||
|
||
def self.object_encoding(obj) | ||
Rubinius.primitive :encoding_get_object_encoding | ||
raise PrimitiveFailure, "Rubinius::Type.object_encoding primitive failed" | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright (c) 2007-2014, Evan Phoenix and contributors | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# * Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# * Redistributions in binary form must reproduce the above copyright notice | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# * Neither the name of Rubinius nor the names of its contributors | ||
# may be used to endorse or promote products derived from this software | ||
# without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# Only part of Rubinius' kernel.rb | ||
|
||
class Float < Numeric | ||
|
||
def to_r | ||
f, e = Math.frexp self | ||
f = Math.ldexp(f, MANT_DIG).to_i | ||
e -= MANT_DIG | ||
|
||
(f * (RADIX ** e)).to_r | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright (c) 2007-2014, Evan Phoenix and contributors | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# * Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# * Redistributions in binary form must reproduce the above copyright notice | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# * Neither the name of Rubinius nor the names of its contributors | ||
# may be used to endorse or promote products derived from this software | ||
# without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# Only part of Rubinius' kernel.rb | ||
|
||
class Integer < Numeric | ||
|
||
def gcd(other) | ||
raise TypeError, "Expected Integer but got #{other.class}" unless other.kind_of?(Integer) | ||
min = self.abs | ||
max = other.abs | ||
while min > 0 | ||
tmp = min | ||
min = max % min | ||
max = tmp | ||
end | ||
max | ||
end | ||
|
||
def to_r | ||
Rational(self, 1) | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Copyright (c) 2007-2014, Evan Phoenix and contributors | ||
# All rights reserved. | ||
# | ||
# Redistribution and use in source and binary forms, with or without | ||
# modification, are permitted provided that the following conditions are met: | ||
# | ||
# * Redistributions of source code must retain the above copyright notice, this | ||
# list of conditions and the following disclaimer. | ||
# * Redistributions in binary form must reproduce the above copyright notice | ||
# this list of conditions and the following disclaimer in the documentation | ||
# and/or other materials provided with the distribution. | ||
# * Neither the name of Rubinius nor the names of its contributors | ||
# may be used to endorse or promote products derived from this software | ||
# without specific prior written permission. | ||
# | ||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | ||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
# Only part of Rubinius' numeric.rb | ||
|
||
class Numeric | ||
|
||
def zero? | ||
self == 0 | ||
end | ||
|
||
def nonzero? | ||
zero? ? nil : self | ||
end | ||
|
||
def div(other) | ||
raise ZeroDivisionError, "divided by 0" if other == 0 | ||
self.__slash__(other).floor | ||
end | ||
|
||
end |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,5 @@ | ||
fails:Kernel.Rational passed Integer returns a new Rational number with 1 as the denominator | ||
fails:Kernel.Rational passed two integers returns a new Rational number | ||
fails:Kernel.Rational passed two integers reduces the Rational | ||
fails:Kernel.Rational when passed a String converts the String to a Rational using the same method as String#to_r | ||
fails:Kernel.Rational when passed a String scales the Rational value of the first argument by the Rational value of the second | ||
fails:Kernel.Rational when passed a String does not use the same method as Float#to_r | ||
fails:Kernel.Rational when passed a String raises a TypeError if the first argument is nil | ||
fails:Kernel.Rational when passed a String raises a TypeError if the second argument is nil | ||
fails:Kernel.Rational when passed a String raises a TypeError if the first argument is a Symbol | ||
fails:Kernel.Rational when passed a String raises a TypeError if the second argument is a Symbol | ||
fails:Kernel.Rational when passed a String when passed a Numeric calls #to_r to convert the first argument to a Rational | ||
fails:Kernel.Rational when passed a String when passed a Complex returns a Rational from the real part if the imaginary part is 0 | ||
fails:Kernel.Rational when passed a String when passed a Complex raises a RangeError if the imaginary part is not 0 |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,2 @@ | ||
fails:Rational#ceil with no arguments (precision = 0) returns an Integer | ||
fails:Rational#ceil with no arguments (precision = 0) returns the truncated value toward positive infinity | ||
fails:Rational#ceil with a precision < 0 returns an Integer | ||
fails:Rational#ceil with a precision < 0 moves the truncation point n decimal places left | ||
fails:Rational#ceil with precision > 0 returns a Rational | ||
fails:Rational#ceil with precision > 0 moves the truncation point n decimal places right |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
fails:Rational#coerce returns the passed argument, self as Float, when given a Float | ||
fails:Rational#coerce returns the passed argument, self as Rational, when given an Integer | ||
fails:Rational#coerce returns [argument, self] when given a Rational |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,5 @@ | ||
fails:Rational#div returns an Integer | ||
fails:Rational#div raises an ArgumentError if passed more than one argument | ||
fails:Rational#div raises a TypeError if passed a non-numeric argument | ||
fails:Rational#div passed a Rational performs integer division and returns the result | ||
fails:Rational#div passed a Rational raises a ZeroDivisionError when the argument has a numerator of 0 | ||
fails:Rational#div passed a Rational raises a ZeroDivisionError when the argument has a numerator of 0.0 | ||
fails:Rational#div passed an Integer performs integer division and returns the result | ||
fails:Rational#div passed an Integer raises a ZeroDivisionError when the argument is 0 | ||
fails:Rational#div passed a Float performs integer division and returns the result | ||
fails:Rational#div passed a Float raises a ZeroDivisionError when the argument is 0.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,2 @@ | ||
fails:Rational#/ calls #coerce on the passed argument with self | ||
fails:Rational#/ calls #/ on the coerced Rational with the coerced Object | ||
fails:Rational#/ when passed an Integer returns self divided by other as a Rational | ||
fails:Rational#/ when passed an Integer raises a ZeroDivisionError when passed 0 | ||
fails:Rational#/ when passed a Rational returns self divided by other as a Rational | ||
fails:Rational#/ when passed a Rational raises a ZeroDivisionError when passed a Rational with a numerator of 0 | ||
fails:Rational#/ when passed a Float returns self divided by other as a Float | ||
fails:Rational#/ when passed a Float returns infinity when passed 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
fails:Rational#divmod when passed a Rational returns the quotient as Integer and the remainder as Rational | ||
fails:Rational#divmod when passed a Rational raises a ZeroDivisonError when passed a Rational with a numerator of 0 | ||
fails:Rational#divmod when passed an Integer returns the quotient as Integer and the remainder as Rational | ||
fails:Rational#divmod when passed an Integer raises a ZeroDivisionError when passed 0 | ||
fails:Rational#divmod when passed a Float returns the quotient as Integer and the remainder as Float | ||
fails:Rational#divmod when passed a Float raises a ZeroDivisionError when passed 0 |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,4 @@ | ||
fails:Rational#** calls #coerce on the passed argument with self | ||
fails:Rational#** calls #** on the coerced Rational with the coerced Object | ||
fails:Rational#** raises ZeroDivisionError for Rational(0, 1) passed a negative Integer | ||
fails:Rational#** raises ZeroDivisionError for Rational(0, 1) passed a negative Rational with denominator 1 | ||
fails:Rational#** raises ZeroDivisionError for Rational(0, 1) passed a negative Rational | ||
fails:Rational#** returns Infinity for Rational(0, 1) passed a negative Float | ||
fails:Rational#** when passed Rational returns Rational(1) if the exponent is Rational(0) | ||
fails:Rational#** when passed Rational returns self raised to the argument as a Rational if the exponent's denominator is 1 | ||
fails:Rational#** when passed Rational returns self raised to the argument as a Float if the exponent's denominator is not 1 | ||
fails:Rational#** when passed Rational returns a complex number when self is negative and the passed argument is not 0 | ||
fails:Rational#** when passed Integer returns the Rational value of self raised to the passed argument | ||
fails:Rational#** when passed Integer returns Rational(1, 1) when the passed argument is 0 | ||
fails:Rational#** when passed Bignum returns Rational(0) when self is Rational(0) and the exponent is positive | ||
fails:Rational#** when passed Bignum raises ZeroDivisionError when self is Rational(0) and the exponent is negative | ||
fails:Rational#** when passed Bignum returns Rational(1) when self is Rational(1) | ||
fails:Rational#** when passed Bignum returns Rational(1) when self is Rational(-1) and the exponent is positive and even | ||
fails:Rational#** when passed Bignum returns Rational(-1) when self is Rational(-1) and the exponent is positive and odd | ||
fails:Rational#** when passed Bignum returns positive Infinity when self is > 1 | ||
fails:Rational#** when passed Bignum returns 0.0 when self is > 1 and the exponent is negative | ||
fails:Rational#** when passed Bignum returns positive Infinity when self < -1 | ||
fails:Rational#** when passed Bignum returns 0.0 when self is < -1 and the exponent is negative | ||
fails:Rational#** when passed Float returns self converted to Float and raised to the passed argument | ||
fails:Rational#** when passed Float returns a complex number if self is negative and the passed argument is not 0 | ||
fails:Rational#** when passed Float returns Complex(1.0) when the passed argument is 0.0 |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,2 @@ | ||
fails:Rational#floor with no arguments (precision = 0) returns an integer | ||
fails:Rational#floor with no arguments (precision = 0) returns the truncated value toward negative infinity | ||
fails:Rational#floor with a precision < 0 returns an integer | ||
fails:Rational#floor with a precision < 0 moves the truncation point n decimal places left | ||
fails:Rational#floor with a precision > 0 returns a Rational | ||
fails:Rational#floor with a precision > 0 moves the truncation point n decimal places right |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
fails:Rational#% returns the remainder when this value is divided by other | ||
fails:Rational#% returns a Float value when the argument is Float | ||
fails:Rational#% raises ZeroDivisionError on zero denominator | ||
fails:Rational#% raises a ZeroDivisionError when the argument is 0.0 |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1 @@ | ||
fails:Rational#rationalize returns self with no argument | ||
fails:Rational#rationalize simplifies self to the degree specified by a Rational argument | ||
fails:Rational#rationalize simplifies self to the degree specified by a Float argument | ||
fails:Rational#rationalize raises ArgumentError when passed more than one argument |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,3 @@ | ||
fails:Rational#round with no arguments (precision = 0) returns an integer | ||
fails:Rational#round with no arguments (precision = 0) returns the truncated value toward the nearest integer | ||
fails:Rational#round with a precision < 0 returns an integer | ||
fails:Rational#round with a precision < 0 moves the truncation point n decimal places left | ||
fails:Rational#round with a precision > 0 returns a Rational | ||
fails:Rational#round with a precision > 0 moves the truncation point n decimal places right | ||
fails:Rational#round with a precision > 0 doesn't alter the value if the precision is too great | ||
fails:Rational#round with a precision > 0 doesn't fail when rounding to an absurdly large positive precision |
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,2 @@ | ||
fails:Rational#truncate with no arguments (precision = 0) returns an integer | ||
fails:Rational#truncate with no arguments (precision = 0) returns the truncated value toward 0 | ||
fails:Rational#truncate with a precision < 0 returns an integer | ||
fails:Rational#truncate with a precision < 0 moves the truncation point n decimal places left | ||
fails:Rational#truncate with a precision > 0 returns a Rational | ||
fails:Rational#truncate with a precision > 0 moves the truncation point n decimal places right |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
fails:Struct#eql? returns false if any corresponding elements are not #eql? |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,10 @@ | ||
fails:Time.at passed Numeric returns a Time object representing the given number of Integer seconds since 1970-01-01 00:00:00 UTC | ||
fails:Time.at passed Numeric returns a Time object representing the given number of Float seconds since 1970-01-01 00:00:00 UTC | ||
fails:Time.at passed Numeric returns a non-UTC Time | ||
fails:Time.at passed Numeric returns a subclass instance on a Time subclass | ||
fails:Time.at passed Time creates a new time object with the value given by time | ||
fails:Time.at passed Time creates a dup time object with the value given by time | ||
fails:Time.at passed Time returns a UTC time if the argument is UTC | ||
fails:Time.at passed Time returns a non-UTC time if the argument is non-UTC | ||
fails:Time.at passed Time returns a subclass instance | ||
fails:Time.at passed non-Time, non-Numeric raises a TypeError with a String argument | ||
fails:Time.at passed non-Time, non-Numeric raises a TypeError with a nil argument | ||
fails:Time.at passed non-Time, non-Numeric with an argument that responds to #to_int coerces using #to_int | ||
fails:Time.at passed non-Time, non-Numeric with an argument that responds to #to_r coerces using #to_r | ||
fails:Time.at passed [Integer, Numeric] returns a Time object representing the given number of seconds and Integer microseconds since 1970-01-01 00:00:00 UTC | ||
fails:Time.at passed [Integer, Numeric] returns a Time object representing the given number of seconds and Float microseconds since 1970-01-01 00:00:00 UTC | ||
fails:Time.at with a second argument that responds to #to_int coerces using #to_int | ||
fails:Time.at with a second argument that responds to #to_r coerces using #to_r | ||
fails:Time.at passed [Integer, nil] raises a TypeError | ||
fails:Time.at passed [Integer, String] raises a TypeError | ||
fails:Time.at passed [Time, Integer] raises a TypeError |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
fails:Time#dup returns a Time object that represents the same time | ||
fails:Time#dup copies the gmt state flag | ||
fails:Time#dup returns an independent Time object | ||
fails:Time#dup returns a subclass instance |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
fails:Time#inspect formats the local time following the pattern 'yyyy-MM-dd HH:mm:ss Z' | ||
fails:Time#inspect formats the UTC time following the pattern 'yyyy-MM-dd HH:mm:ss UTC' | ||
fails:Time#inspect formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM' | ||
fails:Time#inspect returns a US-ASCII encoded string |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,13 @@ | ||
fails:Time#- decrements the time by the specified amount | ||
fails:Time#- understands negative subtractions | ||
fails:Time#- accepts arguments that can be coerced into Rational | ||
fails:Time#- raises a TypeError if given argument is a coercible String | ||
fails:Time#- raises TypeError on argument that can't be coerced | ||
fails:Time#- raises TypeError on nil argument | ||
fails:Time#- tracks microseconds | ||
fails:Time#- tracks nanoseconds | ||
fails:Time#- maintains precision | ||
fails:Time#- maintains microseconds precision | ||
fails:Time#- maintains nanoseconds precision | ||
fails:Time#- maintains subseconds precision | ||
fails:Time#- returns a UTC time if self is UTC | ||
fails:Time#- returns a non-UTC time if self is non-UTC | ||
fails:Time#- returns a time with the same fixed offset as self | ||
fails:Time#- does not return a subclass instance | ||
fails:Time#- returns a time with nanoseconds precision between two time objects | ||
fails:Time#- maintains precision |
This file was deleted.