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: c6ea19519f4a
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 73fd040ed314
Choose a head ref
  • 8 commits
  • 11 files changed
  • 1 contributor

Commits on May 23, 2016

  1. Copy the full SHA
    7bb412b View commit details
  2. Copy the full SHA
    8077fc1 View commit details
  3. Copy the full SHA
    d946791 View commit details
  4. Copy the full SHA
    e43bcf8 View commit details
  5. Copy the full SHA
    f232aaf View commit details
  6. Copy the full SHA
    de146e7 View commit details
  7. Copy the full SHA
    36b28d7 View commit details
  8. Copy the full SHA
    73fd040 View commit details
3 changes: 0 additions & 3 deletions spec/truffle/tags/library/readline/history/delete_at_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/library/readline/history/each_tags.txt

This file was deleted.

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/readline/history/empty_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/readline/history/length_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/readline/history/pop_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/readline/history/push_tags.txt

This file was deleted.

3 changes: 0 additions & 3 deletions spec/truffle/tags/library/readline/history/shift_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/library/readline/history/size_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -40,23 +40,27 @@
*/
package org.jruby.truffle.stdlib.readline;

import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.specific.UTF8Encoding;
import jline.console.history.History;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.YieldingCoreMethodNode;
import org.jruby.truffle.core.cast.ToStrNode;
import org.jruby.truffle.core.cast.ToStrNodeGen;
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.objects.TaintNode;
import org.jruby.truffle.language.objects.TaintNodeGen;

import java.util.Iterator;

@CoreClass("Truffle::ReadlineHistory")
public abstract class ReadlineHistoryNodes {

@@ -84,7 +88,7 @@ public DynamicObject push(VirtualFrame frame, DynamicObject history, Object... l

}

@CoreMethod(names = "pop")
@CoreMethod(names = "pop", needsSelf = false)
public abstract static class PopNode extends CoreMethodArrayArgumentsNode {

@Child private TaintNode taintNode;
@@ -94,6 +98,7 @@ public PopNode(RubyContext context, SourceSection sourceSection) {
taintNode = TaintNodeGen.create(context, sourceSection, null);
}

@TruffleBoundary
@Specialization
public Object pop() {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();
@@ -110,19 +115,48 @@ public Object pop() {

}

@CoreMethod(names = { "length", "size" })
@CoreMethod(names = "shift", needsSelf = false)
public abstract static class ShiftNode extends CoreMethodArrayArgumentsNode {

@Child private TaintNode taintNode;

public ShiftNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintNode = TaintNodeGen.create(context, sourceSection, null);
}

@TruffleBoundary
@Specialization
public Object shift() {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();

if (consoleHolder.getHistory().isEmpty()) {
return nil();
}

final String lastLine = consoleHolder.getHistory().removeFirst().toString();
final DynamicObject ret = createString(StringOperations.createRope(lastLine, getDefaultInternalEncoding()));

return taintNode.executeTaint(ret);
}

}

@CoreMethod(names = { "length", "size" }, needsSelf = false)
public abstract static class LengthNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public int length() {
return getContext().getConsoleHolder().getHistory().size();
}

}

@CoreMethod(names = "clear")
@CoreMethod(names = "clear", needsSelf = false)
public abstract static class ClearNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject clear() {
getContext().getConsoleHolder().getHistory().clear();
@@ -132,4 +166,114 @@ public DynamicObject clear() {

}

@CoreMethod(names = "each", needsBlock = true)
public abstract static class EachNode extends YieldingCoreMethodNode {

@Child private TaintNode taintNode;

public EachNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintNode = TaintNodeGen.create(context, sourceSection, null);
}

@Specialization
public DynamicObject each(VirtualFrame frame, DynamicObject history, DynamicObject block) {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();

for (Iterator<History.Entry> i = consoleHolder.getHistory().iterator(); i.hasNext();) {
final DynamicObject line = createString(StringOperations.createRope(i.next().value().toString(), getDefaultInternalEncoding()));

yield(frame, block, taintNode.executeTaint(line));
}

return history;
}

}

@CoreMethod(names = "[]", needsSelf = false, required = 1, lowerFixnumParameters = 0)
public abstract static class GetIndexNode extends CoreMethodArrayArgumentsNode {

@Child private TaintNode taintNode;

public GetIndexNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintNode = TaintNodeGen.create(context, sourceSection, null);
}

@TruffleBoundary
@Specialization
public Object getIndex(int index) {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();

final int normalizedIndex = index < 0 ? index + consoleHolder.getHistory().size() : index;

try {
final String line = consoleHolder.getHistory().get(normalizedIndex).toString();
final DynamicObject ret = createString(StringOperations.createRope(line, getDefaultInternalEncoding()));

return taintNode.executeTaint(ret);
} catch (IndexOutOfBoundsException e) {
throw new RaiseException(coreExceptions().indexError("invalid index", this));
}
}

}

@CoreMethod(names = "[]=", needsSelf = false, required = 2, lowerFixnumParameters = 0)
public abstract static class SetIndexNode extends CoreMethodArrayArgumentsNode {

@Child private ToStrNode toStrNode;

public SetIndexNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
toStrNode = ToStrNodeGen.create(context, sourceSection, null);
}

@Specialization
public Object setIndex(VirtualFrame frame, int index, Object line) {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();

final int normalizedIndex = index < 0 ? index + consoleHolder.getHistory().size() : index;

try {
final DynamicObject asString = toStrNode.executeToStr(frame, line);
consoleHolder.getHistory().set(normalizedIndex, RopeOperations.decodeUTF8(StringOperations.rope(asString)));

return nil();
} catch (IndexOutOfBoundsException e) {
throw new RaiseException(coreExceptions().indexError("invalid index", this));
}
}

}

@CoreMethod(names = "delete_at", needsSelf = false, required = 1, lowerFixnumParameters = 0)
public abstract static class DeleteAtNode extends CoreMethodArrayArgumentsNode {

@Child private TaintNode taintNode;

public DeleteAtNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintNode = TaintNodeGen.create(context, sourceSection, null);
}

@Specialization
public Object deleteAt(int index) {
final ConsoleHolder consoleHolder = getContext().getConsoleHolder();

final int normalizedIndex = index < 0 ? index + consoleHolder.getHistory().size() : index;

try {
final String line = consoleHolder.getHistory().remove(normalizedIndex).toString();
final DynamicObject ret = createString(StringOperations.createRope(line, getDefaultInternalEncoding()));

return taintNode.executeTaint(ret);
} catch (IndexOutOfBoundsException e) {
throw new RaiseException(coreExceptions().indexError("invalid index", this));
}
}

}

}