diff --git a/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFIVariablesCodeGen.java b/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFIVariablesCodeGen.java new file mode 100644 index 0000000000000000000000000000000000000000..58e4f7c87abb5043dbf34512b9ddcbcf9f1d58c9 --- /dev/null +++ b/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFIVariablesCodeGen.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, 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.codegen; + +import java.util.Arrays; +import java.util.stream.Stream; + +import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.ffi.RFFIVariables; + +public class FFIVariablesCodeGen { + /** + * Generates C code necessary to glue the Java and C part together. To run this, run + * {@code mx -v r} to get full command line that runs R and replace the main class with this + * class and add {@code mxbuild/com.oracle.truffle.r.ffi.codegen/bin} to the classpath. + */ + public static void main(String[] args) { + System.out.println("// Update com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h with the following: \n"); + System.out.println("// Generated by RFFIVariables.java:\n"); + for (RFFIVariables var : RFFIVariables.values()) { + System.out.printf("#define %s_x %d\n", var.name(), var.ordinal()); + } + System.out.printf("\n#define VARIABLES_TABLE_SIZE %d", RFFIVariables.values().length); + + System.out.println("\n\n// Update com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c with the following: \n"); + + System.out.println("// Generated by RFFIVariables.java:\n"); + + for (RFFIVariables val : RFFIVariables.values()) { + if (val == RFFIVariables.R_Interactive) { + System.out.printf("Rboolean %s;\n", val.name()); + } else if (val.getValue() instanceof Double) { + System.out.printf("double %s;\n", val.name()); + } else if (val.getValue() instanceof Integer) { + System.out.printf("int %s;\n", val.name()); + } else if (val.getValue() instanceof String) { + System.out.printf("char* %s;\n", val.name()); + } else if (val.getValue() instanceof RSymbol) { + System.out.printf("SEXP %s; /* \"%s\" */\n", val.name(), ((RSymbol) val.getValue()).getName()); + } else { + System.out.printf("SEXP %s;\n", val.name()); + } + } + + System.out.println("\nvoid Call_initvar_double(int index, double value) {"); + printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.getValue() instanceof Double), "Call_initvar_double"); + System.out.println("}\n"); + + System.out.println("void Call_initvar_int(int index, int value) {"); + printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.getValue() instanceof Integer), "Call_initvar_int"); + System.out.println("}\n"); + + System.out.println("void Call_initvar_string(int index, char* value) {"); + printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.getValue() instanceof String), "copystring(value)", "Call_initvar_string"); + System.out.println("}\n"); + + System.out.println("void Call_initvar_obj(TruffleEnv* env, int index, void* value) {"); + System.out.println(" init_utils(env);"); + printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> !(x.getValue() instanceof Number || x.getValue() instanceof String)), "Call_initvar_obj"); + System.out.println("}\n"); + } + + private static void printInitVarFor(Stream<RFFIVariables> vars, String callName) { + printInitVarFor(vars, "value", callName); + } + + private static void printInitVarFor(Stream<RFFIVariables> vars, String value, String callName) { + System.out.println(" switch (index) {"); + vars.forEachOrdered(x -> System.out.printf(" case %s_x: %s = %s; break;\n", x.name(), x.name(), value)); + System.out.println(" default:"); + System.out.printf(" printf(\"%s: unimplemented index %%d\\n\", index);\n", callName); + System.out.println(" exit(1);"); + System.out.println(" }"); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java index eb9fef097ac5f72a0c442294da71b7ee4945a69d..eb89f3e5a8366ff7c30de822c6b31066705c8f31 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -128,68 +128,4 @@ public enum RFFIVariables { R_Interactive.value = context.isInteractive() ? 1 : 0; return values(); } - - /** - * Generates C code necessary to glue the Java and C part together. To run this, run - * {@code mx -v r} to get full command line that runs R and replace the main class with this - * class. - */ - public static void main(String[] args) { - System.out.println("// Update com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h with the following: \n"); - System.out.println("// Generated by RFFIVariables.java:\n"); - for (RFFIVariables var : RFFIVariables.values()) { - System.out.printf("#define %s_x %d\n", var.name(), var.ordinal()); - } - System.out.printf("\n#define VARIABLES_TABLE_SIZE %d", values().length); - - System.out.println("\n\n// Update com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c with the following: \n"); - - System.out.println("// Generated by RFFIVariables.java:\n"); - - for (RFFIVariables val : values()) { - if (val == RFFIVariables.R_Interactive) { - System.out.printf("Rboolean %s;\n", val.name()); - } else if (val.value instanceof Double) { - System.out.printf("double %s;\n", val.name()); - } else if (val.value instanceof Integer) { - System.out.printf("int %s;\n", val.name()); - } else if (val.value instanceof String) { - System.out.printf("char* %s;\n", val.name()); - } else if (val.value instanceof RSymbol) { - System.out.printf("SEXP %s; /* \"%s\" */\n", val.name(), ((RSymbol) val.value).getName()); - } else { - System.out.printf("SEXP %s;\n", val.name()); - } - } - - System.out.println("\nvoid Call_initvar_double(int index, double value) {"); - printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.value instanceof Double), "Call_initvar_double"); - System.out.println("}\n"); - - System.out.println("void Call_initvar_int(int index, int value) {"); - printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.value instanceof Integer), "Call_initvar_int"); - System.out.println("}\n"); - - System.out.println("void Call_initvar_string(int index, char* value) {"); - printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> x.value instanceof String), "copystring(value)", "Call_initvar_string"); - System.out.println("}\n"); - - System.out.println("void Call_initvar_obj(TruffleEnv* env, int index, void* value) {"); - System.out.println(" init_utils(env);"); - printInitVarFor(Arrays.stream(RFFIVariables.values()).filter(x -> !(x.value instanceof Number || x.value instanceof String)), "Call_initvar_obj"); - System.out.println("}\n"); - } - - private static void printInitVarFor(Stream<RFFIVariables> vars, String callName) { - printInitVarFor(vars, "value", callName); - } - - private static void printInitVarFor(Stream<RFFIVariables> vars, String value, String callName) { - System.out.println(" switch (index) {"); - vars.forEachOrdered(x -> System.out.printf(" case %s_x: %s = %s; break;\n", x.name(), x.name(), value)); - System.out.println(" default:"); - System.out.printf(" printf(\"%s: unimplemented index %%d\\n\", index);\n", callName); - System.out.println(" exit(1);"); - System.out.println(" }"); - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java index e35b820fb1aa50de4d89c780e7359e2cc5c8b264..397a154a1f9b7e98db70e1f797a69935d30ce320 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java @@ -69,6 +69,7 @@ public final class NativeCharArray extends NativeUInt8Array { return new String(mbuf, 0, i); } + @TruffleBoundary public String getString() { byte[] val = getValue(); return new String(val, 0, fakesNullTermination() ? val.length : val.length - 1); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java index f52dd8e2e15a2b90da13f3c84f66b2de3814e5e4..3d35ca0ee8650143016277d5e9bff515dbb13ad9 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi.interop; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; @@ -78,6 +79,7 @@ public class NativeCharArrayMR { @Resolve(message = "EXECUTE") public abstract static class NCAToStringNode extends Node { + @TruffleBoundary protected java.lang.Object access(NativeCharArray receiver, @SuppressWarnings("unused") Object[] arguments) { return new String(receiver.getValue()); } diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index 98eaf5ef5091a138231ce979a969793f130770c6..c8030673c77775a83b320ea3a8f62fa274307e95 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -257,6 +257,16 @@ suite = { "jacoco" : "include", }, + "com.oracle.truffle.r.ffi.codegen" : { + "sourceDirs" : ["src"], + "checkstyle" : "com.oracle.truffle.r.runtime", + "dependencies" : [ + "com.oracle.truffle.r.runtime" + ], + "javaCompliance" : "1.8", + "workingSets" : "FastR", + }, + "com.oracle.truffle.r.ffi.processor" : { "sourceDirs" : ["src"], "checkstyle" : "com.oracle.truffle.r.runtime",