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 ebb04b5f2793fb4dd6b38a2cc01c94dd068c027a..9c843d17e479d0926983bf2ccc60cb1d05822cbf 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 58cf577ae84cdb4e2567e0833b33cb903da95543..0000000000000000000000000000000000000000 --- 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 3e7d642615c2b02c03a5ae61beabacc8f44ebec2..9c61534e993b8c6edd9958bef86444aaf5530046 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 41aabde10d90f0d486e90eee8588d8010c49d7e2..f23500e5796112a92e58884ce7eeceb30718459a 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 90b45a76cf1be0f632fed1852a3ac71753bda0e6..62ed8ab62363727eb86855c58a00a5f07e26ecbb 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 ba9eb2458ca0b7de44e4d4507546d8e116a537b8..9daac422f9de74ef90a644ee768c5e1b024fa12b 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 92287d4ab1bc044c3b1e01fc39e35af2ac939fd8..4c6ff95296c808e8c9851be271321aa3a228ab8f 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 21f9e40baf191b055e864ec3e2b5cd668a8e06ef..7ff8cb06fdae73a648451b91e11a03e90a3837a8 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 3a8138ae628d02b5991bf4a9829e902b08d9a51a..9a19441a3d01171a59c18bf285ebcab12b8281a1 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