diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java index 649e80683655b6e50ae51f8aa4fa6d0bec054025..d244da876a5a39d58e8996be9fdf50ad7eeb2ada 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java @@ -68,7 +68,7 @@ import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntimeASTAccess; -import com.oracle.truffle.r.runtime.RSource; +import com.oracle.truffle.r.runtime.RSrcref; import com.oracle.truffle.r.runtime.ReturnException; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.Engine; @@ -212,7 +212,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { break; case 3: // srcref - return RSource.createSrcRef(s.getLazySourceSection()); + return RSrcref.createLloc(s.getLazySourceSection()); default: throw RInternalError.shouldNotReachHere(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java index 4a39e005809dc00097c988d13570251dee949e7a..fbb66b60b7a45715aebce8094a324c57495808a4 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java @@ -174,7 +174,8 @@ public abstract class Parse extends RBuiltinNode { private static Source createSource(Object srcFile, String coalescedLines) { if (srcFile instanceof REnvironment) { REnvironment srcFileEnv = (REnvironment) srcFile; - boolean isFile = RRuntime.fromLogical((byte) srcFileEnv.get("isFile")); + Object b = srcFileEnv.get("isFile"); + boolean isFile = RRuntime.fromLogical(b != null ? (byte) b : 0); if (isFile) { // Might be a URL String urlFileName = RRuntime.asString(srcFileEnv.get("filename")); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java index 0888d7ceece1733710fe1b438e4d3c4b7ae67d0d..31938c37b52c0ee0b9047c16445fbaa20d0d594d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSource.java @@ -28,16 +28,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.env.REnvironment.PutException; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** * A facade for the creation of Truffle {@link Source} objects, which is complicated in R due the @@ -209,45 +201,4 @@ public class RSource { } } - @TruffleBoundary - public static Object createSrcRef(SourceSection src) { - if (src == null) { - return RNull.instance; - } - if (src == RSyntaxNode.INTERNAL || src == RSyntaxNode.LAZY_DEPARSE || src == RSyntaxNode.SOURCE_UNAVAILABLE) { - return RNull.instance; - } - Source source = src.getSource(); - REnvironment env = RContext.getInstance().sourceRefEnvironments.get(source); - if (env == null) { - env = RDataFactory.createNewEnv("src"); - env.setClassAttr(RDataFactory.createStringVector(new String[]{"srcfilecopy", "srcfile"}, true)); - try { - env.put("filename", source.getPath() == null ? "" : source.getPath()); - env.put("fixedNewlines", RRuntime.LOGICAL_TRUE); - String[] lines = new String[source.getLineCount()]; - for (int i = 0; i < lines.length; i++) { - lines[i] = source.getCode(i + 1); - } - env.put("lines", RDataFactory.createStringVector(lines, true)); - } catch (PutException e) { - throw RInternalError.shouldNotReachHere(e); - } - RContext.getInstance().sourceRefEnvironments.put(source, env); - } - /* - * TODO: it's unclear what the exact format is, experimentally it is (first line, first - * column, last line, last column, first column, last column, first line, last line). the - * second pair of columns is likely bytes instead of chars, and the second pair of lines - * parsed as opposed to "real" lines (may be modified by #line). - */ - int startLine = src.getStartLine(); - int startColumn = src.getStartColumn(); - int endLine = src.getEndLine(); - int endColumn = src.getEndColumn(); - RIntVector ref = RDataFactory.createIntVector(new int[]{startLine, startColumn, endLine, endColumn, startColumn, endColumn, startLine, endLine}, true); - ref.setAttr("srcfile", env); - ref.setClassAttr(RDataFactory.createStringVector("srcref")); - return ref; - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java index 911ee913029030ab83a7e411cc94f16c8567a998..5de8f818ee41e43b3b4ae684b28555650bcddb28 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSrcref.java @@ -20,11 +20,15 @@ import java.nio.file.attribute.PosixFileAttributes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** * Utilities for handling R srcref attributes, in particular conversion from {@link Source}, @@ -89,8 +93,43 @@ public class RSrcref { return createLloc(ss, createSrcfile(path)); } + @TruffleBoundary + public static Object createLloc(SourceSection src) { + if (src == null) { + return RNull.instance; + } + if (src == RSyntaxNode.INTERNAL || src == RSyntaxNode.LAZY_DEPARSE || src == RSyntaxNode.SOURCE_UNAVAILABLE) { + return RNull.instance; + } + Source source = src.getSource(); + REnvironment env = RContext.getInstance().sourceRefEnvironments.get(source); + if (env == null) { + env = RDataFactory.createNewEnv("src"); + env.setClassAttr(RDataFactory.createStringVector(new String[]{"srcfilecopy", RRuntime.R_SRCFILE}, true)); + try { + env.put("filename", source.getPath() == null ? "" : source.getPath()); + env.put("fixedNewlines", RRuntime.LOGICAL_TRUE); + String[] lines = new String[source.getLineCount()]; + for (int i = 0; i < lines.length; i++) { + lines[i] = source.getCode(i + 1); + } + env.put("lines", RDataFactory.createStringVector(lines, true)); + } catch (PutException e) { + throw RInternalError.shouldNotReachHere(e); + } + RContext.getInstance().sourceRefEnvironments.put(source, env); + } + return createLloc(src, env); + } + @TruffleBoundary public static RIntVector createLloc(SourceSection ss, REnvironment srcfile) { + /* + * TODO: it's unclear what the exact format is, experimentally it is (first line, first + * column, last line, last column, first column, last column, first line, last line). the + * second pair of columns is likely bytes instead of chars, and the second pair of lines + * parsed as opposed to "real" lines (may be modified by #line). + */ int[] llocData = new int[8]; int startLine = ss.getStartLine(); int startColumn = ss.getStartColumn(); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index e71dce24d54fcc8a826d9540fe43525a1dce981e..42427b2a675d34693c1f19dbb6a5ca98ca56630e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -39420,6 +39420,10 @@ In addition: Warning message: In file(filename, "r", encoding = encoding) : cannot open file 'test/r/simple/data/tree2/setx.r': No such file or directory +##com.oracle.truffle.r.test.builtins.TestBuiltin_parse.testSrcfile# +#parse(text='', srcfile=srcfile(system.file('testfile'))) +expression() + ##com.oracle.truffle.r.test.builtins.TestBuiltin_paste.testPaste# #{ a <- as.raw(200) ; b <- as.raw(255) ; paste(a, b) } [1] "c8 ff" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java index 748403bf04222400b0c2d1518b2ae61633adff42..fa4d7c9ccef80a2ffdba55d38684e665857e2266 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_parse.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2016, Oracle and/or its affiliates + * Copyright (c) 2013, 2017, Oracle and/or its affiliates * * All rights reserved. */ @@ -13,6 +13,7 @@ package com.oracle.truffle.r.test.builtins; import org.junit.Test; import com.oracle.truffle.r.test.TestBase; +import java.io.IOException; // Checkstyle: stop line length check @@ -57,4 +58,10 @@ public class TestBuiltin_parse extends TestBase { public void testArgumentsCasts() { assertEval(".Internal(parse(stdin(), c(1,2), c('expr1', 'expr2'), '?', '<weird-text', 'unknown'))"); } + + @Test + public void testSrcfile() throws IOException { + assertEval("parse(text='', srcfile=srcfile(system.file('testfile')))"); + } + }