Skip to content

Commit

Permalink
Merge commit 'ee11fce71b248d77ac4d6d6af75a2a5b33c20035' into release/…
Browse files Browse the repository at this point in the history
…graal-vm/1.0
  • Loading branch information
ansalond committed Nov 28, 2018
2 parents 3a3e6cf + ee11fce commit 6b3d158
Show file tree
Hide file tree
Showing 194 changed files with 7,180 additions and 2,194 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
# 1.0 RC 10

New features:

* interop and tooling: READ and WRITE of ActiveBinding may have side effects. This is communicated via `KEY_INFO` to the tools and other languages (e.g., a debugger may warn before evaluating an ActiveBinding)
* the MRAN mirror used by FastR as default repo was moved to https://mran.microsoft.com/snapshot/2018-06-20
* new function `install.fastr.packages` to install FastR rJava replacement and possibly other packages in the future
* print the whole guest language stacktrace if an exception occurs during an interop call into another language

Added missing R builtins and C API

* `pos.to.env` builtin
* private `do_fmin` external function from the stats packages used by public R function `optimize`
* `beta` #33

Bug fixes:

* tooling: top level statements are not marked as functions (e.g., a debugger will not treat them as such anymore)
* update rpath correctly for redistributed libraries when producing a release build. This issue caused linking problems for MacOS users #26
* UseMethod caused internal error under some specific circumstances (happens during installation of the R.oo package)
* fully support indirect use of .Internal, e.g. in `(get('.Internal'))(paste0(list(1,2),','))`
* `as.character(external-pointer)` does not crash, but prints the pointer address #28
* `file.path` with `NULL` as one of its arguments gives correct result (empty character vector)
* `format.POSIXlt` uses the same time zone database as rest of the system #29
* `dev.control(displaylist = 'inhibit')` caused `ClassCastException`
* `download.file` follows redirects.
* static members of Java interop objects are not ignored during printing and deparsing
* fixed internal error in `on.exit(NULL)`
* fixed `mget` to accept also non list values for `ifnotfound`
* updating dimensions of a vector always resets the dimnames. #34
* `env2list` used in, e.g., `as.list.environment` can handle `...` inside the environment

# 1.0 RC 9

New features

* various improvements in handling of foreign objects in R
* [brief overview in the documentation](http://www.graalvm.org/docs/reference-manual/languages/r/#foreign)
* [executable specification](https://github.com/oracle/fastr/blob/master/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/R/interop-array-conversion-test.R#L158)

Added missing R builtins and C API

Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
A high performance implementation of the R programming language., built on the GraalVM by Oracle Labs.
[![Join the chat at https://gitter.im/graalvm/graal-core](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graalvm/graal-core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

A high-performance implementation of the R programming language, built on GraalVM.

FastR aims to be:
* [efficient](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#4ab6): executing R language scripts faster than any other R runtime.
* [efficient](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#4ab6): executing R language scripts faster than any other R runtime
* [polyglot](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#0f5c): allowing [polyglot interoperability](https://www.graalvm.org/docs/reference-manual/polyglot/) with other languages in the GraalVM ecosystem.
* [compatible](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#fff5): providing support for existing packages and the R native interface.
* [embeddable](https://github.com/graalvm/examples/tree/master/r_java_embedding): allowing integration using the R embedding API or the GraalVM polyglot embedding SDK.
* [compatible](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#fff5): providing support for existing packages and the R native interface
* [embeddable](https://github.com/graalvm/examples/tree/master/r_java_embedding): allowing integration using the R embedding API or the GraalVM polyglot embedding SDK


The screenshot below shows Java application with embedded FastR engine.
The plot below was generated by `ggplot2` running on FastR and it shows
peak performance of the [raytracing example](http://www.tylermw.com/throwing-shade/).
The measurements were [reproduced independently](https://nextjournal.com/sdanisch/fastr-benchmark).

![Java embedding](documentation/assets/javaui.png)
![Speedup](documentation/assets/speedup.png)

## Getting Started
See the documentation on the GraalVM website on how to [get GraalVM](https://www.graalvm.org/docs/getting-started/) and [install and use FastR](http://www.graalvm.org/docs/reference-manual/languages/r/).
Expand Down
7 changes: 6 additions & 1 deletion ci_common/common.hocon
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ logfiles : [
"com.oracle.truffle.r.test.native/embedded/src/*.output"
# Uncomment to debug pkgtest issues, produces lot of logs!
"test.fastr/**/*.Rout"
"test.fastr/**/*.fail"
"test.fastr/**/*-tests/*.Rout"
"test.gnur/**/*.Rout"
"test.gnur/**/*-tests/*.Rout"
"test.gnur/**/*.fail"
# Uncomment to debug the event loop hanging issue. It must be accompanied by enabling
# the logging by setting the TRACE_EVENT_LOOP env var to true.
# "traceEventLoop.log"
]

# This is needed by all (Linux) builds but is specific to the module system employed
Expand Down Expand Up @@ -223,7 +228,7 @@ rbcheck : ${common} {
internalPkgtest: ${common} {
run : [
["mx", "build"]
["mx", "pkgtest", "--repos", "FASTR", "--pkg-filelist", "com.oracle.truffle.r.test.native/packages/pkg-filelist"]
["mx", "pkgtest", "--verbose", "--repos", "FASTR", "--pkg-filelist", "com.oracle.truffle.r.test.native/packages/pkg-filelist"]
]
logs: ${common.logs}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleException;
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand Down Expand Up @@ -91,6 +92,9 @@ public Object execute(VirtualFrame frame) {
throw e;
} catch (Throwable t) {
CompilerDirectives.transferToInterpreter();
if (t instanceof TruffleException && !((TruffleException) t).isInternalError()) {
throw t;
}
// other errors didn't produce an output yet
RInternalError.reportError(t);
throw t;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ private EngineRootNode createRScriptRoot(Source fullSource, MaterializedFrame fr

@Override
@TruffleBoundary
public Object eval(RExpression exprs, REnvironment envir, RCaller caller) {
public Object eval(RExpression exprs, REnvironment envir, Object callerFrame, RCaller caller, RFunction function) {
Object result = RNull.instance;
for (int i = 0; i < exprs.getLength(); i++) {
Object obj = exprs.getDataAt(i);
Expand All @@ -427,7 +427,7 @@ public Object eval(RExpression exprs, REnvironment envir, RCaller caller) {
throw RError.error(RError.SHOW_CALLER, RError.Message.ARGUMENT_MISSING, identifier);
}
} else if ((obj instanceof RPairList && ((RPairList) obj).isLanguage())) {
result = eval((RPairList) obj, envir, caller);
result = eval((RPairList) obj, envir, callerFrame, caller, function);
} else {
result = obj;
}
Expand All @@ -437,9 +437,9 @@ public Object eval(RExpression exprs, REnvironment envir, RCaller caller) {

@Override
@TruffleBoundary
public Object eval(RPairList expr, REnvironment envir, RCaller caller) {
public Object eval(RPairList expr, REnvironment envir, Object callerFrame, RCaller caller, RFunction function) {
assert expr.isLanguage();
return expr.getClosure().eval(envir, caller);
return expr.getClosure().eval(envir, callerFrame, caller, function);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,16 @@ abstract static class REnvironmentKeyInfoImplNode extends Node {

@Specialization
protected int access(REnvironment receiver, String identifier) {
Object val = receiver.get(identifier);
if (val == null) {
return 0;
}
Object val = null;
int result = KeyInfo.READABLE;
if (receiver.isActiveBinding(identifier)) {
result |= KeyInfo.READ_SIDE_EFFECTS | KeyInfo.WRITE_SIDE_EFFECTS;
} else {
val = receiver.get(identifier);
if (val == null) {
return 0;
}
}
if (!receiver.isLocked() && !receiver.bindingIsLocked(identifier)) {
result |= KeyInfo.MODIFIABLE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private static void runRmainloop() {
RContext ctx = RContext.getInstance();
ctx.completeEmbeddedInitialization();
ctx.getRFFI().initializeEmbedded(ctx);
int status = REPL.readEvalPrint(context, consoleHandler, false);
int status = REPL.readEvalPrint(context, consoleHandler, false, System.err);
context.leave();
context.close();
Utils.systemExit(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,25 +75,29 @@
import com.oracle.truffle.r.runtime.data.RComplexVector;
import com.oracle.truffle.r.runtime.data.RDataFactory;
import com.oracle.truffle.r.runtime.data.RDoubleVector;
import com.oracle.truffle.r.runtime.data.REmpty;
import com.oracle.truffle.r.runtime.data.RExpression;
import com.oracle.truffle.r.runtime.data.RExternalPtr;
import com.oracle.truffle.r.runtime.data.RFunction;
import com.oracle.truffle.r.runtime.data.RIntVector;
import com.oracle.truffle.r.runtime.data.RPairList;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RLogicalVector;
import com.oracle.truffle.r.runtime.data.RMissing;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RObject;
import com.oracle.truffle.r.runtime.data.RPairList;
import com.oracle.truffle.r.runtime.data.RPromise;
import com.oracle.truffle.r.runtime.data.RRaw;
import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise;
import com.oracle.truffle.r.runtime.data.RRaw;
import com.oracle.truffle.r.runtime.data.RRawVector;
import com.oracle.truffle.r.runtime.data.RShareable;
import com.oracle.truffle.r.runtime.data.RStringVector;
import com.oracle.truffle.r.runtime.data.RSymbol;
import com.oracle.truffle.r.runtime.data.RTypedValue;
import com.oracle.truffle.r.runtime.data.RUnboundValue;
import com.oracle.truffle.r.runtime.data.RVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
Expand Down Expand Up @@ -224,7 +228,11 @@ public void Rf_defineVar(Object symbolArg, Object value, Object envArg) {
REnvironment env = (REnvironment) envArg;
RSymbol name = (RSymbol) symbolArg;
try {
env.put(name.getName(), value);
if (value == RUnboundValue.instance) {
env.rm(name.getName());
} else {
env.put(name.getName(), value);
}
} catch (PutException ex) {
throw RError.error(RError.SHOW_CALLER2, ex);
}
Expand Down Expand Up @@ -283,7 +291,11 @@ private static Object findVarInFrameHelper(Object envArg, Object symbolArg, bool
return ((RPromise) value).getRawValue();
}
if (value instanceof RArgsValuesAndNames) {
return ((RArgsValuesAndNames) value).toPairlist();
RArgsValuesAndNames argsValsNames = (RArgsValuesAndNames) value;
return argsValsNames.isEmpty() ? RSymbol.MISSING : argsValsNames.toPairlist();
}
if (value == RMissing.instance || value == REmpty.instance) {
return RSymbol.MISSING;
}
return value;
}
Expand Down Expand Up @@ -460,6 +472,8 @@ public Object Rf_allocVector(int mode, long n) {
case LISTSXP:
case LANGSXP:
return RDataFactory.createPairList(ni, type);
case NILSXP:
return RNull.instance;
default:
throw unimplemented("unexpected SEXPTYPE " + type);
}
Expand Down Expand Up @@ -727,7 +741,7 @@ public Object PRINTNAME(Object x) {
return x;
}
guaranteeInstanceOf(x, RSymbol.class);
return CharSXPWrapper.create(((RSymbol) x).getName());
return ((RSymbol) x).getWrappedName();
}

@Override
Expand Down Expand Up @@ -1619,8 +1633,7 @@ public int registerRoutines(Object dllInfoObj, int nstOrd, int num, Object routi
@Override
@TruffleBoundary
public int registerCCallable(String pkgName, String functionName, Object address) {
DLLInfo lib = DLL.safeFindLibrary(pkgName);
lib.registerCEntry(new CEntry(functionName, new SymbolHandle(address)));
DLLInfo.registerCEntry(pkgName, new CEntry(functionName, new SymbolHandle(address)));
return 0;
}

Expand Down Expand Up @@ -2399,8 +2412,12 @@ public Object LOGICAL(Object x) {
}

@Override
@TruffleBoundary
public Object REAL(Object x) {
return VectorRFFIWrapper.get(guaranteeVectorOrNull(x, RDoubleVector.class));
if ((x instanceof RAbstractStringVector) || (x instanceof RAbstractListBaseVector)) {
RFFIUtils.unimplemented("REAL is being called for type " + Utils.getTypeName(x));
}
return VectorRFFIWrapper.get(guaranteeVectorOrNull(x, RAbstractAtomicVector.class));
}

@Override
Expand Down Expand Up @@ -2433,6 +2450,11 @@ public Object R_forceAndCall(Object e, Object f, int n, Object args) {
throw implementedAsNode();
}

@Override
public void R_MakeActiveBinding(Object symArg, Object funArg, Object envArg) {
throw implementedAsNode();
}

private static TruffleObject guaranteeVectorOrNull(Object obj, Class<? extends TruffleObject> clazz) {
if (obj == RNull.instance) {
return RNull.instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.Utils;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RObject;
import com.oracle.truffle.r.runtime.data.RPairList;
import com.oracle.truffle.r.runtime.data.RSymbol;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
import com.oracle.truffle.r.runtime.ffi.RFFIContext;
import com.oracle.truffle.r.runtime.ffi.RFFILog;

Expand Down Expand Up @@ -121,32 +120,20 @@ private static void printArgs(CallMode mode, StringBuilder sb, Object[] args) {
sb.append("null");
continue;
}
sb.append(arg.getClass().getSimpleName()).append('(').append(arg.hashCode());
sb.append(arg.getClass().getSimpleName()).append('(').append(arg.hashCode()).append(';');
if (arg instanceof TruffleObject && ForeignAccess.sendIsPointer(getIsPointerNode(), (TruffleObject) arg)) {
try {
sb.append(";ptr:").append(String.valueOf(ForeignAccess.sendAsPointer(getAsPointerNode(), (TruffleObject) arg)));
sb.append("ptr:").append(Long.toHexString(ForeignAccess.sendAsPointer(getAsPointerNode(), (TruffleObject) arg)));
} catch (UnsupportedMessageException e) {
throw RInternalError.shouldNotReachHere();
}
} else if (arg instanceof RSymbol) {
sb.append(';').append("\"" + arg.toString() + "\"");
} else if (arg instanceof RAbstractVector) {
RAbstractVector vec = (RAbstractVector) arg;
if (vec.getLength() == 0) {
sb.append(";empty");
} else {
sb.append(";len:" + vec.getLength() + ";data:");
for (int i = 0; i < Math.min(3, vec.getLength()); i++) {
String str = ((RAbstractVector) arg).getDataAtAsObject(0).toString();
str = str.length() > 30 ? str.substring(0, 27) + "..." : str;
sb.append(',').append(str);
}
}
} else {
Utils.printDebugInfo(sb, arg);
}
// Note: it makes sense to include native mirrors only once they have been create
// already
if (mode.logNativeMirror && arg instanceof RObject) {
sb.append(";" + ((RObject) arg).getNativeMirror());
sb.append(((RObject) arg).getNativeMirror());
}
sb.append(')');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
Expand Down Expand Up @@ -180,6 +181,7 @@ private LLVMArchive(LLVM_IR[] irs, List<String> nativeLibs) {
}
}

@TruffleBoundary
public static LLVMArchive getZipLLVMIR(String path) {
List<String> nativeLibs = Collections.emptyList();
try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(path + "l")))) {
Expand Down Expand Up @@ -248,6 +250,7 @@ private static class TruffleLLVM_DLOpenNode extends Node implements DLOpenNode {
* the IR has not been parsed yet.
*/
@Override
@TruffleBoundary
public Object execute(String path, boolean local, boolean now) {
try {
LLVMArchive ar = getZipLLVMIR(path);
Expand Down Expand Up @@ -365,6 +368,7 @@ private static String getLibName(String path) {
*/
private LLVM_IR[] libRModules;

@TruffleBoundary
private static CallTarget parseLLVM(String libName, LLVM_IR ir) {
if (ir instanceof LLVM_IR.Binary) {
LLVM_IR.Binary bir = (LLVM_IR.Binary) ir;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/
package com.oracle.truffle.r.ffi.impl.llvm;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.InteropException;
import com.oracle.truffle.api.interop.Message;
Expand Down Expand Up @@ -92,6 +93,7 @@ public Object Rf_mkCharLenCE(Object obj, int len, int encoding) {
}

@Override
@TruffleBoundary
public Object R_Home() {
byte[] sbytes = REnvVars.rHome().getBytes();
return new NativeCharArray(sbytes);
Expand Down Expand Up @@ -127,8 +129,7 @@ public Object getCallback(int index) {

@Override
public Object getCCallable(String pkgName, String functionName) {
DLLInfo lib = DLL.safeFindLibrary(pkgName);
CEntry result = lib.lookupCEntry(functionName);
CEntry result = DLLInfo.lookupCEntry(pkgName, functionName);
if (result == null) {
throw RError.error(RError.NO_CALLER, RError.Message.UNKNOWN_OBJECT, functionName);
}
Expand Down
Loading

0 comments on commit 6b3d158

Please sign in to comment.