Skip to content
Snippets Groups Projects
Commit 86a373be authored by Lukas Stadler's avatar Lukas Stadler
Browse files

Merge pull request #580 in G/fastr from ~LUKAS.STADLER_ORACLE.COM/fastr:feature/srcref to master

* commit '09c77535':
  create proper srcref attributes for function literals
parents 17705622 09c77535
No related branches found
No related tags found
No related merge requests found
......@@ -68,11 +68,11 @@ 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.ReturnException;
import com.oracle.truffle.r.runtime.Utils;
import com.oracle.truffle.r.runtime.context.Engine;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
import com.oracle.truffle.r.runtime.data.RAttributable;
import com.oracle.truffle.r.runtime.data.RAttributesLayout;
import com.oracle.truffle.r.runtime.data.RComplex;
......@@ -211,9 +211,8 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
result = ((RSyntaxFunction) s).getSyntaxBody();
break;
case 3:
// TODO: handle srcref properly - for now, clearly mark an erroneous access to
// this piece of data
return new RArgsValuesAndNames(new String[]{"DUMMY UNIMPLEMENTED SRCREF"}, ArgumentsSignature.get("dummy"));
// srcref
return RSource.createSrcRef(s.getLazySourceSection());
default:
throw RInternalError.shouldNotReachHere();
}
......
......@@ -26,14 +26,13 @@ import java.nio.charset.StandardCharsets;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.java.JavaInterop;
import com.oracle.truffle.r.engine.interop.NativeRawArray;
import com.oracle.truffle.r.engine.interop.NativeCharArray;
import com.oracle.truffle.r.engine.interop.NativeDoubleArray;
import com.oracle.truffle.r.engine.interop.NativeIntegerArray;
import com.oracle.truffle.r.engine.interop.NativeLogicalArray;
import com.oracle.truffle.r.engine.interop.NativeRawArray;
import com.oracle.truffle.r.runtime.REnvVars;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RDouble;
import com.oracle.truffle.r.runtime.data.RInteger;
......
......@@ -584,8 +584,6 @@ public class RErrorHandling {
/*
* Warnings generally do not prevent results being printed. However, this call into R will
* destroy any visibility setting made by the calling builtin prior to this call.
*
* TODO: it's not clear whether this is still the case with the optimized visibility scheme
*/
ContextStateImpl errorHandlingState = getRErrorHandlingState();
RFunction f = errorHandlingState.getDotSignalSimpleWarning();
......
......@@ -30,6 +30,13 @@ import java.net.URL;
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
......@@ -202,4 +209,44 @@ public class RSource {
}
}
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;
}
}
......@@ -418,6 +418,7 @@ public final class RContext extends ExecutionContext implements TruffleObject {
private ContextState stateRFFI;
public final WeakHashMap<String, WeakReference<String>> stringMap = new WeakHashMap<>();
public final WeakHashMap<Source, REnvironment> sourceRefEnvironments = new WeakHashMap<>();
private ContextState[] contextStates() {
return new ContextState[]{stateREnvVars, stateRProfile, stateROptions, stateREnvironment, stateRErrorHandling, stateRConnection, stateStdConnections, stateRNG, stateRFFI, stateRSerialize,
......
......@@ -58762,6 +58762,34 @@ NULL
##com.oracle.truffle.r.test.functions.TestFunctions.testReturn#
#{ f<-function() { return(invisible(2)) } ; f() }
 
##com.oracle.truffle.r.test.functions.TestFunctions.testSrcref#
#1<<<NEWLINE>>>f <- quote(function(x, y) <<<NEWLINE>>> a + <<<NEWLINE>>> foooo); as.list(f); as.list(f)[[4]]; unclass(as.list(f)[[4]]); class(as.list(f)[[4]])
[1] 1
[[1]]
`function`
[[2]]
[[2]]$x
[[2]]$y
[[3]]
a + foooo
[[4]]
function(x, y)
a +
foooo
function(x, y)
a +
foooo
[1] 1 12 3 6 12 6 1 3
[1] "srcref"
##com.oracle.truffle.r.test.functions.TestFunctions.testStateTransitions#
#{ f<-function(x) { l<-length(x); x[1]<-1 }; y<-c(42,7); f(y); y }
[1] 42 7
......@@ -400,4 +400,9 @@ public class TestFunctions extends TestBase {
public void testConversions() {
assertEval("{ x<-quote(list(...)); l<-list(); l[[2]]<-x; names(l)<-c(\"...\"); f<-as.function(l); f(7, 42) }");
}
@Test
public void testSrcref() {
assertEval("1\nf <- quote(function(x, y) \n a + \n foooo); as.list(f); as.list(f)[[4]]; unclass(as.list(f)[[4]]); class(as.list(f)[[4]])");
}
}
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