From c86f96f8f8a13dfa73f136719ae42a1540ddac97 Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Tue, 15 Dec 2015 13:56:05 -0800 Subject: [PATCH] FFI fixes for installation of packages with C++ --- com.oracle.truffle.r.native/fficall/README | 4 ++-- .../fficall/src/common/arithmetic.c | 5 +++++ .../fficall/src/jni/Makefile | 10 +++++++-- .../fficall/src/jni/Rinternals.c | 8 +++++++ .../stats/src => fficall/src/jni}/xxxpr.f | 0 mx.fastr/mx_fastr_pkgtest.py | 22 ++++++++++++++++--- 6 files changed, 42 insertions(+), 7 deletions(-) rename com.oracle.truffle.r.native/{library/stats/src => fficall/src/jni}/xxxpr.f (100%) diff --git a/com.oracle.truffle.r.native/fficall/README b/com.oracle.truffle.r.native/fficall/README index beac20fa51..8f67219eef 100644 --- a/com.oracle.truffle.r.native/fficall/README +++ b/com.oracle.truffle.r.native/fficall/README @@ -5,8 +5,8 @@ fficall contains the implementation of the R FFI, as described in https://cran.r jni 'jni' contains the implementation that is based on Java JNI. 'common' contains code that has no JNI dependencies and has been extracted for - reuse in other implementations. Note however, that common cannot be compiled in isolation, as it depends on the implementation via rffiutils.h. - During the build symbolic lionk are made to the files in command and they are compiled with the other 'jni' files. + reuse in other implementations. Note however, that the common files cannot all be compiled in isolation, as they may depend on the implementation + via rffiutils.h. During the build symbolic links are made to the files in common and they are compiled with the other 'jni' files. The R FFI is rather baroque and defined in large set of header files in the sibling 'include' directory. In GnuR, the implementation of the functions is spread over the GnuR C files in 'src/main'. To ease navigation of the FastR implementation, in general, the implementation diff --git a/com.oracle.truffle.r.native/fficall/src/common/arithmetic.c b/com.oracle.truffle.r.native/fficall/src/common/arithmetic.c index fb36b55c42..17ea1d495f 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/arithmetic.c +++ b/com.oracle.truffle.r.native/fficall/src/common/arithmetic.c @@ -92,6 +92,11 @@ int R_IsNaN(double x) return 0; } +int R_isnancpp(double x) +{ + return (isnan(x)!=0); +} + /* Mainly for use in packages */ int R_finite(double x) { diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Makefile b/com.oracle.truffle.r.native/fficall/src/jni/Makefile index abde616517..b922b435e8 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Makefile +++ b/com.oracle.truffle.r.native/fficall/src/jni/Makefile @@ -49,6 +49,9 @@ C_SOURCES = $(C_LOCAL_SOURCES) $(C_COMMON_SOURCES) C_OBJECTS := $(patsubst %.c,$(OBJ)/%.o,$(C_SOURCES)) #$(info C_OBJECTS=$(C_OBJECTS)) +F_SOURCES := $(wildcard *.f) +F_OBJECTS := $(patsubst %.f,$(OBJ)/%.o,$(F_SOURCES)) + JNI_INCLUDES = -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(JDK_OS_DIR) FFI_INCLUDES = -I$(TOPDIR)/include -I$(TOPDIR)/gnur/R-3.1.3/src/include -I$(TOPDIR)/include/R_ext @@ -62,8 +65,8 @@ all: Makefile $(C_COMMON_SOURCES) $(C_LIB) links: $(foreach file,$(C_COMMON_SOURCES),ln -sf $(COMMON)/$(file) $(file);) -$(C_LIB): $(OBJ) $(C_OBJECTS) - $(DYLIB_LD) $(DYLIB_LDFLAGS) -o $(C_LIB) $(C_OBJECTS) +$(C_LIB): $(OBJ) $(C_OBJECTS) $(F_OBJECTS) + $(DYLIB_LD) $(DYLIB_LDFLAGS) -o $(C_LIB) $(C_OBJECTS) $(F_OBJECTS) $(OBJ): mkdir -p $(OBJ) @@ -74,6 +77,9 @@ $(OBJ)/%.o: %.c $(TOPDIR)/include/Rinternals.h $(C_HDRS) $(OBJ)/%.E: %.c $(TOPDIR)/include/Rinternals.h $(CC) -E $(CFLAGS) $(INCLUDES) -c $< > $@ +$(OBJ)/%.o: %.f + $(F77) $(FFLAGS) $(FPICFLAGS) -c $< -o $@ + clean: rm -rf $(OBJ) $(C_LIB) $(foreach file,$(C_COMMON_SOURCES),rm -f $(file);) 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 ebfb83cbc6..2dd7d6b971 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -299,6 +299,10 @@ void Rf_copyMostAttrib(SEXP x, SEXP y) { unimplemented("Rf_copyMostAttrib"); } +void Rf_copyVector(SEXP x, SEXP y) { + unimplemented("Rf_copyVector"); +} + Rboolean Rf_inherits(SEXP x, const char * klass) { JNIEnv *thisenv = getEnv(); jstring klazz = (*thisenv)->NewStringUTF(thisenv, klass); @@ -516,6 +520,10 @@ void R_FlushConsole(void) { // ignored } +void R_ProcessEvents(void) { + unimplemented("R_ProcessEvents"); +} + // Tools package support, not in public API SEXP R_NewHashedEnv(SEXP parent, SEXP size) { diff --git a/com.oracle.truffle.r.native/library/stats/src/xxxpr.f b/com.oracle.truffle.r.native/fficall/src/jni/xxxpr.f similarity index 100% rename from com.oracle.truffle.r.native/library/stats/src/xxxpr.f rename to com.oracle.truffle.r.native/fficall/src/jni/xxxpr.f diff --git a/mx.fastr/mx_fastr_pkgtest.py b/mx.fastr/mx_fastr_pkgtest.py index 1a29ccb187..3e7a10fd79 100644 --- a/mx.fastr/mx_fastr_pkgtest.py +++ b/mx.fastr/mx_fastr_pkgtest.py @@ -89,7 +89,7 @@ def rpt_compare(args): Analyze test package test results by comparing with GnuR output. Return 0 if passed, non-zero if failed ''' - parser = ArgumentParser(prog='mx rpt_compare') + parser = ArgumentParser(prog='mx rpt-compare') parser.add_argument('--fastr-dir', action='store', help='dir containing fastr results', default=os.getcwd()) parser.add_argument('--pkg', action='store', help='pkg to compare, default all') parser.add_argument('--verbose', action='store_true', help='print names of files that differ') @@ -154,11 +154,14 @@ def check_install(result, text): result_data = "" def find_done(index, pkgname): + exception = False for i in range(index, nlines): line = lines[i] + if 'exception' in line: + exception = True if line.startswith("* DONE"): done_pkgname = line[line.find("(") + 1 : line.rfind(")")] - return pkgname == done_pkgname + return pkgname == done_pkgname and not exception return False start_index = None @@ -166,8 +169,9 @@ def check_install(result, text): line = lines[i] if line.startswith("BEGIN package installation"): start_index = i + break - if start_index: + if start_index is not None: for i in range(start_index, nlines): line = lines[i] if line.startswith("* installing *source* package"): @@ -181,6 +185,17 @@ def check_install(result, text): return result, result_data +def rpt_check_install_log(args): + parser = ArgumentParser(prog='mx rpt-check-install-log') + parser.add_argument('--log', action='store', help='file containing install log', required=True) + args = parser.parse_args(args) + + with open(args.log) as f: + content = f.read() + _, result_data = check_install(0, content) + + print result_data + def _extract_pkgname(line): sx = line.find("'") ex = line.rfind("'") @@ -546,5 +561,6 @@ _commands = { 'rpt-install-status' : [rpt_install_status, '[options]'], 'rpt-list-testdirs' : [rpt_list_testdirs, '[options]'], 'rpt-compare': [rpt_compare, '[options]'], + 'rpt-check-install-log': [rpt_check_install_log, '[options]'], 'pkgtestanalyze': [rpt_compare, '[options]'], } -- GitLab