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

support interop KEY_INFO message

parent a9d34ca4
Branches
No related tags found
No related merge requests found
...@@ -22,12 +22,14 @@ ...@@ -22,12 +22,14 @@
*/ */
package com.oracle.truffle.r.engine.interop; package com.oracle.truffle.r.engine.interop;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.engine.TruffleRLanguage; import com.oracle.truffle.r.engine.TruffleRLanguage;
import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; 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.ExtractVectorNode;
...@@ -36,7 +38,9 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNames ...@@ -36,7 +38,9 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNames
import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.context.RContext.RCloseable; import com.oracle.truffle.r.runtime.context.RContext.RCloseable;
import com.oracle.truffle.r.runtime.data.RFunction;
import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RStringVector;
@MessageResolution(receiverType = RList.class, language = TruffleRLanguage.class) @MessageResolution(receiverType = RList.class, language = TruffleRLanguage.class)
public class RListMR { public class RListMR {
...@@ -77,7 +81,7 @@ public class RListMR { ...@@ -77,7 +81,7 @@ public class RListMR {
@Resolve(message = "WRITE") @Resolve(message = "WRITE")
public abstract static class RListWriteNode extends Node { public abstract static class RListWriteNode extends Node {
@Child private ReplaceVectorNode extract = ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, true); @Child private ReplaceVectorNode replace = ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
@Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode(); @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode();
@SuppressWarnings("try") @SuppressWarnings("try")
...@@ -97,7 +101,7 @@ public class RListMR { ...@@ -97,7 +101,7 @@ public class RListMR {
} else if (value instanceof Byte) { } else if (value instanceof Byte) {
value = (int) ((Byte) value).byteValue(); value = (int) ((Byte) value).byteValue();
} }
Object x = extract.apply(frame, receiver, new Object[]{field}, value); Object x = replace.apply(frame, receiver, new Object[]{field}, value);
return x; return x;
} }
} }
...@@ -116,6 +120,48 @@ public class RListMR { ...@@ -116,6 +120,48 @@ public class RListMR {
} }
} }
@Resolve(message = "KEY_INFO")
public abstract static class RListKeyInfoNode extends Node {
@Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode();
@Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create();
@Child private ExtractVectorNode extractNode;
private final ConditionProfile unknownIdentifier = ConditionProfile.createBinaryProfile();
private static final int READABLE = 1 << 1;
private static final int WRITABLE = 1 << 2;
private static final int INVOCABLE = 1 << 3;
private static final int INTERNAL = 1 << 4;
@SuppressWarnings("try")
protected Object access(VirtualFrame frame, RList receiver, String identifier) {
try (RCloseable c = RContext.withinContext(TruffleRLanguage.INSTANCE.actuallyFindContext0(findContext))) {
int info = 0;
RStringVector names = getNamesNode.getNames(receiver);
for (int i = 0; i < names.getLength(); i++) {
if (identifier.equals(names.getDataAt(i))) {
info = 1;
break;
}
}
if (unknownIdentifier.profile(info == 0)) {
return info;
}
info = info + READABLE + WRITABLE;
if (extractNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
extractNode = insert(ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true));
}
Object value = extractNode.applyAccessField(frame, receiver, identifier);
if (value instanceof RFunction) {
info = info + INVOCABLE;
}
return info;
}
}
}
@CanResolve @CanResolve
public abstract static class RListCheck extends Node { public abstract static class RListCheck extends Node {
......
/*
* Copyright (c) 2017, 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.test.engine.interop;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.KeyInfo;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import org.junit.Test;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class RListMRTest {
@Test
public void testKeysReadWrite() throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException {
TruffleObject l = createRListTruffleObject("n1=1L, n2=2L, 3, 4");
TruffleObject keys = ForeignAccess.sendKeys(Message.KEYS.createNode(), l);
assertEquals("n1", ForeignAccess.sendRead(Message.READ.createNode(), keys, 0));
assertEquals("n2", ForeignAccess.sendRead(Message.READ.createNode(), keys, 1));
assertEquals("", ForeignAccess.sendRead(Message.READ.createNode(), keys, 2));
assertEquals("", ForeignAccess.sendRead(Message.READ.createNode(), keys, 3));
assertEquals(4, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), keys));
assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, "n1"));
assertEquals(2, ForeignAccess.sendRead(Message.READ.createNode(), l, "n2"));
// TODO fails - should this return NULL as in l[""] or 3 as in l$""
// ElementAccessMode.FIELD_SUBSCRIPT vs .SUBSCRIPT doesn't seem to have any effect
// assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), l, ""));
// TODO - more tests for NA, ... ?
l = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "n2", 123);
assertEquals(123, ForeignAccess.sendRead(Message.READ.createNode(), l, "n2"));
}
@Test
public void testKeysInfo() throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException {
TruffleObject l = createRListTruffleObject("n1=1, n2=2");
int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "nnoonnee");
assertFalse(KeyInfo.isExisting(info));
assertFalse(KeyInfo.isReadable(info));
assertFalse(KeyInfo.isWritable(info));
assertFalse(KeyInfo.isInvocable(info));
assertFalse(KeyInfo.isInternal(info));
info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "n2");
assertTrue(KeyInfo.isExisting(info));
assertTrue(KeyInfo.isReadable(info));
assertTrue(KeyInfo.isWritable(info));
assertFalse(KeyInfo.isInvocable(info));
assertFalse(KeyInfo.isInternal(info));
l = createRListTruffleObject("f=function() {}");
info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "f");
assertTrue(KeyInfo.isExisting(info));
assertTrue(KeyInfo.isReadable(info));
assertTrue(KeyInfo.isWritable(info));
assertTrue(KeyInfo.isInvocable(info));
assertFalse(KeyInfo.isInternal(info));
}
private TruffleObject createRListTruffleObject(String values) {
PolyglotEngine engine = PolyglotEngine.newBuilder().build();
Source src = Source.newBuilder("list(" + values + ")").mimeType("text/x-r").name("test.R").build();
PolyglotEngine.Value result = engine.eval(src);
return result.as(TruffleObject.class);
}
}
...@@ -152,6 +152,7 @@ public class FastRTckTest extends TruffleTCK { ...@@ -152,6 +152,7 @@ public class FastRTckTest extends TruffleTCK {
"builtinFunctionValue <- function() `+`\n" + "builtinFunctionValue <- function() `+`\n" +
"builtinFunctionType <- function() 'builtin'\n" + "builtinFunctionType <- function() 'builtin'\n" +
"valueWithSource <- function() intValue\n" + "valueWithSource <- function() intValue\n" +
"objectWithKeyInfoAttributes <- function() { list(rw=1, invocable=function(){ 'invoked' }) }\n" +
"for (name in ls()) .fastr.interop.export(name, get(name))\n", "for (name in ls()) .fastr.interop.export(name, get(name))\n",
RSource.Internal.TCK_INIT RSource.Internal.TCK_INIT
); );
...@@ -285,12 +286,6 @@ public class FastRTckTest extends TruffleTCK { ...@@ -285,12 +286,6 @@ public class FastRTckTest extends TruffleTCK {
return "objectWithValueAndAddProperty"; return "objectWithValueAndAddProperty";
} }
@Override
protected String objectWithKeyInfoAttributes() {
// TODO
return null;
}
@Override @Override
protected String callMethod() { protected String callMethod() {
return "callMethod"; return "callMethod";
...@@ -511,4 +506,8 @@ public class FastRTckTest extends TruffleTCK { ...@@ -511,4 +506,8 @@ public class FastRTckTest extends TruffleTCK {
return "valueWithSource"; return "valueWithSource";
} }
protected String objectWithKeyInfoAttributes() {
return "objectWithKeyInfoAttributes";
}
} }
...@@ -29,7 +29,7 @@ suite = { ...@@ -29,7 +29,7 @@ suite = {
{ {
"name" : "truffle", "name" : "truffle",
"subdir" : True, "subdir" : True,
"version" : "8ee92107d834749dc2355cf48062e08d49e02a67", "version" : "7d960d6682ef3636cc7455e28132c1e537ea81f0",
"urls" : [ "urls" : [
{"url" : "https://github.com/graalvm/graal", "kind" : "git"}, {"url" : "https://github.com/graalvm/graal", "kind" : "git"},
{"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment