Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ed58d733733e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3918de933241
Choose a head ref
  • 3 commits
  • 8 files changed
  • 1 contributor

Commits on Mar 5, 2015

  1. Copy the full SHA
    11f9cd2 View commit details
  2. [Truffle] Hash#to_a

    chrisseaton committed Mar 5, 2015
    Copy the full SHA
    3a97474 View commit details
  3. 5
    Copy the full SHA
    3918de9 View commit details
2 changes: 2 additions & 0 deletions spec/truffle/tags/core/encoding/find_tags.txt
Original file line number Diff line number Diff line change
@@ -5,3 +5,5 @@ fails:Encoding.find supports the 'locale' encoding alias
fails:Encoding.find returns default external encoding for the 'external' encoding alias
fails:Encoding.find returns default internal encoding for the 'internal' encoding alias
fails:Encoding.find uses default external encoding for the 'filesystem' encoding alias
fails:Encoding.find returns the corresponding Encoding object if given a valid encoding name
fails:Encoding.find is case insensitive
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/hash/replace_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
fails:Hash#replace replaces the contents of self with other
fails:Hash#replace tries to convert the passed argument to a hash using #to_hash
fails:Hash#replace calls to_hash on hash subclasses
fails:Hash#replace does not transfer default values
fails:Hash#replace raises a RuntimeError if called on a frozen instance that is modified
fails:Hash#replace raises a RuntimeError if called on a frozen instance that would not be modified
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/hash/to_a_tags.txt

This file was deleted.

26 changes: 26 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
Original file line number Diff line number Diff line change
@@ -10,7 +10,9 @@
package org.jruby.truffle.nodes;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrument.Probe;
import com.oracle.truffle.api.instrument.ProbeNode;
@@ -23,10 +25,12 @@
import org.jruby.truffle.nodes.instrument.RubyWrapperNode;
import org.jruby.truffle.nodes.yield.YieldDispatchNode;
import org.jruby.truffle.runtime.LexicalScope;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.ByteList;

import java.math.BigInteger;

@@ -467,4 +471,26 @@ public boolean isRubiniusUndefined(Object value) {
return value == getContext().getCoreLibrary().getRubiniusUndefined();
}

protected Object ruby(VirtualFrame frame, String expression, Object... arguments) {
notDesignedForCompilation();

final MaterializedFrame evalFrame = Truffle.getRuntime().createMaterializedFrame(
RubyArguments.pack(null, null, RubyArguments.getSelf(frame.getArguments()), null, new Object[]{}));

if (arguments.length % 2 == 1) {
throw new UnsupportedOperationException("odd number of name-value pairs for arguments");
}

for (int n = 0; n < arguments.length; n += 2) {
evalFrame.setObject(evalFrame.getFrameDescriptor().findOrAddFrameSlot(arguments[n]), arguments[n + 1]);
}

final RubyBinding binding = new RubyBinding(
getContext().getCoreLibrary().getBindingClass(),
RubyArguments.getSelf(frame.getArguments()),
evalFrame);

return getContext().eval(ByteList.create(expression), binding, true, "inline-ruby", this);
}

}
51 changes: 16 additions & 35 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/HashNodes.java
Original file line number Diff line number Diff line change
@@ -1134,54 +1134,35 @@ public int sizePackedArray(RubyHash hash) {

}

@CoreMethod(names = "to_a")
public abstract static class ToArrayNode extends HashCoreMethodNode {
@CoreMethod(names = "replace", required = 1)
public abstract static class ReplaceNode extends HashCoreMethodNode {

public ToArrayNode(RubyContext context, SourceSection sourceSection) {
public ReplaceNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public ToArrayNode(ToArrayNode prev) {
public ReplaceNode(ReplaceNode prev) {
super(prev);
}

@Specialization(guards = "isNull")
public RubyArray toArrayNull(RubyHash hash) {
notDesignedForCompilation();

return new RubyArray(getContext().getCoreLibrary().getArrayClass(), null, 0);
}

@Specialization(guards = {"!isNull", "!isBuckets"})
public RubyArray toArrayPackedArray(RubyHash hash) {
@Specialization
public RubyHash replace(VirtualFrame frame, RubyHash hash, RubyHash other) {
notDesignedForCompilation();

final Object[] store = (Object[]) hash.getStore();
final int size = hash.getSize();
final Object[] pairs = new Object[size];

for (int n = 0; n < size; n++) {
pairs[n] = RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), store[n * 2], store[n * 2 + 1]);
}

return new RubyArray(getContext().getCoreLibrary().getArrayClass(), pairs, size);
ruby(frame, "Rubinius.check_frozen");

HashOperations.verySlowSetKeyValues(hash, HashOperations.verySlowToKeyValues(other));
hash.setDefaultBlock(other.getDefaultBlock());
hash.setDefaultValue(other.getDefaultValue());

return hash;
}

@Specialization(guards = "isBuckets")
public RubyArray toArrayBuckets(RubyHash hash) {
@Specialization(guards = "!isRubyHash(arguments[1])")
public Object replace(VirtualFrame frame, RubyHash hash, Object other) {
notDesignedForCompilation();

final int size = hash.getSize();
final Object[] pairs = new Object[size];

int n = 0;

for (KeyValue keyValue : HashOperations.verySlowToKeyValues(hash)) {
pairs[n] = RubyArray.fromObjects(getContext().getCoreLibrary().getArrayClass(), keyValue.getValue(), keyValue.getValue());
n++;
}

return new RubyArray(getContext().getCoreLibrary().getArrayClass(), pairs, size);
return ruby(frame, "replace(Rubinius::Type.coerce_to other, Hash, :to_hash)", "other", other);
}

}
Original file line number Diff line number Diff line change
@@ -15,6 +15,10 @@
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.core.FixnumOrBignumNode;
import org.jruby.truffle.nodes.objects.IsTaintedNode;
import org.jruby.truffle.nodes.objects.IsTaintedNodeFactory;
import org.jruby.truffle.nodes.objects.TaintNode;
import org.jruby.truffle.nodes.objects.TaintNodeFactory;
import org.jruby.truffle.runtime.ObjectIDOperations;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
@@ -103,18 +107,37 @@ protected boolean isSmallFixnum(long fixnum) {
@RubiniusPrimitive(name = "object_infect", needsSelf = false)
public static abstract class ObjectInfectPrimitiveNode extends RubiniusPrimitiveNode {

@Child private IsTaintedNode isTaintedNode;
@Child private TaintNode taintNode;

public ObjectInfectPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public ObjectInfectPrimitiveNode(ObjectInfectPrimitiveNode prev) {
super(prev);
isTaintedNode = prev.isTaintedNode;
taintNode = prev.taintNode;
}

@Specialization
public Object objectInfect(Object host, Object source) {
notDesignedForCompilation();
// TODO(CS 26-Jan-15) infect
if (isTaintedNode == null) {
CompilerDirectives.transferToInterpreter();
isTaintedNode = insert(IsTaintedNodeFactory.create(getContext(), getSourceSection(), null));
}

if (isTaintedNode.executeIsTainted(source)) {
// This lazy node allocation effectively gives us a branch profile

if (taintNode == null) {
CompilerDirectives.transferToInterpreter();
taintNode = insert(TaintNodeFactory.create(getContext(), getSourceSection(), null));
}

taintNode.executeTaint(host);
}

return host;
}

Original file line number Diff line number Diff line change
@@ -446,7 +446,7 @@ private RubyNode translateRubiniusInvokePrimitive(SourceSection sourceSection, C
*
* into
*
* CallRubiniusPrimitiveNode(FooNode(arg1, arg2, ..., argN))
* InvokeRubiniusPrimitiveNode(FooNode(arg1, arg2, ..., argN))
*/

if (node.getArgsNode().childNodes().size() < 1 || !(node.getArgsNode().childNodes().get(0) instanceof org.jruby.ast.SymbolNode)) {
11 changes: 11 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/hash.rb
Original file line number Diff line number Diff line change
@@ -97,4 +97,15 @@ def invert
inverted
end

def to_a
ary = []

each_item do |item|
ary << [item.key, item.value]
end

Rubinius::Type.infect ary, self
ary
end

end