Skip to content

Commit

Permalink
[Truffle] Made TaintResultNode work more like freezing and lowering f…
Browse files Browse the repository at this point in the history
…ixnums.
  • Loading branch information
nirvdrum committed Mar 5, 2015
1 parent fdbfa5a commit d258589
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 36 deletions.
Expand Up @@ -16,8 +16,6 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
import org.jruby.truffle.nodes.objects.IsTaintedNode;
import org.jruby.truffle.nodes.objects.IsTaintedNodeFactory;
import org.jruby.truffle.nodes.objects.TaintNode;
Expand All @@ -28,28 +26,27 @@

public class TaintResultNode extends RubyNode {

private final boolean needsSelf;
private final int taintSourceIndex;
private final boolean taintFromSelf;
private final int[] taintFromParameters;
private final ConditionProfile taintProfile = ConditionProfile.createBinaryProfile();

@Child private RubyNode method;
@Child private IsTaintedNode isTaintedNode;
@Child private TaintNode taintNode;

public TaintResultNode(RubyContext context, SourceSection sourceSection, boolean needSelf, int taintSourceIndex, RubyNode method) {
super(context, sourceSection);
this.needsSelf = needSelf;
this.taintSourceIndex = taintSourceIndex;
public TaintResultNode(boolean taintFromSelf, int[] taintFromParameters, RubyNode method) {
super(method.getContext(), method.getEncapsulatingSourceSection());
this.taintFromSelf = taintFromSelf;
this.taintFromParameters = taintFromParameters;
this.method = method;
this.isTaintedNode = IsTaintedNodeFactory.create(context, sourceSection, null);
this.isTaintedNode = IsTaintedNodeFactory.create(getContext(), getSourceSection(), null);
}

public TaintResultNode(TaintResultNode prev) {
super(prev);
needsSelf = prev.needsSelf;
taintSourceIndex = prev.taintSourceIndex;
method = prev.method;
isTaintedNode = prev.isTaintedNode;
public TaintResultNode(RubyContext context, SourceSection sourceSection, boolean taintFromSelf, int[] taintFromParameters) {
super(context, sourceSection);
this.taintFromSelf = taintFromSelf;
this.taintFromParameters = taintFromParameters;
this.isTaintedNode = IsTaintedNodeFactory.create(getContext(), getSourceSection(), null);
}

public Object maybeTaint(RubyBasicObject source, RubyBasicObject result) {
Expand All @@ -76,16 +73,15 @@ public Object execute(VirtualFrame frame) {
}

if (result != getContext().getCoreLibrary().getNilObject()) {
final RubyBasicObject taintSource;

if (needsSelf && taintSourceIndex == 0) {
taintSource = (RubyBasicObject) RubyArguments.getSelf(frame.getArguments());
} else {
final int adjustedIndex = needsSelf ? taintSourceIndex - 1 : taintSourceIndex;
taintSource = (RubyBasicObject) RubyArguments.getUserArgument(frame.getArguments(), adjustedIndex);
if (taintFromSelf) {
maybeTaint((RubyBasicObject) RubyArguments.getSelf(frame.getArguments()), result);
}

maybeTaint(taintSource, result);
for (int i = 0; i < taintFromParameters.length; i++) {
final RubyBasicObject taintSource =
(RubyBasicObject) RubyArguments.getUserArgument(frame.getArguments(), taintFromParameters[i]);
maybeTaint(taintSource, result);

This comment has been minimized.

Copy link
@eregon

eregon Mar 5, 2015

Member

@ExplodeLoop sounds good for this. Also, I think most cases will not use multiple parameters so I would have just one int if there is no major use case.

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Mar 5, 2015

Contributor

Yes definitely explode this.

}
}

return result;
Expand Down
Expand Up @@ -58,7 +58,9 @@

int[] lowerFixnumParameters() default {};

int taintFrom() default -1;
boolean taintFromSelf() default false;

int[] taintFromParameters() default {};

boolean raiseIfFrozenSelf() default false;

Expand Down
Expand Up @@ -210,9 +210,10 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, arity);
RubyNode sequence = SequenceNode.sequence(context, sourceSection, checkArity, methodNode);

final int taintSource = methodDetails.getMethodAnnotation().taintFrom();
if (taintSource != -1) {
sequence = new TaintResultNode(context, sourceSection, needsSelf, taintSource, sequence);
if (methodDetails.getMethodAnnotation().taintFromSelf() || methodDetails.getMethodAnnotation().taintFromParameters().length > 0) {
sequence = new TaintResultNode(methodDetails.getMethodAnnotation().taintFromSelf(),
methodDetails.getMethodAnnotation().taintFromParameters(),
sequence);
}

final ExceptionTranslatingNode exceptionTranslatingNode = new ExceptionTranslatingNode(context, sourceSection, sequence, methodDetails.getMethodAnnotation().unsupportedOperationBehavior());
Expand Down
Expand Up @@ -413,7 +413,7 @@ public RubyClass getClass(Object self) {

}

@CoreMethod(names = "clone", taintFrom = 0)
@CoreMethod(names = "clone", taintFromSelf = true)
public abstract static class CloneNode extends CoreMethodNode {

private final ConditionProfile frozenProfile = ConditionProfile.createBinaryProfile();
Expand Down Expand Up @@ -460,7 +460,7 @@ public Object clone(VirtualFrame frame, RubyBasicObject self) {

}

@CoreMethod(names = "dup", taintFrom = 0)
@CoreMethod(names = "dup", taintFromSelf = true)
public abstract static class DupNode extends CoreMethodNode {

@Child private CallDispatchHeadNode initializeDupNode;
Expand Down
Expand Up @@ -32,7 +32,7 @@
@CoreClass(name = "MatchData")
public abstract class MatchDataNodes {

@CoreMethod(names = "[]", required = 1, lowerFixnumParameters = 0, taintFrom = 0)
@CoreMethod(names = "[]", required = 1, lowerFixnumParameters = 0, taintFromSelf = true)
public abstract static class GetIndexNode extends CoreMethodNode {

@Child private ToIntNode toIntNode;
Expand Down
Expand Up @@ -223,7 +223,7 @@ public RubyString match(RubyRegexp regexp) {

}

@CoreMethod(names = "match", required = 1, taintFrom = 0)
@CoreMethod(names = "match", required = 1, taintFromSelf = true)
public abstract static class MatchNode extends CoreMethodNode {

public MatchNode(RubyContext context, SourceSection sourceSection) {
Expand Down
Expand Up @@ -200,7 +200,7 @@ public Object compare(VirtualFrame frame, RubyString a, Object b) {
}
}

@CoreMethod(names = { "<<", "concat" }, required = 1, taintFrom = 1, raiseIfFrozenSelf = true)
@CoreMethod(names = { "<<", "concat" }, required = 1, taintFromParameters = 0, raiseIfFrozenSelf = true)
@NodeChildren({
@NodeChild(value = "string"),
@NodeChild(value = "other")
Expand Down Expand Up @@ -278,7 +278,7 @@ private RubyString formatSlow(RubyString format, Object[] args) {
}
}

@CoreMethod(names = {"[]", "slice"}, required = 1, optional = 1, lowerFixnumParameters = {0, 1}, taintFrom = 0)
@CoreMethod(names = {"[]", "slice"}, required = 1, optional = 1, lowerFixnumParameters = {0, 1}, taintFromSelf = true)
public abstract static class GetIndexNode extends CoreMethodNode {

@Child private ToIntNode toIntNode;
Expand Down Expand Up @@ -570,7 +570,7 @@ public boolean asciiOnly(RubyString string) {
}
}

@CoreMethod(names = "b", taintFrom = 0)
@CoreMethod(names = "b", taintFromSelf = true)
public abstract static class BNode extends CoreMethodNode {

public BNode(RubyContext context, SourceSection sourceSection) {
Expand Down Expand Up @@ -1209,7 +1209,7 @@ public RubyString ljust(RubyString string, int length, RubyString padding) {

}

@CoreMethod(names = "match", required = 1, taintFrom = 0)
@CoreMethod(names = "match", required = 1, taintFromSelf = true)
public abstract static class MatchNode extends CoreMethodNode {

@Child private CallDispatchHeadNode regexpMatchNode;
Expand Down
Expand Up @@ -73,7 +73,7 @@ public static abstract class StringByteSubstringPrimitiveNode extends RubiniusPr

public StringByteSubstringPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
taintResultNode = new TaintResultNode(context, sourceSection, true, 0, null);
taintResultNode = new TaintResultNode(context, sourceSection, true, new int[]{});
}

public StringByteSubstringPrimitiveNode(StringByteSubstringPrimitiveNode prev) {
Expand Down

0 comments on commit d258589

Please sign in to comment.