From cefea8cc24ce145cb94c6537430c0304ae32bb6b Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Mon, 11 Sep 2017 15:56:42 +0200 Subject: [PATCH] NFI based Parse.c implementation --- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 28 ++++++++--- .../r/ffi/impl/common/ParseResult.java | 46 ------------------- .../fficall/src/common/rffi_upcalls.h | 2 + .../fficall/src/truffle_common/Parse.c | 26 ++--------- .../packages/testrffi/testrffi/R/testrffi.R | 4 ++ .../packages/testrffi/testrffi/src/init.c | 1 + .../packages/testrffi/testrffi/src/testrffi.c | 14 +++++- .../packages/testrffi/testrffi/src/testrffi.h | 2 + .../testrffi/testrffi/tests/simpleTests.R | 4 ++ 9 files changed, 52 insertions(+), 75 deletions(-) delete mode 100644 com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/ParseResult.java diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index ebb04b5f27..9c843d17e4 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -44,7 +44,6 @@ 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.ffi.impl.common.ParseResult.ParseStatus; import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; @@ -66,6 +65,7 @@ import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection; import com.oracle.truffle.r.runtime.conn.ConnectionSupport.InvalidConnection; import com.oracle.truffle.r.runtime.conn.NativeConnections.NativeRConnection; import com.oracle.truffle.r.runtime.conn.RConnection; +import com.oracle.truffle.r.runtime.context.Engine.IncompleteSourceException; import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; @@ -1058,22 +1058,36 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { return p.isEvaluated() ? p.getValue() : RUnboundValue.instance; } + private enum ParseStatus { + PARSE_NULL, + PARSE_OK, + PARSE_INCOMPLETE, + PARSE_ERROR, + PARSE_EOF + } + @Override public Object R_ParseVector(Object text, int n, Object srcFile) { - // TODO general case - assert n == 1; - assert srcFile == RNull.instance; + // TODO general case + all statuses + assert n == 1 : "unsupported: R_ParseVector with n != 0."; + assert srcFile == RNull.instance : "unsupported: R_ParseVector with non-null srcFile argument."; String textString = RRuntime.asString(text); assert textString != null; + Object[] resultData = new Object[2]; try { Source source = RSource.fromTextInternal(textString, RSource.Internal.R_PARSEVECTOR); RExpression exprs = RContext.getEngine().parse(source); - return new ParseResult(ParseStatus.PARSE_OK.ordinal(), exprs); + resultData[0] = RDataFactory.createIntVectorFromScalar(ParseStatus.PARSE_OK.ordinal()); + resultData[1] = exprs; + } catch (IncompleteSourceException ex) { + resultData[0] = RDataFactory.createIntVectorFromScalar(ParseStatus.PARSE_INCOMPLETE.ordinal()); + resultData[1] = RNull.instance; } catch (ParseException ex) { - // TODO incomplete - return new ParseResult(ParseStatus.PARSE_ERROR.ordinal(), RNull.instance); + resultData[0] = RDataFactory.createIntVectorFromScalar(ParseStatus.PARSE_ERROR.ordinal()); + resultData[1] = RNull.instance; } + return RDataFactory.createList(resultData); } @Override diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/ParseResult.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/ParseResult.java deleted file mode 100644 index 58cf577ae8..0000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/ParseResult.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.ffi.impl.common; - -import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI; - -/** - * Used in implementation of {@link UpCallsRFFI#R_ParseVector(Object, int, Object)}. - */ -public class ParseResult { - public enum ParseStatus { - PARSE_NULL, - PARSE_OK, - PARSE_INCOMPLETE, - PARSE_ERROR, - PARSE_EOF - } - - @SuppressWarnings("unused") private final int parseStatus; - @SuppressWarnings("unused") private final Object expr; - - ParseResult(int parseStatus, Object expr) { - this.parseStatus = parseStatus; - this.expr = expr; - } -} diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index 3e7d642615..9c61534e99 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -278,6 +278,8 @@ typedef double (*call_Rf_runif)(double x, double y); typedef SEXP (*call_getvar)(); +typedef SEXP (*call_R_ParseVector)(SEXP text, int n, SEXP srcFile); + // connections typedef int (*call_FASTR_getConnectionChar)(SEXP connection); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Parse.c b/com.oracle.truffle.r.native/fficall/src/truffle_common/Parse.c index 41aabde10d..f23500e579 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Parse.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Parse.c @@ -21,29 +21,13 @@ * questions. */ +#include "../truffle_nfi/rffiutils.h" +#include "rffi_upcalls.h" -#if FALSE - -#include <rffiutils.h> #include <R_ext/Parse.h> -static jmethodID parseMethodID; -static jclass parseResultClass; -static jfieldID parseStatusFieldID; -static jfieldID parseExprFieldID; - - -void init_parse(JNIEnv *env) { - parseMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ParseVector", "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;", 0); - parseResultClass = checkFindClass(env, "com/oracle/truffle/r/ffi/impl/common/ParseResult"); - parseStatusFieldID = checkGetFieldID(env, parseResultClass, "parseStatus", "I", 0); - parseExprFieldID = checkGetFieldID(env, parseResultClass, "expr", "Ljava/lang/Object;", 0); -} - SEXP R_ParseVector(SEXP text, int n, ParseStatus *z, SEXP srcfile) { - JNIEnv *env = getEnv(); - jobject result = (*env)->CallObjectMethod(env, UpCallsRFFIObject, parseMethodID, text, n, srcfile); - *z = (*env)->GetIntField(env, result, parseStatusFieldID); - return (*env)->GetObjectField(env, result, parseExprFieldID); + SEXP resultList = ((call_R_ParseVector)callbacks[R_ParseVector_x])(text, n, srcfile); + *z = Rf_asInteger(VECTOR_ELT(resultList, 0)); + return VECTOR_ELT(resultList, 1); } -#endif diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R index 90b45a76cf..62ed8ab623 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R @@ -187,4 +187,8 @@ rffi.readConnection <- function(connection) { rffi.createNativeConnection <- function() { .Call('test_createNativeConnection'); +} + +rffi.parseVector <- function(x) { + .Call('test_ParseVector', x); } \ No newline at end of file diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c index ba9eb2458c..9daac422f9 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c @@ -80,6 +80,7 @@ static const R_CallMethodDef CallEntries[] = { CALLDEF(test_writeConnection, 1), CALLDEF(test_readConnection, 1), CALLDEF(test_createNativeConnection, 0), + CALLDEF(test_ParseVector, 1), {NULL, NULL, 0} }; diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c index 92287d4ab1..4c6ff95296 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, 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 @@ -29,6 +29,7 @@ #include <Rinternals.h> #include <Rinterface.h> #include <R_ext/Connections.h> +#include <R_ext/Parse.h> #include <string.h> #include "testrffi.h" @@ -521,3 +522,14 @@ SEXP test_createNativeConnection() { // customConn->read = &testrfficonn_read; TODO: read test return newConnSEXP; } + +SEXP test_ParseVector(SEXP src) { + ParseStatus status; + SEXP parseResult, result; + PROTECT(parseResult = R_ParseVector(src, 1, &status, R_NilValue)); + PROTECT(result = allocVector(VECSXP, 2)); + SET_VECTOR_ELT(result, 0, ScalarInteger(status)); + SET_VECTOR_ELT(result, 1, parseResult); + UNPROTECT(2); + return result; +} diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h index 21f9e40baf..7ff8cb06fd 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h @@ -103,3 +103,5 @@ extern SEXP test_writeConnection(SEXP conn); extern SEXP test_readConnection(SEXP conn); extern SEXP test_createNativeConnection(void); + +extern SEXP test_ParseVector(SEXP src); diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R index 3a8138ae62..9a19441a3d 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R @@ -76,3 +76,7 @@ rffi.inlined_length(expr[[1]]) # # foo <-function(...) rffi.inlined_length(get('...')) # foo(a = 1, b = 2, c = 3, d = 42) + +rffi.parseVector('1+2') +rffi.parseVector('.*/-') +rffi.parseVector('1+') \ No newline at end of file -- GitLab