From 2e6f11206b097549928af4050d150f43d8991c0f Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Wed, 15 Nov 2017 15:58:44 +0100 Subject: [PATCH] Refactored slot node to detect if its LHS of a call. --- .../truffle/r/nodes/builtin/base/Slot.java | 37 +++++++++++++------ .../r/nodes/access/AccessSlotNode.java | 8 ++++ .../truffle/r/nodes/builtin/RBuiltinNode.java | 4 -- .../truffle/r/nodes/function/RCallNode.java | 3 -- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java index 2ef8f6aa55..e58454418a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java @@ -17,16 +17,19 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.foreign; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.RCallNode; +import com.oracle.truffle.r.nodes.function.RCallNode.BuiltinCallNode; import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -34,11 +37,13 @@ import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @RBuiltin(name = "@", kind = PRIMITIVE, parameterNames = {"", ""}, nonEvalArgs = 1, behavior = COMPLEX) public abstract class Slot extends RBuiltinNode.Arg2 { - @CompilationFinal private boolean isLhsOfCall; @Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create(); @Child private AccessSlotNode accessSlotNode = AccessSlotNodeGen.create(true); @@ -61,14 +66,29 @@ public abstract class Slot extends RBuiltinNode.Arg2 { throw error(RError.Message.GENERIC, "invalid type or length for slot name"); } - protected boolean isLhsOfForeignCall(Object o) { - return isLhsOfCall && RRuntime.isForeignObject(o); + private static boolean isLhsOfSyntaxCall(RSyntaxNode n) { + Node unwrapParent = RASTUtils.unwrapParent(n.asNode()); + return unwrapParent instanceof RSyntaxCall && ((RSyntaxCall) unwrapParent).getSyntaxLHS() == n; } - @Specialization(guards = {"isLhsOfForeignCall(object)"}) + protected boolean isForeignObject(Object obj) { + return RRuntime.isForeignObject(obj); + } + + protected boolean isLhsOfCall() { + CompilerAsserts.neverPartOfCompilation(); + Node unwrapParent = RASTUtils.unwrapParent(this); + assert ((BuiltinCallNode) unwrapParent).getBuiltin() == this; + return unwrapParent instanceof BuiltinCallNode && isLhsOfSyntaxCall(((RBaseNode) unwrapParent).asRSyntaxNode()); + } + + @Specialization(guards = {"isForeignObject(object)", "lhsOfCall"}) protected Object getSlot(TruffleObject object, Object nameObj, + @Cached("isLhsOfCall()") boolean lhsOfCall, @Cached("createClassProfile()") ValueProfile nameObjProfile) { + assert lhsOfCall; + String name = getName(nameObjProfile.profile(nameObj)); assert Utils.isInterned(name); @@ -76,7 +96,7 @@ public abstract class Slot extends RBuiltinNode.Arg2 { return RCallNode.createDeferredMemberAccess(object, name); } - @Specialization(guards = "!isLhsOfForeignCall(object)") + @Specialization protected Object getSlot(Object object, Object nameObj, @Cached("createClassProfile()") ValueProfile nameObjProfile) { String name = getName(nameObjProfile.profile(nameObj)); @@ -88,9 +108,4 @@ public abstract class Slot extends RBuiltinNode.Arg2 { return result; } - @Override - public void setLhsOfCall(boolean value) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - this.isLhsOfCall = value; - } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java index 182e05aa0f..c8d8a6c3f1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java @@ -13,6 +13,7 @@ package com.oracle.truffle.r.nodes.access; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.attributes.GetAttributeNode; @@ -21,6 +22,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClass import com.oracle.truffle.r.nodes.function.ImplicitClassHierarchyNode; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; @@ -80,4 +82,10 @@ public abstract class AccessSlotNode extends BaseAccessSlotNode { throw error(RError.Message.SLOT_NON_S4, name, classAttr.getDataAt(0)); } } + + @Fallback + protected Object getSlot(Object object, String name) { + throw error(RError.Message.SLOT_CANNOT_GET, name, RRuntime.getRTypeName(object)); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java index 26cb852738..11315ae997 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinNode.java @@ -148,10 +148,6 @@ public abstract class RBuiltinNode extends RBuiltinBaseNode implements NodeWithA } } - public void setLhsOfCall(@SuppressWarnings("unused") boolean value) { - // default: do nothing - } - public abstract static class Arg0 extends RBuiltinNode { public abstract Object execute(VirtualFrame frame); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index d8746d02f3..c4fe686b5f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -886,9 +886,6 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS varArgSeen = new boolean[formals.getLength()]; nonWrapSeen = new boolean[formals.getLength()]; wrapSeen = new boolean[formals.getLength()]; - - // Tell this builtin that it is LHS of a call which might imply different behavior. - builtin.setLhsOfCall(true); } @Override -- GitLab