Skip to content
Snippets Groups Projects
Commit 912cc6f5 authored by Stepan Sindelar's avatar Stepan Sindelar
Browse files

[GR-8319] Make RFFI implementation aware of R embedding.

PullRequest: fastr/1406
parents fd8d7272 5e9ba338
No related branches found
No related tags found
No related merge requests found
...@@ -71,7 +71,7 @@ public class REmbedded { ...@@ -71,7 +71,7 @@ public class REmbedded {
* initialize FastR as we cannot do that until the embedding system has had a chance to adjust * initialize FastR as we cannot do that until the embedding system has had a chance to adjust
* the {@link RStartParams}, which happens after this call returns. * the {@link RStartParams}, which happens after this call returns.
*/ */
private static void initializeR(String[] args) { private static void initializeR(String[] args, boolean initMainLoop) {
assert context == null; assert context == null;
RContext.setEmbedded(); RContext.setEmbedded();
RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args, false); RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args, false);
...@@ -86,6 +86,14 @@ public class REmbedded { ...@@ -86,6 +86,14 @@ public class REmbedded {
context = Context.newBuilder().allowHostAccess(true).arguments("R", options.getArguments()).in(input).out(stdOut).err(stdErr).build(); context = Context.newBuilder().allowHostAccess(true).arguments("R", options.getArguments()).in(input).out(stdOut).err(stdErr).build();
consoleHandler.setContext(context); consoleHandler.setContext(context);
context.eval(INIT); context.eval(INIT);
if (initMainLoop) {
context.enter();
RContext ctx = RContext.getInstance();
ctx.completeEmbeddedInitialization();
ctx.getRFFI().initializeEmbedded(ctx);
// stay in the context TODO should we?
}
} }
/** /**
...@@ -110,12 +118,10 @@ public class REmbedded { ...@@ -110,12 +118,10 @@ public class REmbedded {
*/ */
private static final Source INIT = Source.newBuilder("R", "1", "<embedded>").buildLiteral(); private static final Source INIT = Source.newBuilder("R", "1", "<embedded>").buildLiteral();
/** private static void endRmainloop(int status) {
* GnuR distinguishes {@code setup_Rmainloop} and {@code run_Rmainloop}. Currently we don't have context.leave();
* the equivalent separation in FastR. context.close();
*/ Utils.systemExit(status);
private static void setupRmainloop() {
// nothing to do
} }
/** /**
...@@ -124,7 +130,9 @@ public class REmbedded { ...@@ -124,7 +130,9 @@ public class REmbedded {
*/ */
private static void runRmainloop() { private static void runRmainloop() {
context.enter(); context.enter();
RContext.getInstance().completeEmbeddedInitialization(); RContext ctx = RContext.getInstance();
ctx.completeEmbeddedInitialization();
ctx.getRFFI().initializeEmbedded(ctx);
int status = RCommand.readEvalPrint(context, consoleHandler); int status = RCommand.readEvalPrint(context, consoleHandler);
context.leave(); context.leave();
context.close(); context.close();
...@@ -135,8 +143,7 @@ public class REmbedded { ...@@ -135,8 +143,7 @@ public class REmbedded {
* Testing vehicle, emulates a native upcall. * Testing vehicle, emulates a native upcall.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
initializeR(args); initializeR(args, false);
setupRmainloop();
runRmainloop(); runRmainloop();
} }
......
...@@ -35,6 +35,7 @@ import java.util.List; ...@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.ForeignAccess;
...@@ -140,6 +141,7 @@ public final class Managed_DownCallNodeFactory extends DownCallNodeFactory { ...@@ -140,6 +141,7 @@ public final class Managed_DownCallNodeFactory extends DownCallNodeFactory {
public CallTarget accessExecute(int argumentsLength) { public CallTarget accessExecute(int argumentsLength) {
return Truffle.getRuntime().createCallTarget(new RootNode(null) { return Truffle.getRuntime().createCallTarget(new RootNode(null) {
@Override @Override
@TruffleBoundary
public Object execute(VirtualFrame frame) { public Object execute(VirtualFrame frame) {
NativeCharArray templateBytes = (NativeCharArray) ForeignAccess.getArguments(frame).get(0); NativeCharArray templateBytes = (NativeCharArray) ForeignAccess.getArguments(frame).get(0);
String template = new String(templateBytes.getValue(), 0, templateBytes.getValue().length - 1); String template = new String(templateBytes.getValue(), 0, templateBytes.getValue().length - 1);
...@@ -191,6 +193,7 @@ public final class Managed_DownCallNodeFactory extends DownCallNodeFactory { ...@@ -191,6 +193,7 @@ public final class Managed_DownCallNodeFactory extends DownCallNodeFactory {
public CallTarget accessExecute(int argumentsLength) { public CallTarget accessExecute(int argumentsLength) {
return Truffle.getRuntime().createCallTarget(new RootNode(null) { return Truffle.getRuntime().createCallTarget(new RootNode(null) {
@Override @Override
@TruffleBoundary
public Object execute(VirtualFrame frame) { public Object execute(VirtualFrame frame) {
NativeCharArray buffer = (NativeCharArray) ForeignAccess.getArguments(frame).get(0); NativeCharArray buffer = (NativeCharArray) ForeignAccess.getArguments(frame).get(0);
byte[] bytes = Paths.get(".").toAbsolutePath().normalize().toString().getBytes(); byte[] bytes = Paths.get(".").toAbsolutePath().normalize().toString().getBytes();
......
...@@ -196,6 +196,11 @@ final class TruffleNFI_Context extends RFFIContext { ...@@ -196,6 +196,11 @@ final class TruffleNFI_Context extends RFFIContext {
} }
} }
@Override
public void initializeEmbedded(RContext context) {
pushCallbacks();
}
@TruffleBoundary @TruffleBoundary
private long initCallbacksAddress() { private long initCallbacksAddress() {
// get the address of the native thread local // get the address of the native thread local
......
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RObject;
...@@ -101,6 +102,17 @@ public abstract class RFFIContext extends RFFI { ...@@ -101,6 +102,17 @@ public abstract class RFFIContext extends RFFI {
public void initializeVariables(RContext context) { public void initializeVariables(RContext context) {
} }
/**
* Invoked as part of the R embedded initialization just before returning back to the C user
* code. Should do any set-up necessary for the RFFI to be fully functional even outside the
* context of a down-call. At the moment the assumption is that embedded code is always single
* threaded and always creates exactly one context. This method shall be invoked after
* {@link #initialize(RContext)} and {@link #initializeVariables(RContext)}.
*/
public void initializeEmbedded(RContext context) {
throw RInternalError.unimplemented("R Embedding not supported with " + this.getClass().getSimpleName() + " RFFI backend.");
}
public long beforeDowncall() { public long beforeDowncall() {
callDepth++; callDepth++;
return 0; return 0;
......
...@@ -58,6 +58,7 @@ public final class NativeCharArray extends NativeUInt8Array { ...@@ -58,6 +58,7 @@ public final class NativeCharArray extends NativeUInt8Array {
/** /**
* Finds the null terminator and creates the Java String accordingly. * Finds the null terminator and creates the Java String accordingly.
*/ */
@TruffleBoundary
public String getStringFromOutputBuffer() { public String getStringFromOutputBuffer() {
assert !fakesNullTermination() : "create the buffer string via createOutputBuffer()"; assert !fakesNullTermination() : "create the buffer string via createOutputBuffer()";
byte[] mbuf = getValue(); byte[] mbuf = getValue();
......
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