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: a9f34c872ead
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4ba498ccd9cb
Choose a head ref
  • 2 commits
  • 2 files changed
  • 2 contributors

Commits on Mar 19, 2015

  1. Copy the full SHA
    af6bb3e View commit details
  2. Merge pull request #2732 from bjfish/truffle_array_delete_frozen

    [Truffle] Adding frozen check to Array#delete.
    chrisseaton committed Mar 19, 2015
    Copy the full SHA
    4ba498c View commit details
Showing with 32 additions and 8 deletions.
  1. +0 −1 spec/truffle/tags/core/array/delete_tags.txt
  2. +32 −7 truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
1 change: 0 additions & 1 deletion spec/truffle/tags/core/array/delete_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Array#delete may be given a block that is executed if no element matches object
fails:Array#delete raises a RuntimeError on a frozen array
39 changes: 32 additions & 7 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Original file line number Diff line number Diff line change
@@ -35,6 +35,8 @@
import org.jruby.truffle.nodes.methods.arguments.MissingArgumentBehaviour;
import org.jruby.truffle.nodes.methods.arguments.ReadPreArgumentNode;
import org.jruby.truffle.nodes.methods.locals.ReadLevelVariableNodeFactory;
import org.jruby.truffle.nodes.objects.IsFrozenNode;
import org.jruby.truffle.nodes.objects.IsFrozenNodeFactory;
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.BreakException;
@@ -791,6 +793,7 @@ public RubyArray concat(RubyArray array, RubyArray other) {
public abstract static class DeleteNode extends ArrayCoreMethodNode {

@Child private KernelNodes.SameOrEqualNode equalNode;
@Child private IsFrozenNode isFrozenNode;

public DeleteNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -800,6 +803,7 @@ public DeleteNode(RubyContext context, SourceSection sourceSection) {
public DeleteNode(DeleteNode prev) {
super(prev);
equalNode = prev.equalNode;
isFrozenNode = prev.isFrozenNode;
}

@Specialization(guards = "isIntegerFixnum")
@@ -809,11 +813,20 @@ public Object deleteIntegerFixnum(VirtualFrame frame, RubyArray array, Object va
Object found = nil();

int i = 0;

for (int n = 0; n < array.getSize(); n++) {
int n = 0;
for (; n < array.getSize(); n++) {
final Object stored = store[n];

if (equalNode.executeSameOrEqual(frame, stored, value)) {
if (isFrozenNode == null) {
CompilerDirectives.transferToInterpreter();
isFrozenNode = insert(IsFrozenNodeFactory.create(getContext(), getSourceSection(), null));
}
if (isFrozenNode.executeIsFrozen(array)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(
getContext().getCoreLibrary().frozenError(array.getLogicalClass().getName(), this));
}
found = store[n];
continue;
}
@@ -824,8 +837,9 @@ public Object deleteIntegerFixnum(VirtualFrame frame, RubyArray array, Object va

i++;
}

array.setStore(store, i);
if(i != n){
array.setStore(store, i);
}
return found;
}

@@ -836,11 +850,20 @@ public Object deleteObject(VirtualFrame frame, RubyArray array, Object value) {
Object found = nil();

int i = 0;

for (int n = 0; n < array.getSize(); n++) {
int n = 0;
for (; n < array.getSize(); n++) {
final Object stored = store[n];

if (equalNode.executeSameOrEqual(frame, stored, value)) {
if (isFrozenNode == null) {
CompilerDirectives.transferToInterpreter();
isFrozenNode = insert(IsFrozenNodeFactory.create(getContext(), getSourceSection(), null));
}
if (isFrozenNode.executeIsFrozen(array)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(
getContext().getCoreLibrary().frozenError(array.getLogicalClass().getName(), this));
}
found = store[n];
continue;
}
@@ -852,7 +875,9 @@ public Object deleteObject(VirtualFrame frame, RubyArray array, Object value) {
i++;
}

array.setStore(store, i);
if(i != n){
array.setStore(store, i);
}
return found;
}