Skip to content

Commit bc23c47

Browse files
committed
Revert "[Truffle] Removed Array#{inject,reduce} since they should be defined in Enumerable."
This reverts commit 8f8f95c.
1 parent 8c8808d commit bc23c47

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

core/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java

+81
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,87 @@ public RubyArray initializeCopyObject(RubyArray self, RubyArray from) {
18811881

18821882
}
18831883

1884+
@CoreMethod(names = {"inject", "reduce"}, needsBlock = true, optional = 1)
1885+
@ImportGuards(ArrayGuards.class)
1886+
public abstract static class InjectNode extends YieldingCoreMethodNode {
1887+
1888+
@Child private CallDispatchHeadNode dispatch;
1889+
1890+
public InjectNode(RubyContext context, SourceSection sourceSection) {
1891+
super(context, sourceSection);
1892+
dispatch = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.CALL_METHOD_MISSING);
1893+
}
1894+
1895+
public InjectNode(InjectNode prev) {
1896+
super(prev);
1897+
dispatch = prev.dispatch;
1898+
}
1899+
1900+
@Specialization(guards = "isObject")
1901+
public Object injectObject(VirtualFrame frame, RubyArray array, Object initial, RubyProc block) {
1902+
int count = 0;
1903+
1904+
final Object[] store = (Object[]) array.getStore();
1905+
1906+
Object accumulator = initial;
1907+
1908+
try {
1909+
for (int n = 0; n < array.getSize(); n++) {
1910+
if (CompilerDirectives.inInterpreter()) {
1911+
count++;
1912+
}
1913+
1914+
accumulator = yield(frame, block, accumulator, store[n]);
1915+
}
1916+
} finally {
1917+
if (CompilerDirectives.inInterpreter()) {
1918+
((RubyRootNode) getRootNode()).reportLoopCount(count);
1919+
}
1920+
}
1921+
1922+
return accumulator;
1923+
}
1924+
1925+
@Specialization
1926+
public Object inject(VirtualFrame frame, RubyArray array, Object initial, RubyProc block) {
1927+
notDesignedForCompilation();
1928+
1929+
final Object[] store = array.slowToArray();
1930+
1931+
if (store.length < 2) {
1932+
throw new UnsupportedOperationException();
1933+
}
1934+
1935+
Object accumulator = initial;
1936+
1937+
for (int n = 0; n < array.getSize(); n++) {
1938+
accumulator = yield(frame, block, accumulator, store[n]);
1939+
}
1940+
1941+
return accumulator;
1942+
}
1943+
1944+
@Specialization
1945+
public Object inject(VirtualFrame frame, RubyArray array, RubySymbol symbol, UndefinedPlaceholder unused) {
1946+
notDesignedForCompilation();
1947+
1948+
final Object[] store = array.slowToArray();
1949+
1950+
if (store.length < 2) {
1951+
throw new UnsupportedOperationException();
1952+
}
1953+
1954+
Object accumulator = dispatch.call(frame, store[0], symbol, null, store[1]);
1955+
1956+
for (int n = 2; n < array.getSize(); n++) {
1957+
accumulator = dispatch.call(frame, accumulator, symbol, null, store[n]);
1958+
}
1959+
1960+
return accumulator;
1961+
}
1962+
1963+
}
1964+
18841965
@CoreMethod(names = "insert", required = 2)
18851966
public abstract static class InsertNode extends ArrayCoreMethodNode {
18861967

0 commit comments

Comments
 (0)