From 38e048784ce084170798f8cbb118ed085cc09fcc Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 13 Oct 2017 16:11:14 +0200 Subject: [PATCH] More robust approach to handling the .Devices variable --- .../graphics/RGridGraphicsAdapter.java | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java index 709b772191..9c2cce59df 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java @@ -66,7 +66,7 @@ public final class RGridGraphicsAdapter { } public static void initialize() { - addDevice(NULL_DEVICE); + REnvironment.baseEnv().safePut(DOT_DEVICES, RDataFactory.createPairList(NULL_DEVICE)); setCurrentDevice(NULL_DEVICE); RContext ctx = RContext.getInstance(); ROptions.ContextStateImpl options = ctx.stateROptions; @@ -82,25 +82,41 @@ public final class RGridGraphicsAdapter { } /** - * Fixup .Devices array as someone may have set it to something that is not a (pair) list nor - * RNull, which breaks dev.cur built-in R function and others. + * Fixup .Devices global variable to be a pair list of length at least 1. Non-empty lists are + * converted to pair lists, anything else causes the variable to be reset back to the initial + * value. */ @TruffleBoundary - public static void fixupDevicesVariable() { - Object devices = REnvironment.baseEnv().get(DOT_DEVICES); - if (!(devices instanceof RPairList || devices instanceof RList)) { - // reset the .Devices and .Device variables to initial values - REnvironment.baseEnv().safePut(DOT_DEVICES, RNull.instance); - addDevice(NULL_DEVICE); - setCurrentDevice(NULL_DEVICE); + public static RPairList fixupDevicesVariable() { + REnvironment baseEnv = REnvironment.baseEnv(); + Object devices = baseEnv.get(DOT_DEVICES); + if (devices instanceof RPairList) { + return (RPairList) devices; + } + if (devices instanceof RList) { + RList list = (RList) devices; + if (list.getLength() > 0) { + RPairList head = RDataFactory.createPairList(list.getDataAt(0)); + RPairList curr = head; + for (int i = 1; i < list.getLength(); i++) { + RPairList next = RDataFactory.createPairList(list.getDataAt(i)); + curr.setCdr(next); + curr = next; + } + baseEnv.safePut(DOT_DEVICES, head); + return head; + } } + // reset the .Devices and .Device variables to initial values + RPairList nullDevice = RDataFactory.createPairList(NULL_DEVICE); + baseEnv.safePut(DOT_DEVICES, nullDevice); + setCurrentDevice(NULL_DEVICE); + return nullDevice; } public static void removeDevice(int index) { assert index > 0 : "cannot remove null device"; - REnvironment baseEnv = REnvironment.baseEnv(); - fixupDevicesVariable(); - RPairList devices = (RPairList) baseEnv.get(DOT_DEVICES); + RPairList devices = fixupDevicesVariable(); assert index < devices.getLength() : "wrong index in removeDevice"; RPairList prev = devices; for (int i = 0; i < index - 1; ++i) { @@ -120,12 +136,8 @@ public final class RGridGraphicsAdapter { public static void addDevice(String name) { REnvironment baseEnv = REnvironment.baseEnv(); baseEnv.safePut(DOT_DEVICE, name); - Object dotDevices = baseEnv.get(DOT_DEVICES); - if (dotDevices instanceof RPairList) { - ((RPairList) dotDevices).appendToEnd(RDataFactory.createPairList(name)); - } else { - baseEnv.safePut(DOT_DEVICES, RDataFactory.createPairList(name)); - } + RPairList dotDevices = fixupDevicesVariable(); + dotDevices.appendToEnd(RDataFactory.createPairList(name)); } public static String getDefaultDevice() { -- GitLab