From d96a0108555a52e6278bff5077c71b5afd742203 Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Tue, 21 Nov 2017 09:54:23 +0100 Subject: [PATCH] Implemented native function 'octsize'. --- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 5 ++ .../truffle/r/ffi/impl/nodes/MiscNodes.java | 67 +++++++++++++++++++ .../r/ffi/impl/upcalls/StdUpCallsRFFI.java | 4 ++ .../fficall/src/common/rffi_upcalls.h | 1 + .../fficall/src/common/rffi_upcallsindex.h | 13 ++-- .../fficall/src/truffle_common/Utils.c | 7 ++ 6 files changed, 91 insertions(+), 6 deletions(-) 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 f8776dbb21..d5efff6efc 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 @@ -1764,4 +1764,9 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { throw implementedAsNode(); } + @Override + public Object octsize(Object size) { + throw implementedAsNode(); + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java index 9fed0338aa..a4cb9c71e7 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java @@ -22,13 +22,17 @@ */ package com.oracle.truffle.r.ffi.impl.nodes; +import java.nio.charset.Charset; + import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.GetFunctionEnvironmentNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.LENGTHNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.OctSizeNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoNewObjectNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotAssignNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotNodeGen; @@ -43,14 +47,22 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.S import com.oracle.truffle.r.nodes.builtin.EnvironmentNodes.GetFunctionEnvironmentNode; import com.oracle.truffle.r.nodes.objects.NewObject; import com.oracle.truffle.r.nodes.objects.NewObjectNodeGen; +import com.oracle.truffle.r.nodes.unary.CastDoubleBaseNode; +import com.oracle.truffle.r.nodes.unary.CastDoubleBaseNodeGen; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; +import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.nodes.GetDataAt; +import com.oracle.truffle.r.runtime.data.nodes.SetDataAt; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; @@ -252,4 +264,59 @@ public final class MiscNodes { } } + @TypeSystemReference(RTypes.class) + public abstract static class OctSizeNode extends FFIUpCallNode.Arg1 { + + private Charset asciiCharset; + + protected CastDoubleBaseNode createCast() { + return CastDoubleBaseNodeGen.create(false, false, false); + } + + @Specialization(guards = "size.getLength() == 1") + protected RRawVector octSize(RAbstractIntVector size, + @Cached("create()") GetDataAt.Int getDataNode) { + + int s = getDataNode.execute(size, size.getInternalStore(), 0); + byte[] buf = toOctalAsciiString(s); + return RDataFactory.createRawVector(buf); + } + + @TruffleBoundary + private byte[] toOctalAsciiString(int s) { + if (asciiCharset == null) { + asciiCharset = Charset.forName("US-ASCII"); + } + return asciiCharset.encode(Integer.toOctalString(s)).array(); + } + + // Transcribed from ".../utils/src/stubs.c" + @Specialization + protected RRawVector octSize(Object size, + @Cached("create()") SetDataAt.Raw setDataNode, + @Cached("createCast()") CastDoubleBaseNode castToDoubleNode) { + + double s = (double) castToDoubleNode.executeDouble(size); + + if (!RRuntime.isFinite(s) && s >= 0) { + throw RError.error(RError.SHOW_CALLER, RError.Message.GENERIC, "size must be finite and >= 0"); + } + + RRawVector ans = RDataFactory.createRawVector(11); + byte[] store = ans.getInternalStore(); + + for (int i = 0; i < 11; i++) { + double s2 = Math.floor(s / 8.0); + double t = s - 8.0 * s2; + s = s2; + setDataNode.setDataAtAsObject(ans, store, 10 - i, (byte) 48 + t); + } + return ans; + } + + public static OctSizeNode create() { + return OctSizeNodeGen.create(); + } + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index 70dbd8d13a..f8a81aab1f 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -400,4 +400,8 @@ public interface StdUpCallsRFFI { @RFFIUpCallNode(MiscNodes.GetFunctionEnvironment.class) Object CLOENV(Object x); + + @RFFIUpCallNode(MiscNodes.OctSizeNode.class) + Object octsize(Object size); + } 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 dca71097ea..f7f80924ca 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 @@ -281,6 +281,7 @@ typedef SEXP (*call_getvar)(); typedef SEXP (*call_R_ParseVector)(SEXP text, int n, SEXP srcFile); typedef SEXPTYPE (*call_Rf_str2type)(const char *s); typedef SEXP (*call_CLOENV)(SEXP closure); +typedef SEXP (*call_octsize)(SEXP size); // connections diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h index faf4a45a09..8008fede3e 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h @@ -170,12 +170,13 @@ #define getOpenModeString_x 165 #define getSummaryDescription_x 166 #define isSeekable_x 167 -#define registerCCallable_x 168 -#define registerRoutines_x 169 -#define setDotSymbolValues_x 170 -#define unif_rand_x 171 -#define useDynamicSymbols_x 172 +#define octsize_x 168 +#define registerCCallable_x 169 +#define registerRoutines_x 170 +#define setDotSymbolValues_x 171 +#define unif_rand_x 172 +#define useDynamicSymbols_x 173 -#define UPCALLS_TABLE_SIZE 173 +#define UPCALLS_TABLE_SIZE 174 #endif // RFFI_UPCALLSINDEX_H diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Utils.c b/com.oracle.truffle.r.native/fficall/src/truffle_common/Utils.c index 7b3a17dfc2..b5fec41f52 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Utils.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Utils.c @@ -22,6 +22,7 @@ */ #include <rffiutils.h> +#include "rffi_upcalls.h" void R_CheckStack(void) { // TODO: check for stack overflow @@ -48,3 +49,9 @@ Rboolean isOrdered(SEXP s) && inherits(s, "factor") && inherits(s, "ordered")); } + + +SEXP octsize(SEXP s) +{ + return ((call_octsize) callbacks[octsize_x])(s); +} -- GitLab