From be441ef4860fd52b1c0f0bd826ccf5b915246cca Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Fri, 29 Sep 2017 12:01:29 +0200 Subject: [PATCH] Hiding active binding for '.Random.seed'. --- .../com/oracle/truffle/r/engine/REngine.java | 2 +- .../truffle/r/nodes/builtin/base/Exists.java | 4 +-- .../r/nodes/builtin/base/RNGFunctions.java | 4 ++- .../r/runtime/env/frame/ActiveBinding.java | 29 +++++++++++++++++-- .../env/frame/REnvTruffleFrameAccess.java | 9 ++++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 4c03ebeafe..f9d21ecd3a 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -211,7 +211,7 @@ final class REngine implements Engine, Engine.Timings { private void initializeRNG() { assert REnvironment.globalEnv() != null; RFunction fun = context.lookupBuiltin(".fastr.set.seed"); - ActiveBinding dotRandomSeed = new ActiveBinding(RType.Any, fun); + ActiveBinding dotRandomSeed = new ActiveBinding(RType.Any, fun, true); Frame frame = REnvironment.globalEnv().getFrame(); FrameSlot slot = FrameSlotChangeMonitor.findOrAddFrameSlot(frame.getFrameDescriptor(), RRNG.RANDOM_SEED, FrameSlotKind.Object); FrameSlotChangeMonitor.setActiveBinding(frame, slot, dotRandomSeed, false, null); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Exists.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Exists.java index dff9b6e0bb..a9587d4adb 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Exists.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Exists.java @@ -69,14 +69,14 @@ public abstract class Exists extends RBuiltinNode.Arg4 { if (modeType != RType.Any && obj instanceof RPromise) { obj = PromiseHelperNode.evaluateSlowPath((RPromise) obj); } - return RRuntime.asLogical(obj != null && obj != RMissing.instance && RRuntime.checkType(obj, modeType)); + return RRuntime.asLogical(obj != null && RRuntime.checkType(obj, modeType)); } for (REnvironment e = env; e != REnvironment.emptyEnv(); e = e.getParent()) { Object obj = e.get(name); if (modeType != RType.Any && obj instanceof RPromise) { obj = PromiseHelperNode.evaluateSlowPath((RPromise) obj); } - if (obj != null && obj != RMissing.instance && RRuntime.checkType(obj, modeType)) { + if (obj != null && RRuntime.checkType(obj, modeType)) { return RRuntime.LOGICAL_TRUE; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java index b1d788fb5c..3696abf51c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java @@ -151,7 +151,9 @@ public class RNGFunctions { int[] seedsArr = (int[]) seeds; return RDataFactory.createIntVector(seedsArr, RDataFactory.INCOMPLETE_VECTOR); } - assert seeds != null; + if (seeds == null) { + return RNull.instance; + } return seeds; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/ActiveBinding.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/ActiveBinding.java index 2fda68c093..2e3c443069 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/ActiveBinding.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/ActiveBinding.java @@ -39,10 +39,17 @@ public class ActiveBinding implements RTruffleObject { private final RType expectedType; private final RFunction function; + private boolean initialized = false; + private boolean hidden = false; - public ActiveBinding(RType expectedType, RFunction fun) { + public ActiveBinding(RType expectedType, RFunction fun, boolean hidden) { this.expectedType = Objects.requireNonNull(expectedType); this.function = Objects.requireNonNull(fun); + this.hidden = hidden; + } + + public ActiveBinding(RType expectedType, RFunction fun) { + this(expectedType, fun, false); } public RFunction getFunction() { @@ -62,11 +69,29 @@ public class ActiveBinding implements RTruffleObject { return "active binding"; } + public boolean isHidden() { + return hidden; + } + + public boolean isInitialized() { + return initialized; + } + public Object writeValue(Object value) { - return RContext.getEngine().evalFunction(function, REnvironment.baseEnv().getFrame(), RCaller.createInvalid(null), true, null, value); + Object result = RContext.getEngine().evalFunction(function, REnvironment.baseEnv().getFrame(), RCaller.createInvalid(null), true, null, value); + initialized = true; + return result; } public Object readValue() { return RContext.getEngine().evalFunction(function, REnvironment.baseEnv().getFrame(), RCaller.createInvalid(null), true, null); } + + public static boolean isListed(Object value) { + if (isActiveBinding(value)) { + ActiveBinding binding = (ActiveBinding) value; + return !binding.hidden || binding.initialized; + } + return true; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java index d6d1b687c9..5e0167b6bb 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java @@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.REnvironment.PutException; @@ -75,7 +76,10 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess { Object value = FrameSlotChangeMonitor.getValue(slot, frame); // special treatment for active binding: call bound function if (ActiveBinding.isActiveBinding(value)) { - return ((ActiveBinding) value).readValue(); + Object readValue = ((ActiveBinding) value).readValue(); + // special case: if the active binding returns RMissing, then this should behave + // like the variable does not exist. + return readValue != RMissing.instance ? readValue : null; } return value; } @@ -161,7 +165,8 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess { for (int i = 0; i < names.length; i++) { String name = names[i]; FrameSlot frameSlot = fd.findFrameSlot(name); - if (FrameSlotChangeMonitor.getValue(frameSlot, frame) == null) { + Object value = FrameSlotChangeMonitor.getValue(frameSlot, frame); + if (value == null || !ActiveBinding.isListed(value)) { continue; } if (REnvironment.includeName(name, allNames, pattern)) { -- GitLab