From 6d452ae3b5c8e12966da71bdd80c180fb152f4e8 Mon Sep 17 00:00:00 2001
From: Michael Haupt <michael.haupt@oracle.com>
Date: Tue, 23 Sep 2014 16:24:10 +0200
Subject: [PATCH] adopt node abstraction for RMissingHelper.getMissingValue()
 and apply it in missing builtin

---
 .../truffle/r/nodes/builtin/base/Missing.java |  9 ++-
 .../r/nodes/function/GetMissingValueNode.java | 80 +++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetMissingValueNode.java

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
index 2f4c7d542d..a00d5102dd 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Missing.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.builtin.base;
 
 import static com.oracle.truffle.r.runtime.RBuiltinKind.*;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
@@ -39,6 +40,8 @@ public abstract class Missing extends RBuiltinNode {
 
     private final PromiseProfile promiseProfile = new PromiseProfile();
 
+    @Child private GetMissingValueNode getMissingValue;
+
     @Specialization
     protected byte missing(VirtualFrame frame, RPromise promise) {
         controlVisibility();
@@ -50,7 +53,11 @@ public abstract class Missing extends RBuiltinNode {
         }
 
         // Read symbols value directly
-        Object obj = RMissingHelper.getMissingValue(frame, symbol);
+        if (getMissingValue == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            getMissingValue = insert(GetMissingValueNode.create(symbol));
+        }
+        Object obj = getMissingValue.execute(frame);
         if (obj == null) {
             // In case we are not able to read the symbol in current frame: This is not an argument
             // and thus return false
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetMissingValueNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetMissingValueNode.java
new file mode 100644
index 0000000000..c3601502e9
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GetMissingValueNode.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 2014, 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.nodes.function;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.access.*;
+
+/**
+ * This is a node abstraction for the functionality defined in
+ * {@link RMissingHelper#getMissingValue(Frame,Symbol)}.
+ */
+public abstract class GetMissingValueNode extends RNode {
+
+    public static GetMissingValueNode create(Symbol sym) {
+        return new UninitializedGetMissingValueNode(sym);
+    }
+
+    private static final class UninitializedGetMissingValueNode extends GetMissingValueNode {
+
+        final Symbol sym;
+
+        UninitializedGetMissingValueNode(Symbol sym) {
+            this.sym = sym;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(sym.getName());
+            GetMissingValueNode gmvn = new ResolvedGetMissingValueNode(slot);
+            return replace(gmvn).execute(frame);
+        }
+
+    }
+
+    private static final class ResolvedGetMissingValueNode extends GetMissingValueNode {
+
+        final FrameSlot slot;
+
+        ResolvedGetMissingValueNode(FrameSlot slot) {
+            this.slot = slot;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            if (slot == null) {
+                return null;
+            }
+            try {
+                return frame.getObject(slot);
+            } catch (FrameSlotTypeException e) {
+                return null;
+            }
+        }
+
+    }
+
+}
-- 
GitLab