From ff3383c272888932463a267d8276191498f1b61c Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Wed, 9 Nov 2016 14:51:02 +0100 Subject: [PATCH] further cleanups in replacement and write variable nodes --- .../r/nodes/builtin/base/AllNames.java | 3 +- .../truffle/r/nodes/builtin/base/Call.java | 1 - .../oracle/truffle/r/nodes/RASTBuilder.java | 97 ++++++---------- .../r/nodes/access/BaseWriteVariableNode.java | 7 +- .../access/WriteSuperFrameVariableNode.java | 107 ++++++++++-------- .../nodes/access/WriteSuperVariableNode.java | 96 ---------------- .../r/nodes/access/WriteVariableNode.java | 20 +--- .../access/WriteVariableNodeSyntaxHelper.java | 53 --------- ...Node.java => WriteVariableSyntaxNode.java} | 70 ++++++------ .../truffle/r/nodes/control/ForNode.java | 18 +-- .../control/ReplacementDispatchNode.java | 85 ++++---------- .../r/nodes/control/ReplacementNode.java | 33 ++---- 12 files changed, 180 insertions(+), 410 deletions(-) delete mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java delete mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNodeSyntaxHelper.java rename com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/{WriteCurrentVariableNode.java => WriteVariableSyntaxNode.java} (53%) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java index 905fb5e0d0..053928da25 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java @@ -46,6 +46,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; @RBuiltin(name = "all.names", kind = INTERNAL, parameterNames = {"expr", "functions", "max.names", "unique"}, behavior = PURE) @@ -133,7 +134,7 @@ public abstract class AllNames extends RBuiltinNode { @Override protected Void visit(RSyntaxFunction element) { - accept(RSyntaxLookup.createDummyLookup(null, "function", true)); + accept(RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, "function", true)); accept(element.getSyntaxBody()); // functions do not recurse into the arguments return null; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java index 4944158701..b219b18a59 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java @@ -36,7 +36,6 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java index c39d5e67c5..441422963f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java @@ -41,7 +41,6 @@ import com.oracle.truffle.r.nodes.control.IfNode; import com.oracle.truffle.r.nodes.control.NextNode; import com.oracle.truffle.r.nodes.control.RepeatNode; import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode; -import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode.LHSError; import com.oracle.truffle.r.nodes.control.WhileNode; import com.oracle.truffle.r.nodes.function.FormalArguments; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; @@ -54,7 +53,6 @@ import com.oracle.truffle.r.nodes.function.WrapDefaultArgumentNode; import com.oracle.truffle.r.nodes.function.signature.MissingNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; -import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; import com.oracle.truffle.r.runtime.data.REmpty; @@ -62,8 +60,6 @@ import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.EvaluatedArgumentsVisitor; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; -import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @@ -96,27 +92,28 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { @Override public RSyntaxNode call(SourceSection source, RSyntaxNode lhs, List<Argument<RSyntaxNode>> args) { if (lhs instanceof RSyntaxLookup) { - String symbol = ((RSyntaxLookup) lhs).getIdentifier(); + RSyntaxLookup lhsLookup = (RSyntaxLookup) lhs; + String symbol = lhsLookup.getIdentifier(); if (args.size() == 0) { switch (symbol) { case "break": - return new BreakNode(source, lhs); + return new BreakNode(source, lhsLookup); case "next": - return new NextNode(source, lhs); + return new NextNode(source, lhsLookup); } } else if (args.size() == 1) { switch (symbol) { case "repeat": - return new RepeatNode(source, lhs, args.get(0).value); + return new RepeatNode(source, lhsLookup, args.get(0).value); case "(": return args.get(0).value; } } else if (args.size() == 2) { switch (symbol) { case "while": - return new WhileNode(source, lhs, args.get(0).value, args.get(1).value); + return new WhileNode(source, lhsLookup, args.get(0).value, args.get(1).value); case "if": - return new IfNode(source, lhs, args.get(0).value, args.get(1).value, null); + return new IfNode(source, lhsLookup, args.get(0).value, args.get(1).value, null); case "=": case "<-": case ":=": @@ -125,63 +122,38 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { case "->>": boolean isSuper = "<<-".equals(symbol) || "->>".equals(symbol); boolean switchArgs = "->".equals(symbol) || "->>".equals(symbol); - RSyntaxLookup operator = (RSyntaxLookup) lhs; // fix the operators while keeping the correct source sections if ("->>".equals(symbol)) { - operator = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<<-"); + lhsLookup = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<<-"); } else if ("->".equals(symbol)) { - operator = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<-"); + lhsLookup = ReadVariableNode.createForcedFunctionLookup(lhs.getLazySourceSection(), "<-"); } - return createReplacement(source, operator, isSuper, args.get(switchArgs ? 1 : 0).value, args.get(switchArgs ? 0 : 1).value); + // switch the args if needed + RSyntaxNode lhsArg = args.get(switchArgs ? 1 : 0).value; + RSyntaxNode rhsArg = args.get(switchArgs ? 0 : 1).value; + return new ReplacementDispatchNode(source, lhsLookup, lhsArg, rhsArg, isSuper, context.getReplacementVarsStartIndex()); } } else if (args.size() == 3) { switch (symbol) { case "for": if (args.get(0).value instanceof RSyntaxLookup) { - String name = ((RSyntaxLookup) args.get(0).value).getIdentifier(); - WriteVariableNode cvar = WriteVariableNode.create(source, name, null, false); - return new ForNode(source, lhs, cvar, args.get(1).value.asRNode(), args.get(2).value.asRNode()); + RSyntaxLookup var = (RSyntaxLookup) args.get(0).value; + return new ForNode(source, lhsLookup, var, args.get(1).value.asRNode(), args.get(2).value.asRNode()); } break; case "if": - return new IfNode(source, lhs, args.get(0).value, args.get(1).value, args.get(2).value); + return new IfNode(source, lhsLookup, args.get(0).value, args.get(1).value, args.get(2).value); } } switch (symbol) { case "{": - return new BlockNode(source, lhs, args.stream().map(n -> n.value.asRNode()).toArray(RNode[]::new)); + return new BlockNode(source, lhsLookup, args.stream().map(n -> n.value.asRNode()).toArray(RNode[]::new)); case "missing": - return new MissingNode(source, lhs, createSignature(args), args.stream().map(a -> a.value).toArray(RSyntaxElement[]::new)); + return new MissingNode(source, lhsLookup, createSignature(args), args.stream().map(a -> a.value).toArray(RSyntaxElement[]::new)); } } - ArgumentsSignature signature = createSignature(args); - RSyntaxNode[] nodes = args.stream().map( - arg -> (arg.value == null && arg.name == null) ? ConstantNode.create(arg.source == null ? RSyntaxNode.SOURCE_UNAVAILABLE : arg.source, REmpty.instance) : arg.value).toArray( - RSyntaxNode[]::new); - - return RCallSpecialNode.createCall(source, lhs.asRNode(), signature, nodes); - } - - private RSyntaxNode createReplacement(SourceSection source, RSyntaxLookup operator, boolean isSuper, RSyntaxNode replacementLhs, RSyntaxNode replacementRhs) { - if (replacementLhs instanceof RSyntaxCall) { - return createReplacement(source, replacementLhs, replacementRhs, operator, isSuper); - } else { - String name; - if (replacementLhs instanceof RSyntaxLookup) { - name = ((RSyntaxLookup) replacementLhs).getIdentifier(); - } else if (replacementLhs instanceof RSyntaxConstant) { - RSyntaxConstant c = (RSyntaxConstant) replacementLhs; - if (c.getValue() instanceof String) { - name = (String) c.getValue(); - } else { - return new LHSError(source, operator, replacementLhs, replacementRhs); - } - } else { - throw RInternalError.unimplemented("unexpected lhs type: " + replacementLhs.getClass()); - } - return (RSyntaxNode) WriteVariableNode.create(source, name, replacementRhs.asRNode(), isSuper); - } + return RCallSpecialNode.createCall(source, lhs.asRNode(), createSignature(args), createArguments(args)); } private static ArgumentsSignature createSignature(List<Argument<RSyntaxNode>> args) { @@ -190,6 +162,15 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { return signature; } + private static RSyntaxNode[] createArguments(List<Argument<RSyntaxNode>> args) { + RSyntaxNode[] nodes = new RSyntaxNode[args.size()]; + for (int i = 0; i < nodes.length; i++) { + Argument<RSyntaxNode> arg = args.get(i); + nodes[i] = (arg.value == null && arg.name == null) ? ConstantNode.create(arg.source == null ? RSyntaxNode.SOURCE_UNAVAILABLE : arg.source, REmpty.instance) : arg.value; + } + return nodes; + } + private static String getFunctionDescription(SourceSection source, Object assignedTo) { if (assignedTo instanceof String) { return (String) assignedTo; @@ -201,10 +182,6 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { } } - private RSyntaxNode createReplacement(SourceSection source, RSyntaxNode lhs, RSyntaxNode rhs, RSyntaxElement operator, boolean isSuper) { - return new ReplacementDispatchNode(source, operator, lhs, rhs, isSuper, this.context.getReplacementVarsStartIndex()); - } - public static FastPathFactory createFunctionFastPath(RSyntaxElement body, ArgumentsSignature signature) { return EvaluatedArgumentsVisitor.process(body, signature); } @@ -300,21 +277,19 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { } @Override - public RSyntaxNode lookup(SourceSection sourceIn, String symbol, boolean functionLookup) { + public RSyntaxNode lookup(SourceSection source, String symbol, boolean functionLookup) { + assert source != null; if (constants != null && symbol.startsWith("C")) { Object object = constants.get(symbol); if (object != null) { - return ConstantNode.create(sourceIn, object); + return ConstantNode.create(source, object); } } - /* - * TODO Ideally, sourceIn != null always, however ReplacementNodes can cause this on the - * rewrite nodes. - */ - SourceSection source = sourceIn == null ? RSyntaxNode.INTERNAL : sourceIn; - if (!functionLookup && getVariadicComponentIndex(symbol) != -1) { - int ind = getVariadicComponentIndex(symbol); - return new ReadVariadicComponentNode(source, ind > 0 ? ind - 1 : ind); + if (!functionLookup) { + int index = getVariadicComponentIndex(symbol); + if (index != -1) { + return new ReadVariadicComponentNode(source, index > 0 ? index - 1 : index); + } } return functionLookup ? ReadVariableNode.createForcedFunctionLookup(source, symbol) : ReadVariableNode.create(source, symbol, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java index 98ed65cc09..52fa750d03 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java @@ -30,7 +30,6 @@ import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotKind; import com.oracle.truffle.api.frame.FrameSlotTypeException; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; @@ -122,17 +121,17 @@ abstract class BaseWriteVariableNode extends WriteVariableNode { } @SuppressWarnings("unused") - protected boolean isLogicalKind(VirtualFrame frame, FrameSlot frameSlot) { + protected boolean isLogicalKind(Frame frame, FrameSlot frameSlot) { return isKind(frameSlot, FrameSlotKind.Boolean); } @SuppressWarnings("unused") - protected boolean isIntegerKind(VirtualFrame frame, FrameSlot frameSlot) { + protected boolean isIntegerKind(Frame frame, FrameSlot frameSlot) { return isKind(frameSlot, FrameSlotKind.Int); } @SuppressWarnings("unused") - protected boolean isDoubleKind(VirtualFrame frame, FrameSlot frameSlot) { + protected boolean isDoubleKind(Frame frame, FrameSlot frameSlot) { return isKind(frameSlot, FrameSlotKind.Double); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java index d5243f1b97..c3d06849fa 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java @@ -27,7 +27,6 @@ import static com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.find 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.NodeField; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotKind; @@ -37,7 +36,7 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNodeFactory.UnresolvedWriteLocalFrameVariableNodeGen; -import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode; +import com.oracle.truffle.r.nodes.access.WriteSuperFrameVariableNodeFactory.ResolvedWriteSuperFrameVariableNodeGen; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -49,59 +48,75 @@ import com.oracle.truffle.r.runtime.nodes.RNode; * * The state starts out a "unresolved" and transforms to "resolved". */ -@SuppressWarnings("unused") -@NodeChildren({@NodeChild(value = "enclosingFrame", type = AccessEnclosingFrameNode.class), @NodeChild(value = "frameSlotNode", type = FrameSlotNode.class)}) -@NodeField(name = "mode", type = Mode.class) -abstract class WriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHelper { - private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile(); - private final BranchProfile invalidateProfile = BranchProfile.create(); - private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); - - protected abstract FrameSlotNode getFrameSlotNode(); - - public abstract Mode getMode(); +abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode { static WriteVariableNode create(String name, RNode rhs, Mode mode) { return new UnresolvedWriteSuperFrameVariableNode(name, rhs, mode); } - @Specialization(guards = "isLogicalKind(frame, frameSlot)") - protected void doLogical(VirtualFrame frame, byte value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { - FrameSlotChangeMonitor.setByteAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); - } + protected abstract void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame); - @Specialization(guards = "isIntegerKind(frame, frameSlot)") - protected void doInteger(VirtualFrame frame, int value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { - FrameSlotChangeMonitor.setIntAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); + @Override + public final Object execute(VirtualFrame frame) { + Object value = getRhs().execute(frame); + execute(frame, value); + return value; } - @Specialization(guards = "isDoubleKind(frame, frameSlot)") - protected void doDouble(VirtualFrame frame, double value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { - FrameSlotChangeMonitor.setDoubleAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); - } + @NodeChildren({@NodeChild(value = "enclosingFrame", type = AccessEnclosingFrameNode.class), @NodeChild(value = "frameSlotNode", type = FrameSlotNode.class)}) + protected abstract static class ResolvedWriteSuperFrameVariableNode extends WriteSuperFrameVariableNode { + + private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile(); + private final BranchProfile invalidateProfile = BranchProfile.create(); + private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); + + private final Mode mode; + + public ResolvedWriteSuperFrameVariableNode(Mode mode) { + this.mode = mode; + } - @Specialization - protected void doObject(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { - MaterializedFrame profiledFrame = enclosingFrameProfile.profile(enclosingFrame); - Object newValue = shareObjectValue(profiledFrame, frameSlot, storedObjectProfile.profile(value), getMode(), true); - FrameSlotChangeMonitor.setObjectAndInvalidate(profiledFrame, frameSlot, newValue, true, invalidateProfile); + protected abstract FrameSlotNode getFrameSlotNode(); + + @Specialization(guards = "isLogicalKind(enclosingFrame, frameSlot)") + protected void doLogical(byte value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { + FrameSlotChangeMonitor.setByteAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); + } + + @Specialization(guards = "isIntegerKind(enclosingFrame, frameSlot)") + protected void doInteger(int value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { + FrameSlotChangeMonitor.setIntAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); + } + + @Specialization(guards = "isDoubleKind(enclosingFrame, frameSlot)") + protected void doDouble(double value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { + FrameSlotChangeMonitor.setDoubleAndInvalidate(enclosingFrameProfile.profile(enclosingFrame), frameSlot, value, true, invalidateProfile); + } + + @Specialization + protected void doObject(Object value, MaterializedFrame enclosingFrame, FrameSlot frameSlot) { + MaterializedFrame profiledFrame = enclosingFrameProfile.profile(enclosingFrame); + Object newValue = shareObjectValue(profiledFrame, frameSlot, storedObjectProfile.profile(value), mode, true); + FrameSlotChangeMonitor.setObjectAndInvalidate(profiledFrame, frameSlot, newValue, true, invalidateProfile); + } } - private static class UnresolvedWriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHelper { + private static final class UnresolvedWriteSuperFrameVariableNode extends WriteSuperFrameVariableNode { @Child private RNode rhs; - private final String symbol; - private final BaseWriteVariableNode.Mode mode; - UnresolvedWriteSuperFrameVariableNode(String symbol, RNode rhs, BaseWriteVariableNode.Mode mode) { + private final String name; + private final Mode mode; + + UnresolvedWriteSuperFrameVariableNode(String name, RNode rhs, Mode mode) { this.rhs = rhs; - this.symbol = symbol; + this.name = name; this.mode = mode; } @Override public String getName() { - return symbol; + return name; } @Override @@ -112,21 +127,21 @@ abstract class WriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHe @Override public void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame) { CompilerDirectives.transferToInterpreterAndInvalidate(); - if (getName().isEmpty()) { + if (name.isEmpty()) { throw RError.error(RError.NO_CALLER, RError.Message.ZERO_LENGTH_VARIABLE); } - final WriteSuperFrameVariableNodeHelper writeNode; + final WriteSuperFrameVariableNode writeNode; if (REnvironment.isGlobalEnvFrame(enclosingFrame)) { /* * we've reached the global scope, do unconditional write. if this is the first node * in the chain, needs the rhs and enclosingFrame nodes */ AccessEnclosingFrameNode enclosingFrameNode = RArguments.getEnclosingFrame(frame) == enclosingFrame ? new AccessEnclosingFrameNode() : null; - writeNode = WriteSuperFrameVariableNodeGen.create(getRhs(), enclosingFrameNode, - FrameSlotNode.create(findOrAddFrameSlot(enclosingFrame.getFrameDescriptor(), symbol, FrameSlotKind.Illegal)), getName(), mode); + writeNode = ResolvedWriteSuperFrameVariableNodeGen.create(mode, rhs, enclosingFrameNode, + FrameSlotNode.create(findOrAddFrameSlot(enclosingFrame.getFrameDescriptor(), name, FrameSlotKind.Illegal)), name); } else { - WriteSuperFrameVariableNode actualWriteNode = WriteSuperFrameVariableNodeGen.create(null, null, FrameSlotNode.create(symbol), this.getName(), mode); - writeNode = new WriteSuperFrameVariableConditionalNode(actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(symbol, null, mode), getRhs()); + ResolvedWriteSuperFrameVariableNode actualWriteNode = ResolvedWriteSuperFrameVariableNodeGen.create(mode, null, null, FrameSlotNode.create(name), name); + writeNode = new WriteSuperFrameVariableConditionalNode(actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(name, null, mode), rhs); } replace(writeNode).execute(frame, value, enclosingFrame); } @@ -139,22 +154,22 @@ abstract class WriteSuperFrameVariableNode extends WriteSuperFrameVariableNodeHe execute(frame, value, enclosingFrame); } else { // we're in global scope, do a local write instead - replace(UnresolvedWriteLocalFrameVariableNodeGen.create(getRhs(), symbol, mode)).execute(frame, value); + replace(UnresolvedWriteLocalFrameVariableNodeGen.create(rhs, name, mode)).execute(frame, value); } } } - public static class WriteSuperFrameVariableConditionalNode extends WriteSuperFrameVariableNodeHelper { + private static final class WriteSuperFrameVariableConditionalNode extends WriteSuperFrameVariableNode { - @Child private WriteSuperFrameVariableNode writeNode; - @Child private WriteSuperFrameVariableNodeHelper nextNode; + @Child private ResolvedWriteSuperFrameVariableNode writeNode; + @Child private WriteSuperFrameVariableNode nextNode; @Child private RNode rhs; private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); private final ConditionProfile hasValueProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile nullSuperFrameProfile = ConditionProfile.createBinaryProfile(); - WriteSuperFrameVariableConditionalNode(WriteSuperFrameVariableNode writeNode, WriteSuperFrameVariableNodeHelper nextNode, RNode rhs) { + WriteSuperFrameVariableConditionalNode(ResolvedWriteSuperFrameVariableNode writeNode, WriteSuperFrameVariableNode nextNode, RNode rhs) { this.writeNode = writeNode; this.nextNode = nextNode; this.rhs = rhs; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java deleted file mode 100644 index dbbeb43fd0..0000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperVariableNode.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.nodes.access; - -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.NodeCost; -import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; -import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; -import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; -import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; - -/** - * The "syntax" variant corresponding to {@code x <<- y} in the source. - * - * Owing to type hierarchy restrictions (and lack of multiple (state) inheritance) this cannot - * extend {@link RSourceSectionNode}, so we store the field in {@link WriteVariableNodeSyntaxHelper} - * . - */ -@NodeInfo(cost = NodeCost.NONE) -public class WriteSuperVariableNode extends WriteVariableNodeSyntaxHelper implements RSyntaxNode, RSyntaxCall { - - @Child private WriteVariableNode writeSuperFrameVariableNode; - @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); - - protected WriteSuperVariableNode(SourceSection src, String name, RNode rhs) { - super(src); - writeSuperFrameVariableNode = WriteSuperFrameVariableNode.create(name, rhs, Mode.REGULAR); - } - - static WriteSuperVariableNode create(SourceSection src, String name, RNode rhs) { - return new WriteSuperVariableNode(src, name, rhs); - } - - @Override - public Object getName() { - return writeSuperFrameVariableNode.getName(); - } - - @Override - public RNode getRhs() { - return writeSuperFrameVariableNode.getRhs(); - } - - @Override - public Object execute(VirtualFrame frame) { - Object result = writeSuperFrameVariableNode.execute(frame); - visibility.execute(frame, false); - return result; - } - - @Override - public void execute(VirtualFrame frame, Object value) { - writeSuperFrameVariableNode.execute(frame, value); - } - - @Override - public RSyntaxElement getSyntaxLHS() { - return RSyntaxLookup.createDummyLookup(null, "<<-", true); - } - - @Override - public RSyntaxElement[] getSyntaxArguments() { - return new RSyntaxElement[]{RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, (String) getName(), false), getRhs().asRSyntaxNode()}; - } - - @Override - public ArgumentsSignature getSyntaxSignature() { - return ArgumentsSignature.empty(2); - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java index 3f761e2308..d8bd5afed8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java @@ -23,18 +23,21 @@ package com.oracle.truffle.r.nodes.access; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; /** * The base of the {@code WriteVariableNode} type hierarchy. There are several variants for * different situations and this class provides static methods to create these. + * + * The types in this hierarchy do not implement {@link RSyntaxElement} - use + * {@link WriteVariableSyntaxNode} instead. */ public abstract class WriteVariableNode extends RNode { - public enum Mode { + public enum Mode { REGULAR, COPY, INVISIBLE @@ -46,19 +49,6 @@ public abstract class WriteVariableNode extends RNode { public abstract void execute(VirtualFrame frame, Object value); - /** - * Variant for a variable that appears in the R language source. - * - * @param isSuper {@code true} if the write is {@code <<-}. - */ - public static WriteVariableNode create(SourceSection src, String name, RNode rhs, boolean isSuper) { - if (isSuper) { - return WriteSuperVariableNode.create(src, name, rhs); - } else { - return WriteCurrentVariableNode.create(src, name, rhs); - } - } - /** * Variant for saving function arguments, i.e. from {@link RArguments} into the frame. */ diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNodeSyntaxHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNodeSyntaxHelper.java deleted file mode 100644 index a463662841..0000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNodeSyntaxHelper.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.nodes.access; - -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.runtime.RDeparse; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; - -abstract class WriteVariableNodeSyntaxHelper extends WriteVariableNode implements RSyntaxNode { - @CompilationFinal private SourceSection sourceSectionR; - - protected WriteVariableNodeSyntaxHelper(SourceSection sourceSection) { - assert sourceSection != null; - this.sourceSectionR = sourceSection; - } - - @Override - public void setSourceSection(SourceSection sourceSection) { - this.sourceSectionR = sourceSection; - } - - @Override - public SourceSection getLazySourceSection() { - return sourceSectionR; - } - - @Override - public SourceSection getSourceSection() { - RDeparse.ensureSourceSection(this); - return sourceSectionR; - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java similarity index 53% rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java rename to com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java index f3503c82e5..a442c0747a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteCurrentVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java @@ -22,66 +22,62 @@ */ package com.oracle.truffle.r.nodes.access; +import static com.oracle.truffle.api.nodes.NodeCost.NONE; + import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode; +import com.oracle.truffle.r.nodes.control.OperatorNode; import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; -/** - * The "syntax" variant corresponding to {@code x <- y} in the source. - */ -@NodeInfo(cost = NodeCost.NONE) -public class WriteCurrentVariableNode extends WriteVariableNodeSyntaxHelper implements RSyntaxNode, RSyntaxCall { +@NodeInfo(cost = NONE) +public final class WriteVariableSyntaxNode extends OperatorNode { - @Child private WriteLocalFrameVariableNode writeLocalFrameVariableNode; + @Child private WriteVariableNode write; @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); - protected WriteCurrentVariableNode(SourceSection src, String name, RNode rhs) { - super(src); - writeLocalFrameVariableNode = WriteLocalFrameVariableNode.create(name, rhs, Mode.REGULAR); - } - - static WriteCurrentVariableNode create(SourceSection src, String name, RNode rhs) { - return new WriteCurrentVariableNode(src, name, rhs); - } + private final RSyntaxElement lhs; - @Override - public Object getName() { - return writeLocalFrameVariableNode.getName(); - } - - @Override - public RNode getRhs() { - return writeLocalFrameVariableNode.getRhs(); + public WriteVariableSyntaxNode(SourceSection source, RSyntaxLookup operator, RSyntaxElement lhs, RNode rhs, boolean isSuper) { + super(source, operator); + this.lhs = lhs; + String name; + if (lhs instanceof RSyntaxLookup) { + name = ((RSyntaxLookup) lhs).getIdentifier(); + } else if (lhs instanceof RSyntaxConstant) { + RSyntaxConstant c = (RSyntaxConstant) lhs; + if (c.getValue() instanceof String) { + name = (String) c.getValue(); + } else { + // "this" needs to be initialized for error reporting to work + this.write = WriteVariableNode.createAnonymous("dummy", rhs, Mode.REGULAR, isSuper); + throw RError.error(this, RError.Message.INVALID_LHS, "do_set"); + } + } else { + throw RInternalError.unimplemented("unexpected lhs type in replacement: " + lhs.getClass()); + } + this.write = WriteVariableNode.createAnonymous(name, rhs, Mode.REGULAR, isSuper); + assert write != null; } @Override public Object execute(VirtualFrame frame) { - Object result = writeLocalFrameVariableNode.execute(frame); + Object result = write.execute(frame); visibility.execute(frame, false); return result; } - @Override - public void execute(VirtualFrame frame, Object value) { - writeLocalFrameVariableNode.execute(frame, value); - } - - @Override - public RSyntaxElement getSyntaxLHS() { - return RSyntaxLookup.createDummyLookup(null, "<-", true); - } - @Override public RSyntaxElement[] getSyntaxArguments() { - return new RSyntaxElement[]{RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, (String) getName(), false), getRhs().asRSyntaxNode()}; + return new RSyntaxElement[]{lhs, write.getRhs().asRSyntaxNode()}; } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java index 6e316b4d3d..a49df510c7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java @@ -53,8 +53,11 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn @Child private LoopNode loopNode; @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); - public ForNode(SourceSection src, RSyntaxElement operator, WriteVariableNode cvar, RNode range, RNode body) { + private final RSyntaxLookup var; + + public ForNode(SourceSection src, RSyntaxLookup operator, RSyntaxLookup var, RNode range, RNode body) { super(src, operator); + this.var = var; String indexName = AnonymousFrameVariable.create("FOR_INDEX"); String rangeName = AnonymousFrameVariable.create("FOR_RANGE"); String lengthName = AnonymousFrameVariable.create("FOR_LENGTH"); @@ -62,7 +65,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, null, Mode.REGULAR); this.writeRangeNode = WriteVariableNode.createAnonymous(rangeName, range, Mode.REGULAR); this.writeLengthNode = WriteVariableNode.createAnonymous(lengthName, RLengthNodeGen.create(ReadVariableNode.create(rangeName)), Mode.REGULAR); - this.loopNode = Truffle.getRuntime().createLoopNode(new ForRepeatingNode(this, cvar, body, indexName, lengthName, rangeName)); + this.loopNode = Truffle.getRuntime().createLoopNode(new ForRepeatingNode(this, var.getIdentifier(), body, indexName, lengthName, rangeName)); } @Override @@ -87,19 +90,17 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn @Child private ReadVariableNode readIndexNode; @Child private ReadVariableNode readLengthNode; @Child private WriteVariableNode writeIndexNode; - @Child private RNode loadElement; private final ForNode forNode; - ForRepeatingNode(ForNode forNode, WriteVariableNode cvar, RNode body, String indexName, String lengthName, String rangeName) { + ForRepeatingNode(ForNode forNode, String var, RNode body, String indexName, String lengthName, String rangeName) { this.forNode = forNode; - this.writeElementNode = cvar; + this.writeElementNode = WriteVariableNode.createAnonymous(var, createIndexedLoad(indexName, rangeName), Mode.REGULAR, false); this.body = body; this.readIndexNode = ReadVariableNode.create(indexName); this.readLengthNode = ReadVariableNode.create(lengthName); this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, null, Mode.REGULAR); - this.loadElement = createIndexedLoad(indexName, rangeName); // pre-initialize the profile so that loop exits to not deoptimize conditionProfile.profile(false); } @@ -124,7 +125,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn } try { if (conditionProfile.profile(index <= length)) { - writeElementNode.execute(frame, loadElement.execute(frame)); + writeElementNode.execute(frame); body.execute(frame); return true; } else { @@ -150,8 +151,7 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn @Override public RSyntaxElement[] getSyntaxArguments() { ForRepeatingNode repeatingNode = (ForRepeatingNode) loopNode.getRepeatingNode(); - return new RSyntaxElement[]{RSyntaxLookup.createDummyLookup(null, (String) repeatingNode.writeElementNode.getName(), false), writeRangeNode.getRhs().asRSyntaxNode(), - repeatingNode.body.asRSyntaxNode()}; + return new RSyntaxElement[]{var, writeRangeNode.getRhs().asRSyntaxNode(), repeatingNode.body.asRSyntaxNode()}; } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java index d726f51153..689bacaeac 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java @@ -33,11 +33,13 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.WriteVariableNode; +import com.oracle.truffle.r.nodes.access.WriteVariableSyntaxNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -52,18 +54,18 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; */ public final class ReplacementDispatchNode extends OperatorNode { - @Child private ReplacementNode replacementNode; + // these are only @Child to make instrumentation work + @Child private RNode lhs; + @Child private RNode rhs; - private final RSyntaxNode lhs; - private final RSyntaxNode rhs; private final boolean isSuper; private final int tempNamesStartIndex; - public ReplacementDispatchNode(SourceSection src, RSyntaxElement operator, RSyntaxNode lhs, RSyntaxNode rhs, boolean isSuper, int tempNamesStartIndex) { + public ReplacementDispatchNode(SourceSection src, RSyntaxLookup operator, RSyntaxNode lhs, RSyntaxNode rhs, boolean isSuper, int tempNamesStartIndex) { super(src, operator); assert lhs != null && rhs != null; - this.lhs = lhs; - this.rhs = rhs; + this.lhs = lhs.asRNode(); + this.rhs = rhs.asRNode(); this.isSuper = isSuper; this.tempNamesStartIndex = tempNamesStartIndex; } @@ -72,21 +74,14 @@ public final class ReplacementDispatchNode extends OperatorNode { public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); - return replace(getReplacementNode()).execute(frame); - } + RNode replacement; + if (lhs instanceof RSyntaxCall) { + replacement = createReplacementNode(); + } else { + replacement = new WriteVariableSyntaxNode(getLazySourceSection(), operator, lhs.asRSyntaxNode(), rhs, isSuper); + } - /** - * Support for syntax tree visitor. - */ - public RSyntaxNode getLhs() { - return lhs; - } - - /** - * Support for syntax tree visitor. - */ - public RSyntaxNode getRhs() { - return rhs; + return replace(replacement).execute(frame); } @Override @@ -96,15 +91,7 @@ public final class ReplacementDispatchNode extends OperatorNode { @Override public RSyntaxElement[] getSyntaxArguments() { - return new RSyntaxElement[]{lhs, rhs}; - } - - private ReplacementNode getReplacementNode() { - if (replacementNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - replacementNode = insert(createReplacementNode()); - } - return replacementNode; + return new RSyntaxElement[]{lhs.asRSyntaxNode(), rhs.asRSyntaxNode()}; } private ReplacementNode createReplacementNode() { @@ -115,7 +102,7 @@ public final class ReplacementDispatchNode extends OperatorNode { * "a(...)" and "b(...)". */ List<RSyntaxCall> calls = new ArrayList<>(); - RSyntaxElement current = lhs; + RSyntaxElement current = lhs.asRSyntaxNode(); while (!(current instanceof RSyntaxLookup)) { if (!(current instanceof RSyntaxCall)) { if (current instanceof RSyntaxConstant && ((RSyntaxConstant) current).getValue() == RNull.instance) { @@ -135,7 +122,7 @@ public final class ReplacementDispatchNode extends OperatorNode { } RSyntaxLookup variable = (RSyntaxLookup) current; ReadVariableNode varRead = createReplacementForVariableUsing(variable, isSuper); - return new ReplacementNode(getLazySourceSection(), operator, varRead, lhs, rhs.asRNode(), calls, "*rhs*" + tempNamesStartIndex, variable.getIdentifier(), isSuper, tempNamesStartIndex); + return new ReplacementNode(getLazySourceSection(), operator, varRead, lhs.asRSyntaxNode(), rhs, calls, "*rhs*" + tempNamesStartIndex, variable.getIdentifier(), isSuper, tempNamesStartIndex); } private static ReadVariableNode createReplacementForVariableUsing(RSyntaxLookup var, boolean isSuper) { @@ -154,10 +141,10 @@ public final class ReplacementDispatchNode extends OperatorNode { RSyntaxCall call = (RSyntaxCall) e; // check for syntax nodes as this will be required to recreate a call during // replacement form construction in createFunctionUpdate - if (call.getSyntaxLHS() instanceof RSyntaxLookup && call.getSyntaxLHS() instanceof RSyntaxNode) { + if (call.getSyntaxLHS() instanceof RSyntaxLookup) { if (((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier().equals("::")) { RSyntaxElement[] args = call.getSyntaxArguments(); - if (args.length == 2 && args[0] instanceof RSyntaxLookup && args[0] instanceof RSyntaxNode && args[1] instanceof RSyntaxLookup && args[1] instanceof RSyntaxNode) { + if (args.length == 2 && args[0] instanceof RSyntaxLookup && args[1] instanceof RSyntaxLookup) { return true; } } @@ -179,36 +166,4 @@ public final class ReplacementDispatchNode extends OperatorNode { } return null; } - - /** - * Used by the parser for assignments that miss a left hand side. This node will raise an error - * once executed. - */ - public static final class LHSError extends OperatorNode { - - private final RSyntaxElement lhs; - private final RSyntaxElement rhs; - - public LHSError(SourceSection sourceSection, RSyntaxLookup operator, RSyntaxElement lhs, RSyntaxElement rhs) { - super(sourceSection, operator); - this.lhs = lhs; - this.rhs = rhs; - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.INVALID_LHS, "do_set"); - } - - @Override - public RSyntaxElement[] getSyntaxArguments() { - return new RSyntaxElement[]{lhs, rhs}; - } - - @Override - public ArgumentsSignature getSyntaxSignature() { - return ArgumentsSignature.empty(2); - } - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java index 9f24797fc4..2e3a23178b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java @@ -27,14 +27,11 @@ import java.util.ArrayList; import java.util.List; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.access.RemoveAndAnswerNode; @@ -49,6 +46,7 @@ import com.oracle.truffle.r.runtime.builtins.RSpecialFactory.FullCallNeededExcep import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.CodeBuilderContext; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; @@ -106,10 +104,6 @@ final class ReplacementNode extends OperatorNode { return rhsValue; } - private ReplacementBase createReplacementNodeWithoutSpecials() { - return createReplacementNode(false); - } - private ReplacementBase createReplacementNode(boolean useSpecials) { CompilerAsserts.neverPartOfCompilation(); // Note: if specials are turned off in FastR, onlySpecials will never be true @@ -187,14 +181,15 @@ final class ReplacementNode extends OperatorNode { * {@code newLhs}. */ private static RNode createSpecialFunctionQuery(RSyntaxNode newLhs, RSyntaxCall fun, CodeBuilderContext codeBuilderContext) { + RCodeBuilder<RSyntaxNode> builder = RContext.getASTBuilder(); RSyntaxElement[] arguments = fun.getSyntaxArguments(); RSyntaxNode[] argNodes = new RSyntaxNode[arguments.length]; for (int i = 0; i < arguments.length; i++) { - argNodes[i] = i == 0 ? newLhs : process(arguments[i], codeBuilderContext); + argNodes[i] = i == 0 ? newLhs : builder.process(arguments[i], codeBuilderContext); } - return RCallSpecialNode.createCallInReplace(fun.getLazySourceSection(), process(fun.getSyntaxLHS(), codeBuilderContext).asRNode(), fun.getSyntaxSignature(), argNodes).asRNode(); + return RCallSpecialNode.createCallInReplace(fun.getLazySourceSection(), builder.process(fun.getSyntaxLHS(), codeBuilderContext).asRNode(), fun.getSyntaxSignature(), argNodes).asRNode(); } /** @@ -203,6 +198,7 @@ final class ReplacementNode extends OperatorNode { * added to the arguments list. */ private static RNode createFunctionUpdate(SourceSection source, RSyntaxNode newLhs, RSyntaxNode rhs, RSyntaxCall fun, CodeBuilderContext codeBuilderContext) { + RCodeBuilder<RSyntaxNode> builder = RContext.getASTBuilder(); RSyntaxElement[] arguments = fun.getSyntaxArguments(); ArgumentsSignature signature = fun.getSyntaxSignature(); @@ -210,7 +206,7 @@ final class ReplacementNode extends OperatorNode { String[] names = new String[argNodes.length]; for (int i = 0; i < arguments.length; i++) { names[i] = signature.getName(i); - argNodes[i] = i == 0 ? newLhs : process(arguments[i], codeBuilderContext); + argNodes[i] = i == 0 ? newLhs : builder.process(arguments[i], codeBuilderContext); } argNodes[argNodes.length - 1] = rhs; names[argNodes.length - 1] = "value"; @@ -225,27 +221,19 @@ final class ReplacementNode extends OperatorNode { // to work properly argNodes[0] = GetNonSharedNodeGen.create(argNodes[0].asRNode()); } - newSyntaxLHS = lookup(lookupLHS.getLazySourceSection(), symbol + "<-", true); + newSyntaxLHS = builder.lookup(lookupLHS.getLazySourceSection(), symbol + "<-", true); } else { // data types (and lengths) are verified in isNamespaceLookupCall RSyntaxCall callLHS = (RSyntaxCall) syntaxLHS; RSyntaxElement[] oldArgs = callLHS.getSyntaxArguments(); RSyntaxNode[] newArgs = new RSyntaxNode[2]; newArgs[0] = (RSyntaxNode) oldArgs[0]; - newArgs[1] = lookup(oldArgs[1].getLazySourceSection(), ((RSyntaxLookup) oldArgs[1]).getIdentifier() + "<-", true); + newArgs[1] = builder.lookup(oldArgs[1].getLazySourceSection(), ((RSyntaxLookup) oldArgs[1]).getIdentifier() + "<-", true); newSyntaxLHS = RCallSpecialNode.createCall(callLHS.getLazySourceSection(), ((RSyntaxNode) callLHS.getSyntaxLHS()).asRNode(), callLHS.getSyntaxSignature(), newArgs); } return RCallSpecialNode.createCall(source, newSyntaxLHS.asRNode(), ArgumentsSignature.get(names), argNodes).asRNode(); } - private static RSyntaxNode process(RSyntaxElement original, CodeBuilderContext codeBuilderContext) { - return RContext.getASTBuilder().process(original, codeBuilderContext); - } - - private static RSyntaxNode lookup(SourceSection source, String symbol, boolean functionLookup) { - return RContext.getASTBuilder().lookup(source, symbol, functionLookup); - } - static RLanguage getLanguage(WriteVariableNode wvn) { Node parent = wvn.getParent(); if (parent instanceof ReplacementBase) { @@ -295,13 +283,14 @@ final class ReplacementNode extends OperatorNode { // OK with not calling any other update function and just update the value directly. replaceCall.execute(frame); } catch (FullCallNeededException | RecursiveSpecialBailout e) { + CompilerDirectives.transferToInterpreterAndInvalidate(); // String code = getReplacementNodeParent().source.getCode(); // System.out.println("fallback to generic: " + code); // if (code.contains("season$previousSeasonalIndex.isOnAWeekday <- // previousSeasonalIndex.isOnAWeekday")) { // System.out.println("..."); // } - replace(getReplacementNodeParent().createReplacementNodeWithoutSpecials()).execute(frame); + replace(getReplacementNodeParent().createReplacementNode(false)).execute(frame); } } } -- GitLab