Skip to content
Snippets Groups Projects
Commit 7e812128 authored by Tomas Stupka's avatar Tomas Stupka
Browse files

implemented the REMOVE msg for REnvironment

parent 830e9224
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
/*
* 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 {
......
......@@ -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",
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment