From 8f6da8c87d98aaf6df05364572906e07344cbe3b Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Wed, 23 Aug 2017 16:16:20 +0200 Subject: [PATCH] unbox foreign objects when they enter the R value space --- .../casts/fluent/PreinitialPhaseBuilder.java | 3 -- .../truffle/r/runtime/interop/Foreign2R.java | 43 ++++++++++++++++++- .../r/runtime/interop/ForeignArray2R.java | 3 -- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java index b54e004571..8a29918d64 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/fluent/PreinitialPhaseBuilder.java @@ -99,9 +99,6 @@ public final class PreinitialPhaseBuilder extends InitialPhaseBuilder<Object> { /** * Determines whether foreign arrays are implicitly casted to a R vector/list or not. <br> * The default setting is <code>true</code>. - * - * @param flag - * @return */ public PreinitialPhaseBuilder castForeignObjects(boolean flag) { pipelineBuilder().getPipelineConfig().setCastForeignObjects(flag); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java index 23b3b20dfb..5642fa86b7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java @@ -22,17 +22,27 @@ */ package com.oracle.truffle.r.runtime.interop; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.nodes.RBaseNode; -@ImportStatic(Message.class) +@ImportStatic({RRuntime.class}) public abstract class Foreign2R extends RBaseNode { + @Child private Foreign2R recursive; + @Child private Node isBoxed; + @Child private Node unbox; + public static Foreign2R createForeign2R() { return Foreign2RNodeGen.create(); } @@ -74,6 +84,37 @@ public abstract class Foreign2R extends RBaseNode { return RNull.instance; } + @Specialization(guards = "isForeignObject(obj)") + public Object doUnbox(TruffleObject obj) { + /* + * For the time being, we have to ask "IS_BOXED" all the time (instead of simply trying + * UNBOX first), because some TruffleObjects return bogus values from UNBOX when IS_BOXED is + * false. + */ + if (isBoxed == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + isBoxed = insert(Message.IS_BOXED.createNode()); + } + if (ForeignAccess.sendIsBoxed(isBoxed, obj)) { + if (unbox == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + unbox = insert(Message.UNBOX.createNode()); + } + try { + Object unboxed = ForeignAccess.sendUnbox(unbox, obj); + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(Foreign2RNodeGen.create()); + } + return recursive.execute(unboxed); + } catch (UnsupportedMessageException e) { + CompilerDirectives.transferToInterpreter(); + throw RInternalError.shouldNotReachHere(e, "object does not support UNBOX message even though IS_BOXED == true: " + obj.getClass().getSimpleName()); + } + } + return obj; + } + @Fallback public Object doObject(Object obj) { return obj; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java index 9a75f0c138..ebf2d49122 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java @@ -192,9 +192,6 @@ public abstract class ForeignArray2R extends RBaseNode { /** * Converts the elements collected from a foreign array or java iterable into a vector or list. - * - * @param ce - * @return */ public static RAbstractVector asAbstractVector(CollectedElements ce) { InteropTypeCheck.RType type = ce.typeCheck.getType(); -- GitLab