-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into truffle-head
- 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
Showing
72 changed files
with
1,974 additions
and
1,503 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
core/src/main/java/org/jruby/ir/passes/OptimizeDelegationPass.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package org.jruby.ir.passes; | ||
|
||
import org.jruby.ir.IRClosure; | ||
import org.jruby.ir.IRScope; | ||
import org.jruby.ir.IRFlags; | ||
import org.jruby.ir.instructions.*; | ||
import org.jruby.ir.operands.Operand; | ||
import org.jruby.ir.operands.Variable; | ||
import org.jruby.ir.representations.BasicBlock; | ||
|
||
import java.util.*; | ||
|
||
public class OptimizeDelegationPass extends CompilerPass { | ||
public static List<Class<? extends CompilerPass>> DEPENDENCIES = Arrays.<Class<? extends CompilerPass>>asList(CFGBuilder.class); | ||
|
||
@Override | ||
public String getLabel() { | ||
return "Delegated Variable Removal"; | ||
} | ||
|
||
@Override | ||
public List<Class<? extends CompilerPass>> getDependencies() { | ||
return DEPENDENCIES; | ||
} | ||
|
||
@Override | ||
public Object execute(IRScope s, Object... data) { | ||
for (IRClosure c: s.getClosures()) { | ||
run(c, false, true); | ||
} | ||
|
||
s.computeScopeFlags(); | ||
|
||
if (s.getFlags().contains(IRFlags.BINDING_HAS_ESCAPED)) | ||
return null; | ||
|
||
if (!s.getFlags().contains(IRFlags.RECEIVES_CLOSURE_ARG)) | ||
return null; | ||
|
||
optimizeDelegatedVars(s); | ||
|
||
return true; | ||
} | ||
|
||
@Override | ||
public boolean invalidate(IRScope s) { | ||
// Not reversible right now | ||
return false; | ||
} | ||
|
||
private static void optimizeDelegatedVars(IRScope s) { | ||
Map<Operand, Operand> unusedExplicitBlocks = new HashMap<Operand, Operand>(); | ||
|
||
for (BasicBlock bb: s.cfg().getBasicBlocks()) { | ||
for (Instr i: bb.getInstrs()) { | ||
if (i instanceof ReifyClosureInstr) { | ||
ReifyClosureInstr ri = (ReifyClosureInstr) i; | ||
unusedExplicitBlocks.put(ri.getResult(), ri.getSource()); | ||
} else { | ||
Iterator<Operand> it = unusedExplicitBlocks.keySet().iterator(); | ||
while (it.hasNext()) { | ||
Variable explicitBlock = (Variable) it.next(); | ||
if (usesVariableAsNonClosureArg(i, explicitBlock)) { | ||
it.remove(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
for (BasicBlock bb: s.cfg().getBasicBlocks()) { | ||
ListIterator<Instr> instrs = bb.getInstrs().listIterator(); | ||
while (instrs.hasNext()) { | ||
Instr i = instrs.next(); | ||
if (i instanceof ReifyClosureInstr) { | ||
ReifyClosureInstr ri = (ReifyClosureInstr) i; | ||
Variable procVar = ri.getResult(); | ||
Operand blockVar = unusedExplicitBlocks.get(procVar); | ||
|
||
if (blockVar != null) { | ||
ri.markDead(); | ||
instrs.set(new CopyInstr(procVar, blockVar)); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static boolean usesVariableAsNonClosureArg(Instr i, Variable v) { | ||
List<Variable> usedVariables = i.getUsedVariables(); | ||
if (usedVariables.contains(v)) { | ||
if (i instanceof ClosureAcceptingInstr) { | ||
return usedVariables.indexOf(v) != usedVariables.lastIndexOf(v) || | ||
v != ((ClosureAcceptingInstr) i).getClosureArg(); | ||
} else | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Provided by default |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# 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 | ||
|
||
# Empty thread file - everything is loaded by default at the moment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# https://github.com/jruby/jruby/issues/2574 | ||
describe 'Local variable assignments should not get clobbered' do | ||
it 'returns the right value for array literals' do | ||
a = 0 | ||
b = [a,a=1] | ||
expect(b).to eq([0,1]) | ||
end | ||
|
||
it 'returns the right value for hash literals' do | ||
a = 0 | ||
b = { a => a, (a = 1) => a } # => { 1 => 1 } (MRI: {0=>0, 1=>1}) | ||
c = { a => a, a => (a = 2) } # => { 2 => 2 } (MRI: {1=>2}) | ||
expect(b).to eq({0=>0, 1=>1}) | ||
expect(c).to eq({1=>2}) | ||
end | ||
end | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,5 @@ | ||
fails:Array#flatten returns a one-dimensional flattening recursively | ||
fails:Array#flatten takes an optional argument that determines the level of recursion | ||
fails:Array#flatten returns dup when the level of recursion is 0 | ||
fails:Array#flatten ignores negative levels | ||
fails:Array#flatten tries to convert passed Objects to Integers using #to_int | ||
fails:Array#flatten raises a TypeError when the passed Object can't be converted to an Integer | ||
fails:Array#flatten does not call flatten on elements | ||
fails:Array#flatten raises an ArgumentError on recursive arrays | ||
fails:Array#flatten flattens any element which responds to #to_ary, using the return value of said method | ||
fails:Array#flatten returns subclass instance for Array subclasses | ||
fails:Array#flatten returns a tainted array if self is tainted | ||
fails:Array#flatten returns an untrusted array if self is untrusted | ||
fails:Array#flatten with a non-Array object in the Array ignores the return value of #to_ary if it is nil | ||
fails:Array#flatten with a non-Array object in the Array raises a TypeError if the return value of #to_ary is not an Array | ||
fails:Array#flatten! modifies array to produce a one-dimensional flattening recursively | ||
fails:Array#flatten! returns self if made some modifications | ||
fails:Array#flatten! returns nil if no modifications took place | ||
fails:Array#flatten! should not check modification by size | ||
fails:Array#flatten! takes an optional argument that determines the level of recursion | ||
fails:Array#flatten! returns nil when the level of recursion is 0 | ||
fails:Array#flatten! treats negative levels as no arguments | ||
fails:Array#flatten! tries to convert passed Objects to Integers using #to_int | ||
fails:Array#flatten! raises a TypeError when the passed Object can't be converted to an Integer | ||
fails:Array#flatten! does not call flatten! on elements | ||
fails:Array#flatten! raises an ArgumentError on recursive arrays | ||
fails:Array#flatten! flattens any elements which responds to #to_ary, using the return value of said method | ||
fails:Array#flatten! raises a RuntimeError on frozen arrays when the array is modified | ||
fails:Array#flatten! raises a RuntimeError on frozen arrays when the array would not be modified |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
fails:Array#& creates an array with no duplicates | ||
fails:Array#& creates an array with elements in order they are first encountered | ||
fails:Array#& properly handles recursive arrays | ||
fails:Array#& determines equivalence between elements in the sense of eql? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1 @@ | ||
fails:Array#- tries to convert the passed arguments to Arrays using #to_ary | ||
fails:Array#- does not return subclass instance for Array subclasses | ||
fails:Array#- does not call to_ary on array subclasses | ||
fails:Array#- removes an item identified as equivalent via #hash and #eql? | ||
fails:Array#- doesn't remove an item with the same hash but not #eql? | ||
fails:Array#- properly handles recursive arrays |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,7 @@ | ||
fails:Encoding.find returns the corresponding Encoding object if given a valid encoding name | ||
fails:Encoding.find returns the corresponding Encoding object if given a valid alias name | ||
fails:Encoding.find raises a TypeError if passed a Symbol | ||
fails:Encoding.find returns the passed Encoding object | ||
fails:Encoding.find accepts encoding names as Strings | ||
fails:Encoding.find accepts any object as encoding name, if it responds to #to_str | ||
fails:Encoding.find is case insensitive | ||
fails:Encoding.find raises an ArgumentError if the given encoding does not exist | ||
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(windows - Encoding.aliases):Encoding.find needs to be reviewed for spec completeness |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,5 @@ | ||
fails:String#<=> with String returns -1 when self is less than other | ||
fails:String#<=> with String returns 1 when self is greater than other | ||
fails:String#<=> with String considers string that comes lexicographically first to be less if strings have same size | ||
fails:String#<=> with String compares shorter string with corresponding number of first chars of longer string | ||
fails:String#<=> with String ignores encoding difference | ||
fails:String#<=> with String compares the indices of the encodings when the strings have identical non-ASCII-compatible bytes | ||
fails:String#<=> returns nil if its argument provides neither #to_str nor #<=> | ||
fails:String#<=> uses the result of calling #to_str for comparison when #to_str is defined | ||
fails:String#<=> uses the result of calling #<=> on its argument when #<=> is defined but #to_str is not | ||
fails:String#<=> returns nil if argument also uses an inverse comparison for <=> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1 @@ | ||
fails:String#start_with? returns true only if beginning match | ||
fails:String#start_with? returns true only if any beginning match | ||
fails:String#start_with? converts its argument using :to_str | ||
fails:String#start_with? ignores arguments not convertible to string | ||
fails:String#start_with? uses only the needed arguments | ||
fails:String#start_with? works for multibyte strings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
truffle/src/main/java/org/jruby/truffle/nodes/array/ArrayReadSliceDenormalizedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* 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.array; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
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.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="index", type=RubyNode.class), | ||
@NodeChild(value="length", type=RubyNode.class) | ||
}) | ||
public abstract class ArrayReadSliceDenormalizedNode extends RubyNode { | ||
|
||
@Child private ArrayReadSliceNormalizedNode readNode; | ||
|
||
public ArrayReadSliceDenormalizedNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public ArrayReadSliceDenormalizedNode(ArrayReadSliceDenormalizedNode prev) { | ||
super(prev); | ||
readNode = prev.readNode; | ||
} | ||
|
||
public abstract Object executeReadSlice(VirtualFrame frame, RubyArray array, int index, int length); | ||
|
||
@Specialization | ||
public Object read(VirtualFrame frame, RubyArray array, int index, int length) { | ||
if (readNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
readNode = insert(ArrayReadSliceNormalizedNodeFactory.create(getContext(), getSourceSection(), null, null, null)); | ||
} | ||
|
||
final int normalizedIndex = array.normalizeIndex(index); | ||
|
||
return readNode.executeReadSlice(frame, array, normalizedIndex, length); | ||
} | ||
|
||
} |
159 changes: 159 additions & 0 deletions
159
truffle/src/main/java/org/jruby/truffle/nodes/array/ArrayReadSliceNormalizedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* | ||
* 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.array; | ||
|
||
import com.oracle.truffle.api.dsl.ImportGuards; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
import com.oracle.truffle.api.dsl.NodeChildren; | ||
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.ArrayGuards; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.core.RubyArray; | ||
import org.jruby.truffle.runtime.core.RubyNilClass; | ||
|
||
import java.util.Arrays; | ||
|
||
@NodeChildren({ | ||
@NodeChild(value="array", type=RubyNode.class), | ||
@NodeChild(value="index", type=RubyNode.class), | ||
@NodeChild(value="length", type=RubyNode.class) | ||
}) | ||
@ImportGuards(ArrayGuards.class) | ||
public abstract class ArrayReadSliceNormalizedNode extends RubyNode { | ||
|
||
public ArrayReadSliceNormalizedNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
public ArrayReadSliceNormalizedNode(ArrayReadSliceNormalizedNode prev) { | ||
super(prev); | ||
} | ||
|
||
public abstract Object executeReadSlice(VirtualFrame frame, RubyArray array, int index, int length); | ||
|
||
// Index out of bounds or negative length always gives you nil | ||
|
||
@Specialization( | ||
guards={"!indexInBounds"} | ||
) | ||
public RubyNilClass readIndexOutOfBounds(RubyArray array, int index, int length) { | ||
return getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
@Specialization( | ||
guards={"!lengthPositive"} | ||
) | ||
public RubyNilClass readNegativeLength(RubyArray array, int index, int length) { | ||
return getContext().getCoreLibrary().getNilObject(); | ||
} | ||
|
||
// If these guards pass for a null array you can only get an empty array | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "isNullArray"} | ||
) | ||
public RubyArray readNull(RubyArray array, int index, int length) { | ||
return new RubyArray(array.getLogicalClass(), null, 0); | ||
} | ||
|
||
// Reading within bounds on an array with actual storage | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "endInBounds", "isIntArray"} | ||
) | ||
public RubyArray readIntInBounds(RubyArray array, int index, int length) { | ||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((int[]) array.getStore(), index, index + length), length); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "endInBounds", "isLongArray"} | ||
) | ||
public RubyArray readLongInBounds(RubyArray array, int index, int length) { | ||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((long[]) array.getStore(), index, index + length), length); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "endInBounds", "isDoubleArray"} | ||
) | ||
public RubyArray readDoubleInBounds(RubyArray array, int index, int length) { | ||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((double[]) array.getStore(), index, index + length), length); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "endInBounds", "isObjectArray"} | ||
) | ||
public RubyArray readObjectInBounds(RubyArray array, int index, int length) { | ||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((Object[]) array.getStore(), index, index + length), length); | ||
} | ||
|
||
// Reading beyond upper bounds on an array with actual storage needs clamping | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "!endInBounds", "isIntArray"} | ||
) | ||
public RubyArray readIntOutOfBounds(RubyArray array, int index, int length) { | ||
final int clampedLength = Math.min(array.getSize(), index + length) - index; | ||
|
||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((int[]) array.getStore(), index, index + clampedLength), clampedLength); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "!endInBounds", "isLongArray"} | ||
) | ||
public RubyArray readLongOutOfBounds(RubyArray array, int index, int length) { | ||
final int clampedLength = Math.min(array.getSize(), index + length) - index; | ||
|
||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((long[]) array.getStore(), index, index + clampedLength), clampedLength); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "!endInBounds", "isDoubleArray"} | ||
) | ||
public RubyArray readDoubleOutOfBounds(RubyArray array, int index, int length) { | ||
final int clampedLength = Math.min(array.getSize(), index + length) - index; | ||
|
||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((double[]) array.getStore(), index, index + clampedLength), clampedLength); | ||
} | ||
|
||
@Specialization( | ||
guards={"indexInBounds", "lengthPositive", "!endInBounds", "isObjectArray"} | ||
) | ||
public RubyArray readObjectOutOfBounds(RubyArray array, int index, int length) { | ||
final int clampedLength = Math.min(array.getSize(), index + length) - index; | ||
|
||
return new RubyArray(array.getLogicalClass(), | ||
Arrays.copyOfRange((Object[]) array.getStore(), index, index + clampedLength), clampedLength); | ||
} | ||
|
||
// Guards | ||
|
||
public static boolean indexInBounds(RubyArray array, int index, int length) { | ||
return index >= 0 && index <= array.getSize(); | ||
} | ||
|
||
public static boolean lengthPositive(RubyArray array, int index, int length) { | ||
return length >= 0; | ||
} | ||
|
||
public static boolean endInBounds(RubyArray array, int index, int length) { | ||
return index + length < array.getSize(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
truffle/src/main/java/org/jruby/truffle/nodes/coerce/ToStrNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* 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.coerce; | ||
|
||
import com.oracle.truffle.api.CompilerDirectives; | ||
import com.oracle.truffle.api.dsl.NodeChild; | ||
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.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.control.RaiseException; | ||
import org.jruby.truffle.runtime.core.RubyString; | ||
|
||
@NodeChild(value = "child", type = RubyNode.class) | ||
public abstract class ToStrNode extends RubyNode { | ||
|
||
@Child private CallDispatchHeadNode toStr; | ||
|
||
public ToStrNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
toStr = DispatchHeadNodeFactory.createMethodCall(context); | ||
} | ||
|
||
public ToStrNode(ToStrNode prev) { | ||
super(prev); | ||
toStr = prev.toStr; | ||
} | ||
|
||
@Specialization | ||
public RubyString coerceRubyString(RubyString string) { | ||
return string; | ||
} | ||
|
||
@Specialization(guards = "!isRubyString") | ||
public RubyString coerceObject(VirtualFrame frame, Object object) { | ||
notDesignedForCompilation(); | ||
|
||
final Object coerced; | ||
|
||
try { | ||
coerced = toStr.call(frame, object, "to_str", null); | ||
} catch (RaiseException e) { | ||
if (e.getRubyException().getLogicalClass() == getContext().getCoreLibrary().getNoMethodErrorClass()) { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
throw new RaiseException( | ||
getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "String", this)); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
|
||
if (coerced instanceof RubyString) { | ||
return (RubyString) coerced; | ||
} else { | ||
CompilerDirectives.transferToInterpreter(); | ||
|
||
throw new RaiseException( | ||
getContext().getCoreLibrary().typeErrorBadCoercion(object, "String", "to_str", coerced, this)); | ||
} | ||
} | ||
|
||
@Override | ||
public abstract RubyString executeRubyString(VirtualFrame frame); | ||
|
||
public abstract RubyString executeRubyString(VirtualFrame frame, Object object); | ||
|
||
@Override | ||
public final Object execute(VirtualFrame frame) { | ||
return executeRubyString(frame); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1,016 changes: 122 additions & 894 deletions
1,016
truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
235 changes: 136 additions & 99 deletions
235
truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
475 changes: 254 additions & 221 deletions
475
truffle/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
truffle/src/main/ruby/jruby/truffle/core/rubinius/api/shims/array.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# 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 | ||
|
||
module Rubinius | ||
module Mirror | ||
class Array | ||
|
||
def self.reflect(array) | ||
Array.new(array) | ||
end | ||
|
||
def initialize(array) | ||
@array = array | ||
end | ||
|
||
def total | ||
@array.size | ||
end | ||
|
||
def tuple | ||
@array | ||
end | ||
|
||
def start | ||
0 | ||
end | ||
|
||
end | ||
end | ||
end | ||
|
||
class Array | ||
|
||
def new_reserved(count) | ||
# TODO CS 6-Feb-15 do we want to reserve space or allow the runtime to optimise for us? | ||
[] | ||
end | ||
|
||
end |
22 changes: 22 additions & 0 deletions
22
truffle/src/main/ruby/jruby/truffle/core/rubinius/api/shims/tuple.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Copyright (c) 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 | ||
|
||
module Rubinius | ||
|
||
class Tuple < Array | ||
|
||
def copy_from(other, start, length, dest) | ||
# TODO CS 6-Feb-15 use higher level indexing when it works | ||
length.times do |n| | ||
self[dest + n] = other[start + n] | ||
end | ||
end | ||
|
||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
331 changes: 331 additions & 0 deletions
331
truffle/src/main/ruby/jruby/truffle/core/rubinius/kernel/common/identity_map.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,331 @@ | ||
# 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. | ||
|
||
module Rubinius | ||
|
||
# IdentityMap is customized for uniquely storing elements from an Array to | ||
# implement the following Array methods: #&, #|, #-, #uniq, and #uniq! | ||
# | ||
# The algorithm used is double hashing with an overflow array. For each | ||
# array element, the element, its hash value, and its ordinal in the | ||
# sequence of elements added to the map are stored. | ||
# | ||
# Methods are provided to test an element for inclusion in the map and to | ||
# delete an entry from the map. The contents of a map can be returned as an | ||
# array in the order the elements were added to the map. | ||
|
||
class IdentityMap | ||
attr_reader :size | ||
|
||
Row = Table = Rubinius::Tuple | ||
MIN_CAPACITY = 64 | ||
MIN_ROW = 10 | ||
ROW_GROWTH = 9 | ||
|
||
# Converts one or more Enumerable instances to a single IdentityMap | ||
def self.from(*arrays, &block) | ||
im = allocate | ||
Rubinius.privately { im.load(arrays, &block) } | ||
im | ||
end | ||
|
||
def initialize | ||
capacity = MIN_CAPACITY | ||
@table = Table.new capacity | ||
@mask = capacity - 4 | ||
@max = capacity | ||
@size = 0 | ||
end | ||
|
||
# Adds +item+ to the IdentityMap if it does not already exist. May cause | ||
# a row to be added or enlarged. Returns +self+. | ||
def insert(item, &block) | ||
redistribute if @size > @max | ||
|
||
if block_given? | ||
item_hash = yield(item).hash | ||
else | ||
item_hash = item.hash | ||
end | ||
|
||
index = item_hash & @mask | ||
table = @table | ||
|
||
if num_entries = table[index] | ||
index += 1 | ||
|
||
if num_entries == 1 | ||
return self if match?(table, index, item, item_hash, &block) | ||
|
||
table[index-1] = 2 | ||
table[index] = promote_row table, index, item, item_hash, @size | ||
else | ||
i = 1 | ||
row = table[index] | ||
total = row[0] | ||
|
||
while i < total | ||
return self if match?(row, i, item, item_hash, &block) | ||
i += 3 | ||
end | ||
|
||
if total == row.size | ||
table[index] = enlarge_row row, item, item_hash, @size | ||
else | ||
i = row[0] | ||
set_item row, i, item, item_hash, @size | ||
row[0] = i + 3 | ||
end | ||
end | ||
else | ||
table[index] = 1 | ||
set_item table, index+1, item, item_hash, @size | ||
end | ||
@size += 1 | ||
|
||
self | ||
end | ||
|
||
# Returns +true+ if +item+ is in the IdentityMap, +false+ otherwise. | ||
def include?(item) | ||
item_hash = item.hash | ||
|
||
index = item_hash & @mask | ||
table = @table | ||
if num_entries = table[index] | ||
index += 1 | ||
|
||
if num_entries == 1 | ||
return true if match? table, index, item, item_hash | ||
else | ||
row = table[index] | ||
i = 1 | ||
total = row[0] | ||
while i < total | ||
return true if match? row, i, item, item_hash | ||
i += 3 | ||
end | ||
end | ||
end | ||
|
||
false | ||
end | ||
|
||
# If +item+ is in the IdentityMap, removes it and returns +true+. | ||
# Otherwise, returns +false+. | ||
def delete(item) | ||
item_hash = item.hash | ||
|
||
index = item_hash & @mask | ||
table = @table | ||
|
||
if num_entries = table[index] | ||
index += 1 | ||
if num_entries == 1 | ||
if match? table, index, item, item_hash | ||
table[index] = nil | ||
@size -= 1 | ||
return true | ||
end | ||
else | ||
row = table[index] | ||
i = 1 | ||
total = row[0] | ||
while i < total | ||
if match? row, i, item, item_hash | ||
row[i] = nil | ||
@size -= 1 | ||
return true | ||
end | ||
i += 3 | ||
end | ||
end | ||
end | ||
|
||
false | ||
end | ||
|
||
# Returns an Array containing all items in the IdentityMap in the order | ||
# in which they were added to the IdentityMap. | ||
def to_array | ||
array = Array.new @size | ||
|
||
i = 0 | ||
table = @table | ||
total = table.size | ||
|
||
while i < total | ||
if num_entries = table[i] | ||
if num_entries == 1 | ||
array[table[i+3]] = table[i+2] if table[i+1] | ||
else | ||
row = table[i+1] | ||
k = row[0] | ||
j = 1 | ||
while j < k | ||
array[row[j+2]] = row[j+1] if row[j] | ||
j += 3 | ||
end | ||
end | ||
end | ||
|
||
i += 4 | ||
end | ||
|
||
array | ||
end | ||
|
||
# Private implementation methods | ||
|
||
def resize(total) | ||
capacity = MIN_CAPACITY | ||
while capacity < total | ||
capacity <<= 2 | ||
end | ||
|
||
@table = Table.new capacity | ||
@mask = capacity - 4 | ||
@max = capacity | ||
end | ||
private :resize | ||
|
||
def redistribute | ||
table = @table | ||
resize @size | ||
|
||
i = 0 | ||
total = table.size | ||
|
||
while i < total | ||
if num_entries = table[i] | ||
if num_entries == 1 | ||
if item_hash = table[i+1] | ||
add_item table[i+2], item_hash, table[i+3] | ||
end | ||
else | ||
row = table[i+1] | ||
k = row[0] | ||
j = 1 | ||
while j < k | ||
if item_hash = row[j] | ||
add_item row[j+1], item_hash, row[j+2] | ||
end | ||
j += 3 | ||
end | ||
end | ||
end | ||
|
||
i += 4 | ||
end | ||
end | ||
private :redistribute | ||
|
||
def add_item(item, item_hash, ordinal) | ||
index = item_hash & @mask | ||
table = @table | ||
|
||
if num_entries = table[index] | ||
index += 1 | ||
|
||
if num_entries == 1 | ||
table[index-1] = 2 | ||
table[index] = promote_row table, index, item, item_hash, ordinal | ||
else | ||
row = table[index] | ||
i = row[0] | ||
|
||
if i == row.size | ||
table[index] = enlarge_row row, item, item_hash, ordinal | ||
else | ||
set_item row, i, item, item_hash, ordinal | ||
row[0] = i + 3 | ||
end | ||
end | ||
else | ||
table[index] = 1 | ||
set_item table, index+1, item, item_hash, ordinal | ||
end | ||
end | ||
private :add_item | ||
|
||
# Given an Array of Enumerable instances, computes a bounding set | ||
# to contain them and then adds each item to the IdentityMap. | ||
def load(arrays, &block) | ||
resize(arrays.inject(0) { |sum, array| sum + array.size }) | ||
@size = 0 | ||
|
||
arrays.each do |array| | ||
array.each { |item| insert(item, &block) } | ||
end | ||
end | ||
private :load | ||
|
||
def match?(table, index, item, item_hash) | ||
return false unless table[index] == item_hash | ||
other = table[index+1] | ||
if block_given? | ||
item = yield item | ||
other = yield other | ||
end | ||
Rubinius::Type.object_equal(item, other) or item.eql?(other) | ||
end | ||
private :match? | ||
|
||
def set_item(table, index, item, item_hash, ordinal) | ||
table[index] = item_hash | ||
table[index+1] = item | ||
table[index+2] = ordinal | ||
end | ||
private :set_item | ||
|
||
def promote_row(row, index, item, item_hash, ordinal) | ||
new_row = Row.new MIN_ROW | ||
|
||
new_row[0] = 7 | ||
new_row[1] = row[index] | ||
new_row[2] = row[index+1] | ||
new_row[3] = row[index+2] | ||
new_row[4] = item_hash | ||
new_row[5] = item | ||
new_row[6] = ordinal | ||
|
||
new_row | ||
end | ||
private :promote_row | ||
|
||
def enlarge_row(row, item, item_hash, ordinal) | ||
new_row = Row.new row.size + ROW_GROWTH | ||
new_row.copy_from row, 1, row.size-1, 1 | ||
|
||
index = row[0] | ||
new_row[0] = index + 3 | ||
set_item new_row, index, item, item_hash, ordinal | ||
|
||
new_row | ||
end | ||
private :enlarge_row | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters