From 7e812128cc66d62ebaec958739de35ae1884a523 Mon Sep 17 00:00:00 2001 From: Tomas Stupka <tomas.stupka@oracle.com> Date: Tue, 20 Mar 2018 15:38:43 +0100 Subject: [PATCH] implemented the REMOVE msg for REnvironment --- .../r/engine/interop/REnvironmentMR.java | 47 +++++++++++++++++++ .../truffle/r/nodes/builtin/base/Rm.java | 4 +- .../engine/interop/REnvironmentMRTest.java | 15 ++++++ .../truffle/r/test/generate/FastRSession.java | 2 +- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java index f53da4a554..81632089f0 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java @@ -23,6 +23,7 @@ package com.oracle.truffle.r.engine.interop; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; @@ -39,10 +40,12 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.engine.interop.REnvironmentMRFactory.REnvironmentKeyInfoImplNodeGen; import com.oracle.truffle.r.engine.interop.REnvironmentMRFactory.REnvironmentReadImplNodeGen; +import com.oracle.truffle.r.engine.interop.REnvironmentMRFactory.REnvironmentRemoveImplNodeGen; import com.oracle.truffle.r.engine.interop.REnvironmentMRFactory.REnvironmentWriteImplNodeGen; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode; +import com.oracle.truffle.r.nodes.builtin.base.Rm; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -73,6 +76,15 @@ public class REnvironmentMR { } } + @Resolve(message = "REMOVE") + public abstract static class REnvironmentRemoveNode extends Node { + @Child private REnvironmentRemoveImplNode removeNode = REnvironmentRemoveImplNodeGen.create(); + + protected Object access(VirtualFrame frame, REnvironment receiver, Object identifier) { + return removeNode.execute(frame, receiver, identifier); + } + } + @Resolve(message = "KEYS") public abstract static class REnvironmentKeysNode extends Node { @@ -201,6 +213,41 @@ public class REnvironmentMR { } } + abstract static class REnvironmentRemoveImplNode extends Node { + + private final ConditionProfile unknownIdentifier = ConditionProfile.createBinaryProfile(); + + protected abstract Object execute(VirtualFrame frame, TruffleObject receiver, Object identifier); + + @Specialization + protected Object access(VirtualFrame frame, REnvironment receiver, String identifier, + @Cached("createKeyInfoNode()") REnvironmentKeyInfoImplNode keyInfo) { + int info = keyInfo.execute(receiver, identifier); + if (unknownIdentifier.profile(!KeyInfo.isExisting(info))) { + throw UnknownIdentifierException.raise("" + identifier); + } + return remove(receiver, identifier); + } + + @TruffleBoundary + private boolean remove(REnvironment receiver, String identifier) { + try { + return Rm.removeFromEnv(receiver, identifier, true); + } catch (REnvironment.PutException ex) { + return false; + } + } + + @Fallback + protected Object access(@SuppressWarnings("unused") TruffleObject receiver, Object identifier) { + throw UnknownIdentifierException.raise("" + identifier); + } + + protected REnvironmentKeyInfoImplNode createKeyInfoNode() { + return REnvironmentKeyInfoImplNodeGen.create(); + } + } + abstract static class REnvironmentKeyInfoImplNode extends Node { protected abstract int execute(REnvironment receiver, Object identifier); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java index f7433458c1..bcdcb01f5c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Rm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -77,7 +77,7 @@ public abstract class Rm extends RBuiltinNode.Arg3 { return RNull.instance; } - private static boolean removeFromEnv(REnvironment envir, String key, boolean inherits) throws PutException { + public static boolean removeFromEnv(REnvironment envir, String key, boolean inherits) throws PutException { REnvironment curEnv = envir; while (curEnv != REnvironment.emptyEnv()) { try { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java index 6c55cf3c64..7312f09e90 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java @@ -128,6 +128,21 @@ public class REnvironmentMRTest extends AbstractMRTest { assertFalse(KeyInfo.isInternal(info)); } + @Test + public void testRemove() throws Exception { + assertInteropException(() -> ForeignAccess.sendRemove(Message.REMOVE.createNode(), createEmptyTruffleObject(), "nnoonnee"), UnknownIdentifierException.class); + + REnvironment e = (REnvironment) createTruffleObjects()[0]; + assertInteropException(() -> ForeignAccess.sendRemove(Message.REMOVE.createNode(), e, "nnoonnee"), UnknownIdentifierException.class); + + assertEquals("aaa", ForeignAccess.sendRead(Message.READ.createNode(), e, "s")); + assertEquals(true, ForeignAccess.sendRemove(Message.REMOVE.createNode(), e, "s")); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), e, "s"), UnknownIdentifierException.class); + + e.lock(true); + assertEquals(false, ForeignAccess.sendRemove(Message.REMOVE.createNode(), e, "i")); + } + @Override protected TruffleObject[] createTruffleObjects() throws Exception { Source src = Source.newBuilder("R", "e <- new.env(); e$s <- 'aaa'; e$i <- 123L; e$d <- 123.1; e$b <- TRUE; e$fn <- function() {}; e$n <- NULL; e$l <- 666; lockBinding('l', e); e", diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java index a08bb5bcb2..d6e9c827b8 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java @@ -361,7 +361,7 @@ public final class FastRSession implements RSession { } public static void execInContext(Context context, Callable<Object> c) { - execInContext(context, c, (Class<?>) null); + execInContext(context, c, (Class<?>[]) null); } // TODO: export/importSymbol -- GitLab