diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 7dee98d92d2b02ac9c35d3c686f4d4dd60afe789..ab19a0a278d18db88e0756d2cf7244c49d118e92 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -295,16 +295,18 @@ final class REngine implements Engine, Engine.Timings { @Override public CallTarget parseToCallTarget(Source source, MaterializedFrame executionFrame) throws ParseException { List<RSyntaxNode> statements = parseImpl(source); - return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(statements), executionFrame)); + return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(source, statements), executionFrame)); } - private static SourceSection createSourceSection(List<RSyntaxNode> statements) { + private static SourceSection createSourceSection(Source source, List<RSyntaxNode> statements) { // All statements come from the same "Source" - if (statements.size() == 1) { + if (statements.isEmpty()) { + return source.createSection(0, source.getLength()); + } else if (statements.size() == 1) { return statements.get(0).getSourceSection(); } else { - Source source = statements.get(0).getSourceSection().getSource(); - return source.createSection(0, statements.get(statements.size() - 1).getSourceSection().getCharEndIndex()); + Source newSource = statements.get(0).getSourceSection().getSource(); + return newSource.createSection(0, statements.get(statements.size() - 1).getSourceSection().getCharEndIndex()); } } 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 f5710f0c5060e0b433b8ebe8f6b5e8434289a976..0c7606c8f3ef30a06a7a5c0eecb5c113041a1753 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 @@ -92,7 +92,6 @@ import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; import com.oracle.truffle.r.runtime.nodes.RInstrumentableNode; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; -import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; @@ -133,17 +132,6 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; */ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { - private static Object getIntrinsicValue(Object result) { - if (result instanceof RSyntaxConstant) { - return ((RSyntaxConstant) result).getValue(); - } else if (result instanceof RSyntaxLookup) { - return RDataFactory.createSymbolInterned(((RSyntaxLookup) result).getIdentifier()); - } else { - assert result instanceof RSyntaxCall || result instanceof RSyntaxFunction : result.getClass(); - return RDataFactory.createLanguage(((RSyntaxNode) result).asRNode()); - } - } - @TruffleBoundary @Override public RLanguage.RepType getRepType(RLanguage rl) { @@ -203,7 +191,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { Object list = RNull.instance; for (int i = sig.getLength() - 1; i >= 0; i--) { - list = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : getIntrinsicValue(defaults[i]), list, + list = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(defaults[i]), list, RDataFactory.createSymbolInterned(sig.getName(i))); } return list; @@ -228,7 +216,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { /* * Constants and lookups are converted to their intrinsic value: */ - return getIntrinsicValue(result); + return RASTUtils.createLanguageElement(result); } @Override diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c index 92b618c6f10d6e92dcbdb2ea16f1b375b9cdb1c8..225e41a48e016d01a5699e8aa925e32bffbb558c 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -112,6 +112,10 @@ static jmethodID ENCLOSMethodID; static jmethodID PRVALUEMethodID; static jmethodID R_lsInternal3MethodID; static jmethodID R_do_MAKE_CLASS_MethodID; +static jmethodID PRSEENMethodID; +static jmethodID PRENVMethodID; +static jmethodID R_PromiseExprMethodID; +static jmethodID PRCODEMethodID; static jmethodID R_ToplevelExecMethodID; static jmethodID restoreHandlerStacksMethodID; @@ -215,6 +219,10 @@ void init_internals(JNIEnv *env) { ENCLOSMethodID = checkGetMethodID(env, UpCallsRFFIClass, "ENCLOS", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); PRVALUEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); R_lsInternal3MethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_lsInternal3", "(Ljava/lang/Object;II)Ljava/lang/Object;", 0); + PRSEENMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRSEEN", "(Ljava/lang/Object;)I", 0); + PRENVMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRENV", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + R_PromiseExprMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_PromiseExpr", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + PRCODEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRCODE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); R_ToplevelExecMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExec", "()Ljava/lang/Object;", 0); restoreHandlerStacksMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExecRestoreErrorHandlerStacks", "(Ljava/lang/Object;)V", 0); @@ -1047,14 +1055,15 @@ void SET_HASHTAB(SEXP x, SEXP v) { unimplemented("SET_HASHTAB"); } - SEXP PRCODE(SEXP x) { - return unimplemented("PRCODE"); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRCODEMethodID, x); } SEXP PRENV(SEXP x) { - unimplemented("PRSEEN"); - return 0; + JNIEnv *thisenv = getEnv(); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRENVMethodID, x); + return checkRef(thisenv, result); } SEXP PRVALUE(SEXP x) { @@ -1064,7 +1073,8 @@ SEXP PRVALUE(SEXP x) { } int PRSEEN(SEXP x) { - return (int) unimplemented("PRSEEN"); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRSEENMethodID, x); } void SET_PRSEEN(SEXP x, int v) { @@ -1494,7 +1504,8 @@ double R_strtod(const char *c, char **end) { } SEXP R_PromiseExpr(SEXP x) { - return unimplemented("R_PromiseExpr"); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_PromiseExprMethodID, x); } SEXP R_ClosureExpr(SEXP x) { diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c index ccdcdcd041973e0a3ec5b868d22a004ca18b0a66..db953ec45718afe03c0a084dbe838bc399c77bd2 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c @@ -715,7 +715,7 @@ SEXP PRCODE(SEXP x) { } SEXP PRENV(SEXP x) { - unimplemented("PRSEEN"); + unimplemented("PRENV"); return 0; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java index 92198306f2147525fa9cb044ecd8b4afad4a675f..32fe9994366140e09659f5fd7309885739dc5d9b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsATTY.java @@ -40,6 +40,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @RBuiltin(name = "isatty", kind = INTERNAL, parameterNames = {"con"}, behavior = PURE) public abstract class IsATTY extends RBuiltinNode { + static { + Casts.noCasts(IsATTY.class); + } + @Specialization @TruffleBoundary protected byte isATTYNonConnection(RAbstractIntVector con) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java index b3ee8227c3d2db6bb72e83df13246bc4a9b42f40..39cb3d17be08313cfcb2b864857c22afde8472db 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInspect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -37,6 +37,11 @@ import com.oracle.truffle.r.runtime.data.RNull; */ @RBuiltin(name = ".fastr.inspect", visibility = OFF, kind = PRIMITIVE, parameterNames = {"..."}, behavior = COMPLEX) public abstract class FastRInspect extends RBuiltinNode { + + static { + Casts.noCasts(FastRInspect.class); + } + @Specialization public Object call(@SuppressWarnings("unused") RArgsValuesAndNames args) { return RNull.instance; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java index 21a4e1293a6cecd42faaa778194bc48c1d43944a..2b3bbc78a7ea4c918f19177824499d8017c458da 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -134,7 +134,7 @@ public class RASTUtils { * variables and actual values for constants. */ @TruffleBoundary - public static Object createLanguageElement(RSyntaxNode element) { + public static Object createLanguageElement(RSyntaxElement element) { assert element != null; if (element instanceof RSyntaxConstant) { Object value = ((RSyntaxConstant) element).getValue(); @@ -149,7 +149,7 @@ public class RASTUtils { return RDataFactory.createSymbol(id); } else { assert element instanceof RSyntaxCall || element instanceof RSyntaxFunction; - return RDataFactory.createLanguage(element.asRNode()); + return RDataFactory.createLanguage(((RSyntaxNode) element).asRNode()); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java index 8441fc32c7dec2c65d0a48bd48be67c685ac538c..4aa1e8d9dc89dc6398662e02dac477b57b5a7b03 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java @@ -22,7 +22,9 @@ */ package com.oracle.truffle.r.nodes.ffi; -import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.*; +import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.guarantee; +import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.guaranteeInstanceOf; +import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.unimplemented; import java.nio.charset.StandardCharsets; import java.util.function.Function; @@ -30,9 +32,11 @@ import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.ffi.ParseResult.ParseStatus; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; @@ -81,11 +85,12 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; -import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; +import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; import com.oracle.truffle.r.runtime.rng.RRNG; /** @@ -1142,4 +1147,31 @@ public class JavaUpCallsRFFIImpl implements UpCallsRFFI { return env; } + @Override + public int PRSEEN(Object x) { + RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class); + return promise.getGPBits(); + } + + @Override + public Object PRENV(Object x) { + RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class); + final MaterializedFrame frame = promise.getFrame(); + return frame != null ? REnvironment.frameToEnvironment(frame) : RNull.instance; + } + + @Override + public Object R_PromiseExpr(Object x) { + // R_PromiseExpr usually checks, if 'x' is a byte code object. This is not possible in + // FastR, so simply call PRCODE. + return PRCODE(x); + } + + @Override + public Object PRCODE(Object x) { + RPromise promise = RFFIUtils.guaranteeInstanceOf(x, RPromise.class); + RSyntaxNode expr = RASTUtils.unwrap(promise.getRep()).asRSyntaxNode(); + return RASTUtils.createLanguageElement(expr); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java index 59a0dbc1390adbfc6f9c1ebe90fffe5874ce4235..f0efb662604f09ce4ba0ff9836f5503e7b6681b5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java @@ -927,6 +927,38 @@ public final class UpCallsRFFIImpl implements UpCallsRFFI { return delegate.R_NewHashedEnv(parent, initialSize); } + @Override + public int PRSEEN(Object x) { + if (tracing) { + RFFIUtils.traceUpCall("PRSEEN", x); + } + return delegate.PRSEEN(x); + } + + @Override + public Object PRENV(Object x) { + if (tracing) { + RFFIUtils.traceUpCall("PRENV", x); + } + return delegate.PRENV(x); + } + + @Override + public Object R_PromiseExpr(Object x) { + if (tracing) { + RFFIUtils.traceUpCall("R_PromiseExpr", x); + } + return delegate.R_PromiseExpr(x); + } + + @Override + public Object PRCODE(Object x) { + if (tracing) { + RFFIUtils.traceUpCall("PRCODE", x); + } + return delegate.PRCODE(x); + } + // Implementation specific support /** diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java index 10e9a7ce172cdb19cf95775c1b76f9566cca8bc4..77c0e2875edf4e45f279d1eea5742f279efdd91d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/FileConnections.java @@ -462,8 +462,7 @@ public class FileConnections { raf.seek(writeOffset); byte[] sepData = sep.getBytes(); for (int i = 0; i < lines.getLength(); i++) { - byte[] data = lines.getDataAt(i).getBytes(); - raf.write(data); + writeString(lines.getDataAt(i), false); raf.write(sepData); } writeOffset = raf.getFilePointer(); @@ -476,7 +475,10 @@ public class FileConnections { @Override public void writeString(String s, boolean nl) throws IOException { - throw RInternalError.unimplemented(); + raf.write(s.getBytes()); + if (nl) { + raf.writeBytes(System.lineSeparator()); + } } @Override diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java index b8f0ecf89d961d276e182a8fdb62576e4a77a304..60a8de076bafa2a716962eb7a4ac8566957877da 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java @@ -240,4 +240,12 @@ public interface StdUpCallsRFFI { REnvironment R_NewHashedEnv(REnvironment parent, int initialSize); + int PRSEEN(Object x); + + Object PRENV(Object x); + + Object R_PromiseExpr(Object x); + + Object PRCODE(Object x); + } 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 6a8a449ed938b77889963326a092a789242a536f..14957271ae4861476e601f32f157aa17b1e65741 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 @@ -5466,7 +5466,7 @@ character(0) #argv <- list(list(epsilon = 1e-08, maxit = 25, trace = FALSE));as.character(argv[[1]]); [1] "1e-08" "25" "FALSE" -##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter19#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter19# #argv <- list(structure(list(structure(list(given = c('George', 'E.', 'P.'), family = 'Box', role = NULL, email = NULL, comment = NULL), .Names = c('given', 'family', 'role', 'email', 'comment')), structure(list(given = c('David', 'R.'), family = 'Cox', role = NULL, email = NULL, comment = NULL), .Names = c('given', 'family', 'role', 'email', 'comment'))), class = 'person'));as.character(argv[[1]]); [1] "George E. P. Box" "David R. Cox" @@ -5577,7 +5577,7 @@ character(0) [4] "2012-06-04 04:00:00" "2012-06-05 04:00:00" "2012-06-06 04:00:00" [7] "2012-06-07 04:00:00" -##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter32#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter32# #argv <- list(structure(1:4, class = 'roman'));as.character(argv[[1]]); [1] "I" "II" "III" "IV" @@ -6231,7 +6231,7 @@ a + foo(c) * b #foo <- function(x) x*2; f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))(c=3,b=1) [1] 21 -##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction# #{ .Internal(as.function.default(alist(a+b), "foo")) } Error in as.function.default(alist(a + b), "foo") : invalid environment @@ -7180,15 +7180,15 @@ Warning messages: 2: In as.vector("foo", "raw") : out-of-range values treated as 0 in coercion to raw -##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector# #{ as.vector(42, NULL) } Error in as.vector(x, mode) : invalid 'mode' argument -##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector# #{ as.vector(42, c("character", "character")) } Error in as.vector(x, mode) : invalid 'mode' argument -##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asvector.testAsVector# #{ as.vector(42, character()) } Error in as.vector(x, mode) : invalid 'mode' argument @@ -12188,7 +12188,7 @@ Traceback: 2: cbind(v) An irrecoverable exception occurred. R is aborting now ... -##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testGenericDispatch#Ignored.WrongCaller# +##com.oracle.truffle.r.test.builtins.TestBuiltin_cbind.testGenericDispatch#Output.IgnoreErrorContext# #{ v <- 1; class(v) <- 'foo'; cbind.foo <- rawToBits; cbind(v) } Error in cbind(deparse.level, ...) : argument 'x' must be a raw vector @@ -34312,11 +34312,11 @@ NULL [1] "some" [1] "test" -##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBinaryOperators# +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBooleanOperators# #as.symbol('*') == '*' [1] TRUE -##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBinaryOperators# +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testBooleanOperators# #as.symbol('<-') == '<-' [1] TRUE @@ -35451,7 +35451,7 @@ x 0 1 2 3 4 5 6 7 8 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE -##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testoperators118#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testoperators118# #argv <- list(structure(c('white', 'aquamarine3', 'bisque2', 'blueviolet', 'burlywood4', 'chartreuse4', 'coral4', 'cyan3', 'darkgreen', 'darkorange1', 'aliceblue', 'white', 'white', 'white', 'white', 'chocolate', 'cornflowerblue', 'cyan4', 'darkgrey', 'darkorange2', 'antiquewhite', 'white', 'white', 'white', 'white', 'chocolate1', 'cornsilk', 'darkblue', 'darkkhaki', 'darkorange3', 'antiquewhite1', 'white', 'white', 'white', 'white', 'chocolate2', 'cornsilk1', 'darkcyan', 'darkmagenta', 'darkorange4', 'antiquewhite2', 'azure2', 'blanchedalmond', 'brown3', 'cadetblue3', 'chocolate3', 'cornsilk2', 'darkgoldenrod', 'darkolivegreen', 'darkorchid', 'antiquewhite3', 'azure3', 'blue', 'brown4', 'cadetblue4', 'chocolate4', 'cornsilk3', 'darkgoldenrod1', 'darkolivegreen1', 'darkorchid1', 'antiquewhite4', 'azure4', 'blue1', 'burlywood', 'chartreuse', 'coral', 'cornsilk4', 'darkgoldenrod2', 'darkolivegreen2', 'darkorchid2', 'aquamarine', 'beige', 'blue2', 'burlywood1', 'chartreuse1', 'coral1', 'cyan', 'darkgoldenrod3', 'darkolivegreen3', 'darkorchid3', 'aquamarine1', 'bisque', 'blue3', 'burlywood2', 'chartreuse2', 'coral2', 'cyan1', 'darkgoldenrod4', 'darkolivegreen4', 'darkorchid4', 'aquamarine2', 'bisque1', 'blue4', 'burlywood3', 'chartreuse3', 'coral3', 'cyan2', 'darkgray', 'darkorange', 'darkred'), .Dim = c(10L, 10L), class = 'raster'), 'white');`==`(argv[[1]],argv[[2]]); [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE @@ -42671,7 +42671,7 @@ Traceback: 2: rbind(v) An irrecoverable exception occurred. R is aborting now ... -##com.oracle.truffle.r.test.builtins.TestBuiltin_rbind.testGenericDispatch#Ignored.WrongCaller# +##com.oracle.truffle.r.test.builtins.TestBuiltin_rbind.testGenericDispatch#Output.IgnoreErrorContext# #{ v <- 1; class(v) <- 'foo'; rbind.foo <- rawToBits; rbind(v) } Error in rbind(deparse.level, ...) : argument 'x' must be a raw vector @@ -58143,7 +58143,7 @@ integer(0) [41] 26163.27 26367.35 26571.43 26775.51 26979.59 27183.67 27387.76 27591.84 [49] 27795.92 28000.00 -##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength#Ignored.Unimplemented# +##com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along.testWithNonStandardLength# #{ assign('length.myclass', function(...) 42, envir=.__S3MethodsTable__.); x <- 1; class(x) <- 'myclass'; res <- seq_along(x); rm('length.myclass', envir=.__S3MethodsTable__.); res } [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @@ -61116,7 +61116,7 @@ character(0) #argv <- list('p,L,S = (%2d,%2d,%2d): ', TRUE, FALSE, NA); .Internal(sprintf(argv[[1]], argv[[2]], argv[[3]], argv[[4]])) [1] "p,L,S = ( 1, 0,NA): " -##com.oracle.truffle.r.test.builtins.TestBuiltin_sprintf.testsprintf8#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_sprintf.testsprintf8# #argv <- list('plot_%02g', 1L); .Internal(sprintf(argv[[1]], argv[[2]])) [1] "plot_01" @@ -73077,6 +73077,30 @@ f first 1 #{f<-function(x){UseMethod("f")};f.logical<-function(x){print("logical")};f(TRUE)} [1] "logical" +##com.oracle.truffle.r.test.library.base.TestConditionHandling.runRSourceTests# +#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R") } + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.runRSourceTests#Ignored.Unknown# +#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R") } +[1] "enter fun1 first" +[1] "enter handle_cond1 cond1: signalfirst\n" +[1] "after cond1 restart" +[1] "enter handle_cond0 cond0: signalfirst\n" +[1] "continue" +[1] "exit fun1 first" +[1] "enter fun1 second" +[1] "enter handle_cond1 cond1: signalsecond\n" +[1] "after cond1 restart" +[1] "enter handle_cond0 cond0: signalsecond\n" +[1] "continue" +[1] "exit fun1 second" +NULL +[1] "exit fun0" + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch# +#myCondition <- function(message, call=NULL)<<<NEWLINE>>> structure(list(message=message, call=call),<<<NEWLINE>>> class=c("myCondition", "condition"))<<<NEWLINE>>>tryCatch(signalCondition(myCondition("foo")),<<<NEWLINE>>> myCondition=function(cond) {cat("<my>");123L}) +<my>[1] 123 + ##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch# #{ e <- simpleError("test error"); f <- function() { tryCatch(1, finally = print("Hello")); stop(e)}; f() } [1] "Hello" @@ -73115,6 +73139,63 @@ Error in f() : fred Error in tryCatchList(expr, classes, parentenv, handlers) : fred [1] "Hello" +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testTryCatch# +#{ tryCatch(stop("xyz"), error=function(e) { cat("<error>");123L }, finally=function() { cat("<finally>")}) } +<error>[1] 123 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers# +#withCallingHandlers({message("foo");123L},<<<NEWLINE>>> message=function(e) {<<<NEWLINE>>> cat("<msg>")<<<NEWLINE>>> invokeRestart("muffleMessage")<<<NEWLINE>>> }) +<msg>[1] 123 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers# +#withCallingHandlers({message("foo");123L},<<<NEWLINE>>> message=function(e) {cat("<msg>")}) +<msg>foo +[1] 123 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers# +#withCallingHandlers({message("foo");packageStartupMessage("bar");123L},<<<NEWLINE>>> packageStartupMessage=function(e) {<<<NEWLINE>>> cat("<msg>")<<<NEWLINE>>> invokeRestart("muffleMessage")<<<NEWLINE>>> }) +foo +<msg>[1] 123 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#Ignored.ImplementationError# +#withCallingHandlers({warning("foo");123L},<<<NEWLINE>>> warning=function(e) {<<<NEWLINE>>> cat("<warn>")<<<NEWLINE>>> invokeRestart("muffleWarning")<<<NEWLINE>>> }) +<warn>[1] 123 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithCallingHandlers#Output.IgnoreWarningContext# +#withCallingHandlers({warning("foo");123L},<<<NEWLINE>>> warning=function(e) {cat("<warn>")}) +<warn>[1] 123 +Warning message: +In withCallingHandlers({ : foo + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts(computeRestarts(),<<<NEWLINE>>> foo=function(a,b) c(a,b)) +[[1]] +<restart: foo > + +[[2]] +<restart: abort > + + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts(findRestart("foo"),<<<NEWLINE>>> foo=function(a,b) c(a,b)) +<restart: foo > + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts(findRestart("noSuchRestart"),<<<NEWLINE>>> foo=function(a,b) c(a,b)) +NULL + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=function(a,b) c(a,b)) +<start>[1] 123 456 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=function(a,b) {cat("<first>");invokeRestart("foo", a+1, b+1)},<<<NEWLINE>>> foo=function(a,b) {cat("<second>");c(a,b)}) +<start><first><second>[1] 124 457 + +##com.oracle.truffle.r.test.library.base.TestConditionHandling.testWithRestarts# +#withRestarts({cat("<start>");invokeRestart("foo", 123L, 456L);789L},<<<NEWLINE>>> foo=list(description="my handler", handler=function(a,b) c(a,b))) +<start>[1] 123 456 + ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadBin# #{ readBin(file("tmptest/com.oracle.truffle.r.test.library.base.conn/wb1", "rb"), 3) } numeric(0) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java index 2aff030fb231737e9ef235ccda7fe76c4f3a44f8..8d7b2dcf1abc33ede8b98aa6ddc300275d0c5df2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConditionHandling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,9 +24,14 @@ package com.oracle.truffle.r.test.library.base; import org.junit.Test; -import com.oracle.truffle.r.test.TestBase; +import com.oracle.truffle.r.test.TestRBase; -public class TestConditionHandling extends TestBase { +public class TestConditionHandling extends TestRBase { + + @Override + public String getTestDir() { + return "library/base/condition"; + } @Test public void testTryCatch() { @@ -38,5 +43,25 @@ public class TestConditionHandling extends TestBase { assertEval(Ignored.Unknown, "{ tryCatch(stop(\"fred\"), error = function(e) e, finally = print(\"Hello\"))}"); assertEval("{ f <- function() { tryCatch(1, error = function(e) print(\"Hello\")); stop(\"fred\")}; f() }"); assertEval("{ f <- function() { tryCatch(stop(\"fred\"), error = function(e) print(\"Hello\"))}; f() }"); + assertEval("{ tryCatch(stop(\"xyz\"), error=function(e) { cat(\"<error>\");123L }, finally=function() { cat(\"<finally>\")}) }"); + } + + @Test + public void testWithRestarts() { + assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=function(a,b) c(a,b))"); + assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=list(description=\"my handler\", handler=function(a,b) c(a,b)))"); + assertEval("withRestarts({cat(\"<start>\");invokeRestart(\"foo\", 123L, 456L);789L},\n foo=function(a,b) {cat(\"<first>\");invokeRestart(\"foo\", a+1, b+1)},\n foo=function(a,b) {cat(\"<second>\");c(a,b)})"); + assertEval("withRestarts(findRestart(\"noSuchRestart\"),\n foo=function(a,b) c(a,b))"); + assertEval("withRestarts(findRestart(\"foo\"),\n foo=function(a,b) c(a,b))"); + assertEval("withRestarts(computeRestarts(),\n foo=function(a,b) c(a,b))"); + } + + @Test + public void testWithCallingHandlers() { + assertEval(Output.IgnoreWarningContext, "withCallingHandlers({warning(\"foo\");123L},\n warning=function(e) {cat(\"<warn>\")})"); + assertEval(Ignored.ImplementationError, "withCallingHandlers({warning(\"foo\");123L},\n warning=function(e) {\n cat(\"<warn>\")\n invokeRestart(\"muffleWarning\")\n })"); + assertEval("withCallingHandlers({message(\"foo\");123L},\n message=function(e) {cat(\"<msg>\")})"); + assertEval("withCallingHandlers({message(\"foo\");123L},\n message=function(e) {\n cat(\"<msg>\")\n invokeRestart(\"muffleMessage\")\n })"); + assertEval("withCallingHandlers({message(\"foo\");packageStartupMessage(\"bar\");123L},\n packageStartupMessage=function(e) {\n cat(\"<msg>\")\n invokeRestart(\"muffleMessage\")\n })"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R new file mode 100644 index 0000000000000000000000000000000000000000..85acd59a6af3d527c70000c57430fa4fdf38a0e7 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers0.R @@ -0,0 +1,33 @@ +# Ignored +myCondition <- function(message) structure(list(message=message, call=NULL), class=c("myCondition", "condition")) + +handle_myCondition <- function(e) { + print(paste("enter handle_myCondition", e)) + invokeRestart("continue_test") + print("after restart") +} + +fun0 <- function(code) { + withCallingHandlers({ + print(code) + eval(code) + }, + myCondition = handle_myCondition + ); + print("exit fun0") +} + +fun1 <- function(s) { + print(paste("enter fun1", s)) + withRestarts( + { signalCondition(myCondition(paste0("signal", s))); print("afterSignal") } , + continue_test = function(e) print("continue") + ) + print(paste("exit fun1", s)) + NULL +} + +fun0({ + fun1("first") + fun1("second") +}) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R new file mode 100644 index 0000000000000000000000000000000000000000..0345697134cae2a5c8b2e6513b4e799d20987530 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/condition/R/withCallingHandlers1.R @@ -0,0 +1,45 @@ +# Ignored +cond0 <- function(message) + structure(list(message=message, call=NULL), class=c("cond0", "condition")) + +cond1 <- function(message) + structure(list(message=message, call=NULL), class=c("cond1", "condition")) + +handle_cond0 <- function(e) { + print(paste("enter handle_cond0", e)) + invokeRestart("continue_test") + print("after cond0 restart") +} + +handle_cond1 <- function(e) { + print(paste("enter handle_cond1", e)) + signalCondition(e) + print("after cond1 restart") +} + +fun0 <- function(code) { + withCallingHandlers({ + print(code) + eval(code) + }, + cond0 = handle_cond0, + cond1 = handle_cond1 + ); + print("exit fun0") +} + +fun1 <- function(s) { + print(paste("enter fun1", s)) + withRestarts( + { signalCondition(cond1(paste0("signal", s)));signalCondition(cond0(paste0("signal", s))); print("afterSignal") } , + continue_test = function(e) print("continue") + ) + print(paste("exit fun1", s)) + NULL +} + +fun0({ + fun1("first") + fun1("second") +}) +