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: 96b190113697
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 59b60b54ba1e
Choose a head ref
  • 4 commits
  • 5 files changed
  • 1 contributor

Commits on Feb 6, 2015

  1. Copy the full SHA
    86bda6c View commit details
  2. Copy the full SHA
    942b000 View commit details
  3. Copy the full SHA
    b346237 View commit details
  4. Copy the full SHA
    59b60b5 View commit details
1 change: 1 addition & 0 deletions spec/truffle/tags/core/array/hash_tags.txt
Original file line number Diff line number Diff line change
@@ -5,3 +5,4 @@ fails:Array#hash calls to_int on result of calling hash on each element
fails:Array#hash ignores array class differences
fails:Array#hash returns same hash code for arrays with the same content
fails:Array#hash returns the same value if arrays are #eql?
fails:Array#hash properly handles recursive arrays
Original file line number Diff line number Diff line change
@@ -47,35 +47,35 @@ public RubyNilClass readNull(RubyArray array, int index) {
}

@Specialization(
guards={"isNormalizedInBounds", "isIntArray"}
guards={"isInBounds", "isIntArray"}
)
public int readIntegerInBounds(RubyArray array, int index) {
return ((int[]) array.getStore())[index];
}

@Specialization(
guards={"isNormalizedInBounds", "isLongArray"}
guards={"isInBounds", "isLongArray"}
)
public long readLongInBounds(RubyArray array, int index) {
return ((long[]) array.getStore())[index];
}

@Specialization(
guards={"isNormalizedInBounds", "isDoubleArray"}
guards={"isInBounds", "isDoubleArray"}
)
public double readDoubleInBounds(RubyArray array, int index) {
return ((double[]) array.getStore())[index];
}

@Specialization(
guards={"isNormalizedInBounds", "isObjectArray"}
guards={"isInBounds", "isObjectArray"}
)
public Object readObjectInBounds(RubyArray array, int index) {
return ((Object[]) array.getStore())[index];
}

@Specialization(
guards="!isNormalizedInBounds"
guards="!isInBounds"
)
public RubyNilClass readOutOfBounds(RubyArray array, int index) {
return getContext().getCoreLibrary().getNilObject();
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ public static boolean isObjectArray(RubyArray array) {
return array.getStore() instanceof Object[];
}

public static boolean isNormalizedInBounds(RubyArray array, int index) {
public static boolean isInBounds(RubyArray array, int index) {
return index >= 0 && index < array.getSize();
}

95 changes: 0 additions & 95 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -1910,59 +1910,6 @@ public Object findObject(VirtualFrame frame, RubyArray array, RubyProc block) {
}
}

@CoreMethod(names = "first")
public abstract static class FirstNode extends ArrayCoreMethodNode {

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

public FirstNode(FirstNode prev) {
super(prev);
}

@Specialization(guards = "isNull")
public RubyNilClass firstNull(RubyArray array) {
notDesignedForCompilation();

return getContext().getCoreLibrary().getNilObject();
}

@Specialization(guards = "isIntegerFixnum")
public Object firstIntegerFixnum(RubyArray array) {
notDesignedForCompilation();

if (array.getSize() == 0) {
return getContext().getCoreLibrary().getNilObject();
} else {
return ((int[]) array.getStore())[0];
}
}

@Specialization(guards = "isFloat")
public Object firstFloat(RubyArray array) {
notDesignedForCompilation();

if (array.getSize() == 0) {
return getContext().getCoreLibrary().getNilObject();
} else {
return ((double[]) array.getStore())[0];
}
}

@Specialization(guards = "isObject")
public Object firstObject(RubyArray array) {
notDesignedForCompilation();

if (array.getSize() == 0) {
return getContext().getCoreLibrary().getNilObject();
} else {
return ((Object[]) array.getStore())[0];
}
}

}

@CoreMethod(names = "flatten")
public abstract static class FlattenNode extends ArrayCoreMethodNode {

@@ -1994,24 +1941,6 @@ private void flatten(List<Object> flattened, Object[] store) {

}

@CoreMethod(names = "hash")
public abstract static class HashNode extends CoreMethodNode {

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

public HashNode(HashNode prev) {
super(prev);
}

@Specialization
public long hashNumber(RubyArray array) {
return array.hashCode();
}

}

@CoreMethod(names = "include?", required = 1)
public abstract static class IncludeNode extends ArrayCoreMethodNode {

@@ -2472,30 +2401,6 @@ public RubyString join(RubyArray array, RubyString separator) {

}

@CoreMethod(names = "last")
public abstract static class LastNode extends ArrayCoreMethodNode {

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

public LastNode(LastNode prev) {
super(prev);
}

@Specialization
public Object last(RubyArray array) {
notDesignedForCompilation();

if (array.getSize() == 0) {
return getContext().getCoreLibrary().getNilObject();
} else {
return array.slowToArray()[array.getSize() - 1];
}
}

}

@CoreMethod(names = {"map", "collect"}, needsBlock = true)
@ImportGuards(ArrayGuards.class)
public abstract static class MapNode extends YieldingCoreMethodNode {
Original file line number Diff line number Diff line change
@@ -74,4 +74,80 @@ def values_at(*args)
out
end

def first(n = undefined)
return at(0) if undefined.equal?(n)

n = Rubinius::Type.coerce_to_collection_index n
raise ArgumentError, "Size must be positive" if n < 0

Array.new self[0, n]
end

def hash
hash_val = size
mask = Fixnum::MAX >> 1

# This is duplicated and manually inlined code from Thread for performance
# reasons. Before refactoring it, please benchmark it and compare your
# refactoring against the original.

id = object_id
objects = Thread.current.recursive_objects

# If there is already an our version running...
if objects.key? :__detect_outermost_recursion__

# If we've seen self, unwind back to the outer version
if objects.key? id
raise Thread::InnerRecursionDetected
end

# .. or compute the hash value like normal
begin
objects[id] = true

each { |x| hash_val = ((hash_val & mask) << 1) ^ x.hash }
ensure
objects.delete id
end

return hash_val
else
# Otherwise, we're the outermost version of this code..
begin
objects[:__detect_outermost_recursion__] = true
objects[id] = true

each { |x| hash_val = ((hash_val & mask) << 1) ^ x.hash }

# An inner version will raise to return back here, indicating that
# the whole structure is recursive. In which case, abondon most of
# the work and return a simple hash value.
rescue Thread::InnerRecursionDetected
return size
ensure
objects.delete :__detect_outermost_recursion__
objects.delete id
end
end

return hash_val
end

def last(n=undefined)
if undefined.equal?(n)
return at(-1)
elsif size < 1
return []
end

n = Rubinius::Type.coerce_to_collection_index n
return [] if n == 0

raise ArgumentError, "count must be positive" if n < 0

n = size if n > size
Array.new self[-n..-1]
end

end