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 967be7aeeff45a46ba52aeeec43e85ae574f509f..9c89ec3258afce7e357a46d969db49005a1e40c4 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
@@ -131,8 +131,6 @@ import sun.misc.Unsafe;
  */
 public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
 
-    private final Map<String, Object> nameSymbolCache = new ConcurrentHashMap<>();
-
     private static RuntimeException implementedAsNode() {
         // TODO: Exception handling over native boundaries is currently missing. Once this works,
         // remove the following two lines.
@@ -270,6 +268,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         while (env != REnvironment.emptyEnv()) {
             Object value = env.get(name.getName());
             if (value != null) {
+                if (value instanceof RPromise && ((RPromise) value).isOptimized()) {
+                    // From the point of view of RFFI, optimized promises (i.e. promises with null
+                    // env) should not show up
+                    return ((RPromise) value).getRawValue();
+                }
                 return value;
             }
             if (!inherits) {
@@ -350,12 +353,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     @Override
     @TruffleBoundary
     public Object Rf_install(String name) {
-        Object ret = nameSymbolCache.get(name);
-        if (ret == null) {
-            ret = RDataFactory.createSymbolInterned(name);
-            nameSymbolCache.put(name, ret);
-        }
-        return ret;
+        return RDataFactory.createSymbolInterned(name);
     }
 
     @Override
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
index 61fa874e2c41ff9556ba9ef288fc7eb4fd5b9d25..379adb56840d43fc6fecbed3ea96407bed54f423 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -26,20 +26,13 @@ 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.ListAccessNodesFactory.CAARNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CAD4RNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADDDRNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADDRNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CARNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDARNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDDDRNodeGen;
-import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.SETCARNodeGen;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
 import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode;
 import com.oracle.truffle.r.runtime.RInternalError;
+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.RLanguage;
@@ -75,7 +68,7 @@ public final class ListAccessNodes {
 
         @Specialization
         protected Object car(RSymbol sym) {
-            return sym;
+            return CharSXPWrapper.create(sym.getName());
         }
 
         @Specialization
@@ -98,57 +91,6 @@ public final class ListAccessNodes {
         }
     }
 
-    @TypeSystemReference(RTypes.class)
-    public abstract static class CAARNode extends FFIUpCallNode.Arg1 {
-
-        @Child private CARNode car1 = CARNode.create();
-        @Child private CARNode car2 = CARNode.create();
-
-        @Specialization
-        protected Object caar(Object value) {
-            return car2.executeObject(car1.executeObject(value));
-        }
-
-        public static CAARNode create() {
-            return CAARNodeGen.create();
-        }
-    }
-
-    @TypeSystemReference(RTypes.class)
-    public static final class SETCADRNode extends FFIUpCallNode.Arg2 {
-        @Child private SETCARNode setcarNode = SETCARNode.create();
-        @Child private CDRNode cdrNode = CDRNode.create();
-
-        @Override
-        public Object executeObject(Object x, Object y) {
-            return setcarNode.executeObject(cdrNode.executeObject(x), y);
-        }
-    }
-
-    @TypeSystemReference(RTypes.class)
-    public abstract static class SETCARNode extends FFIUpCallNode.Arg2 {
-        public static SETCARNode create() {
-            return SETCARNodeGen.create();
-        }
-
-        @Specialization
-        protected Object doRLang(RLanguage x, Object y) {
-            x.getPairList().setCar(y);
-            return y;
-        }
-
-        @Specialization
-        protected Object doRLang(RPairList x, Object y) {
-            x.setCar(y);
-            return y;
-        }
-
-        @Fallback
-        protected Object car(@SuppressWarnings("unused") Object x, @SuppressWarnings("unused") Object y) {
-            throw RInternalError.unimplemented("SETCAR only works on pair lists or language objects");
-        }
-    }
-
     @TypeSystemReference(RTypes.class)
     public abstract static class CDRNode extends FFIUpCallNode.Arg1 {
         @Specialization
@@ -183,6 +125,16 @@ public final class ListAccessNodes {
             return copy;
         }
 
+        @Specialization
+        protected RNull cdr(@SuppressWarnings("unused") RSymbol symbol) {
+            return RNull.instance;
+        }
+
+        @Specialization
+        protected RNull handleNull(@SuppressWarnings("unused") RNull rNull) {
+            return rNull;
+        }
+
         @Fallback
         protected Object cdr(@SuppressWarnings("unused") Object obj) {
             throw RInternalError.unimplemented("CDR only works on pair lists, language objects, and argument lists");
@@ -194,153 +146,161 @@ public final class ListAccessNodes {
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CADRNode extends FFIUpCallNode.Arg1 {
+    public static final class CAARNode extends FFIUpCallNode.Arg1 {
+
+        @Child private CARNode car1 = CARNode.create();
+        @Child private CARNode car2 = CARNode.create();
+
+        @Override
+        public Object executeObject(Object x) {
+            return car2.executeObject(car1.executeObject(x));
+        }
+
+        public static CAARNode create() {
+            return new CAARNode();
+        }
+    }
+
+    @TypeSystemReference(RTypes.class)
+    public static final class SETCADRNode extends FFIUpCallNode.Arg2 {
+        @Child private SETCARNode setcarNode = SETCARNode.create();
+        @Child private CDRNode cdrNode = CDRNode.create();
+
+        @Override
+        public Object executeObject(Object x, Object y) {
+            return setcarNode.executeObject(cdrNode.executeObject(x), y);
+        }
+    }
+
+    @TypeSystemReference(RTypes.class)
+    public abstract static class SETCARNode extends FFIUpCallNode.Arg2 {
+        public static SETCARNode create() {
+            return SETCARNodeGen.create();
+        }
+
         @Specialization
-        protected Object cadr(RPairList pl) {
-            return pl.cadr();
+        protected Object doRLang(RLanguage x, Object y) {
+            x.getPairList().setCar(y);
+            return y;
         }
 
         @Specialization
-        protected Object cadr(RLanguage lang) {
-            return lang.getDataAtAsObject(1);
+        protected Object doRPairList(RPairList x, Object y) {
+            x.setCar(y);
+            return y;
         }
 
         @Fallback
-        protected Object cadr(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CADR only works on pair lists and language objects");
+        protected Object car(@SuppressWarnings("unused") Object x, @SuppressWarnings("unused") Object y) {
+            throw RInternalError.unimplemented("SETCAR only works on pair lists or language objects");
+        }
+    }
+
+    @TypeSystemReference(RTypes.class)
+    public static final class CADRNode extends FFIUpCallNode.Arg1 {
+        @Child private CDRNode cdr = CDRNode.create();
+        @Child private CARNode car = CARNode.create();
+
+        @Override
+        public Object executeObject(Object x) {
+            return car.executeObject(cdr.executeObject(x));
         }
 
         public static CADRNode create() {
-            return CADRNodeGen.create();
+            return new CADRNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CDARNode extends FFIUpCallNode.Arg1 {
+    public static final class CDARNode extends FFIUpCallNode.Arg1 {
         @Child private CARNode car = CARNode.create();
         @Child private CDRNode cdr = CDRNode.create();
 
-        @Specialization
-        protected Object cdar(Object value) {
-            return cdr.executeObject(car.executeObject(value));
+        @Override
+        public Object executeObject(Object x) {
+            return cdr.executeObject(car.executeObject(x));
         }
 
         public static CDARNode create() {
-            return CDARNodeGen.create();
+            return new CDARNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CADDRNode extends FFIUpCallNode.Arg1 {
-        @Specialization
-        protected Object caddr(RPairList pl) {
-            return pl.caddr();
-        }
-
-        @Specialization
-        protected Object caddr(RLanguage lang) {
-            return lang.getDataAtAsObject(2);
-        }
+    public static final class CADDRNode extends FFIUpCallNode.Arg1 {
+        @Child private CARNode car = CARNode.create();
+        @Child private CDRNode cdr1 = CDRNode.create();
+        @Child private CDRNode cdr2 = CDRNode.create();
 
-        @Fallback
-        protected Object caddr(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CADDR only works on pair lists and language objects");
+        @Override
+        public Object executeObject(Object x) {
+            return car.executeObject(cdr1.executeObject(cdr2.executeObject(x)));
         }
 
         public static CADDRNode create() {
-            return CADDRNodeGen.create();
+            return new CADDRNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CADDDRNode extends FFIUpCallNode.Arg1 {
-        @Specialization
-        protected Object cadddr(RPairList pl) {
-            RPairList tmp = (RPairList) pl.cddr();
-            return tmp.cadr();
-        }
-
-        @Specialization
-        protected Object cadddr(RLanguage lang) {
-            return lang.getDataAtAsObject(3);
-        }
+    public static final class CADDDRNode extends FFIUpCallNode.Arg1 {
+        @Child private CARNode car = CARNode.create();
+        @Child private CDRNode cdr1 = CDRNode.create();
+        @Child private CDRNode cdr2 = CDRNode.create();
+        @Child private CDRNode cdr3 = CDRNode.create();
 
-        @Fallback
-        protected Object cadddr(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CADDDR only works on pair lists and language objects");
+        @Override
+        public Object executeObject(Object x) {
+            return car.executeObject(cdr1.executeObject(cdr2.executeObject(cdr3.executeObject(x))));
         }
 
         public static CADDDRNode create() {
-            return CADDDRNodeGen.create();
+            return new CADDDRNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CAD4RNode extends FFIUpCallNode.Arg1 {
-        @Specialization
-        protected Object cad4r(RPairList pl) {
-            RPairList tmp = (RPairList) pl.cddr();
-            return tmp.caddr();
-        }
-
-        @Specialization
-        protected Object cad4r(RLanguage lang) {
-            return lang.getDataAtAsObject(4);
-        }
+    public static final class CAD4RNode extends FFIUpCallNode.Arg1 {
+        @Child private CADDDRNode cadddr = CADDDRNode.create();
+        @Child private CDRNode cdr = CDRNode.create();
 
-        @Fallback
-        protected Object cad4r(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CAD4R only works on pair lists and language objects");
+        @Override
+        public Object executeObject(Object x) {
+            return cadddr.executeObject(cdr.executeObject(x));
         }
 
         public static CAD4RNode create() {
-            return CAD4RNodeGen.create();
+            return new CAD4RNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CDDRNode extends FFIUpCallNode.Arg1 {
-        @Specialization
-        protected Object cddr(RPairList pl) {
-            return pl.cddr();
-        }
+    public static final class CDDRNode extends FFIUpCallNode.Arg1 {
+        @Child private CDRNode cdr1 = CDRNode.create();
+        @Child private CDRNode cdr2 = CDRNode.create();
 
-        @Specialization
-        protected Object cddr(RLanguage lang) {
-            RPairList l = lang.getPairList();
-            return l.cddr();
-        }
-
-        @Fallback
-        protected Object cddr(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CDDR only works on pair lists and language objects");
+        @Override
+        public Object executeObject(Object x) {
+            return cdr1.executeObject(cdr2.executeObject(x));
         }
 
         public static CDDRNode create() {
-            return CDDRNodeGen.create();
+            return new CDDRNode();
         }
     }
 
     @TypeSystemReference(RTypes.class)
-    public abstract static class CDDDRNode extends FFIUpCallNode.Arg1 {
-        @Specialization
-        protected Object cdddr(RPairList pl) {
-            return pl.cddr();
-        }
-
-        @Specialization
-        protected Object cdddr(RLanguage lang) {
-            RPairList l = (RPairList) lang.getPairList().cddr();
-            return l.cdr();
-        }
+    public static final class CDDDRNode extends FFIUpCallNode.Arg1 {
+        @Child CDDRNode cddr = CDDRNode.create();
+        @Child CDRNode cdr = CDRNode.create();
 
-        @Fallback
-        protected Object cdddr(@SuppressWarnings("unused") Object obj) {
-            throw RInternalError.unimplemented("CDDDR only works on pair lists and language objects");
+        @Override
+        public Object executeObject(Object x) {
+            return cdr.executeObject(cddr.executeObject(x));
         }
 
         public static CDDDRNode create() {
-            return CDDDRNodeGen.create();
+            return new CDDDRNode();
         }
     }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
index 769b288779887581dabdaab4d381bac80220b5c9..3f1214d0f8bcab8f3a7a9eb3e3811f2ac26270e6 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -27,6 +27,7 @@ import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
@@ -79,10 +80,24 @@ public class DatePOSIXFunctions {
         public final int[] yday;
         public final int[] isdst;
         private boolean complete = true;
-        private final String zone;
-
-        POSIXltBuilder(int length, String zone) {
-            this.zone = zone;
+        private final RAbstractStringVector zone;
+
+        private final TimeZone realZone;
+
+        POSIXltBuilder(int length, String explicitZone) {
+            String[] zones = new String[3];
+            zones[0] = explicitZone;
+            realZone = explicitZone.isEmpty() ? RContext.getInstance().stateREnvVars.getSystemTimeZone() : TimeZone.getTimeZone(explicitZone);
+            // getTimeZone returns the default if the ID does not exist, by comparing the return's
+            // value ID to the explicit one we can find out the if the zone was found.
+            if (explicitZone.isEmpty() || realZone.getID().equals(explicitZone)) {
+                zones[1] = realZone.getDisplayName(false, TimeZone.SHORT);
+                zones[2] = realZone.useDaylightTime() ? realZone.getDisplayName(true, TimeZone.SHORT) : "";
+            } else {
+                zones[1] = explicitZone;
+                zones[2] = "";
+            }
+            this.zone = RDataFactory.createStringVector(zones, RDataFactory.COMPLETE_VECTOR);
             sec = new double[length];
             min = new int[length];
             hour = new int[length];
@@ -94,6 +109,10 @@ public class DatePOSIXFunctions {
             isdst = new int[length];
         }
 
+        public TimeZone getRealZone() {
+            return realZone;
+        }
+
         public void setEntry(int index, double newSec, int newMin, int newHour, int newMDay, int newMon, int newYear, int newWDay, int newYDay, int newIsDst) {
             sec[index] = newSec;
             min[index] = newMin;
@@ -151,14 +170,13 @@ public class DatePOSIXFunctions {
         @TruffleBoundary
         protected RList doDate2POSIXlt(RAbstractDoubleVector x) {
             int xLen = x.getLength();
-            TimeZone zone = TimeZone.getTimeZone("UTC");
             POSIXltBuilder builder = new POSIXltBuilder(xLen, "UTC");
             for (int i = 0; i < xLen; i++) {
                 double d = x.getDataAt(i);
                 if (RRuntime.isFinite(d)) {
                     int day = (int) Math.floor(d);
                     Instant instant = Instant.ofEpochSecond(day * 3600L * 24L);
-                    ZonedDateTime date = ZonedDateTime.ofInstant(instant, zone.toZoneId());
+                    ZonedDateTime date = ZonedDateTime.ofInstant(instant, builder.getRealZone().toZoneId());
                     builder.setEntry(i, 0, 0, 0, date.getDayOfMonth(), date.getMonthValue() - 1, date.getYear() - 1900, date.getDayOfWeek().ordinal(), date.getDayOfYear(), 0);
                 } else {
                     builder.setIncompleteEntry(i);
@@ -187,20 +205,16 @@ public class DatePOSIXFunctions {
         @Specialization
         @TruffleBoundary
         protected RList asPOSIXlt(RAbstractDoubleVector x, String tz) {
-            TimeZone zone;
-            if (tz.isEmpty()) {
-                zone = RContext.getInstance().stateREnvVars.getSystemTimeZone();
-            } else {
-                zone = TimeZone.getTimeZone(tz);
-            }
             int xLen = x.getLength();
-            POSIXltBuilder builder = new POSIXltBuilder(xLen, zone.getDisplayName(false, TimeZone.SHORT));
+            POSIXltBuilder builder = new POSIXltBuilder(xLen, tz);
             for (int i = 0; i < xLen; i++) {
                 double second = x.getDataAt(i);
                 if (RRuntime.isFinite(second)) {
                     Instant instant = Instant.ofEpochSecond((long) second);
-                    ZonedDateTime date = ZonedDateTime.ofInstant(instant, zone.toZoneId());
-                    builder.setEntry(i, date.getSecond(), date.getMinute(), date.getHour(), date.getDayOfMonth(), date.getMonthValue() - 1, date.getYear() - 1900, date.getDayOfWeek().ordinal(),
+                    double miliseconds = second - Math.floor(second);
+                    ZonedDateTime date = ZonedDateTime.ofInstant(instant, builder.getRealZone().toZoneId());
+                    builder.setEntry(i, date.getSecond() + miliseconds, date.getMinute(), date.getHour(), date.getDayOfMonth(), date.getMonthValue() - 1, date.getYear() - 1900,
+                                    date.getDayOfWeek().ordinal(),
                                     date.getDayOfYear(), 0);
                 } else {
                     builder.setIncompleteEntry(i);
@@ -403,15 +417,9 @@ public class DatePOSIXFunctions {
         @Specialization
         @TruffleBoundary
         protected RList strptime(RAbstractStringVector x, RAbstractStringVector format, RAbstractStringVector tz) {
-            TimeZone zone;
             String zoneString = RRuntime.asString(tz);
-            if (zoneString.isEmpty()) {
-                zone = RContext.getInstance().stateREnvVars.getSystemTimeZone();
-            } else {
-                zone = TimeZone.getTimeZone(zoneString);
-            }
             int length = x.getLength();
-            POSIXltBuilder builder = new POSIXltBuilder(length, zone.getDisplayName(false, TimeZone.SHORT));
+            POSIXltBuilder builder = new POSIXltBuilder(length, zoneString);
             DateTimeFormatterBuilder[] builders = createFormatters(format, true);
             DateTimeFormatter[] formatters = new DateTimeFormatter[builders.length];
             for (int i = 0; i < builders.length; i++) {
@@ -436,7 +444,8 @@ public class DatePOSIXFunctions {
                         LocalTime tm = LocalTime.from(parse);
                         time = LocalDateTime.of(LocalDate.now(), tm);
                     }
-                    builder.setEntry(i, time.getSecond(), time.getMinute(), time.getHour(), time.getDayOfMonth(), time.getMonthValue() - 1, time.getYear() - 1900, time.getDayOfWeek().ordinal(),
+                    double ms = (time.toInstant(ZoneOffset.UTC).toEpochMilli() % 1000) / 1000;
+                    builder.setEntry(i, time.getSecond() + ms, time.getMinute(), time.getHour(), time.getDayOfMonth(), time.getMonthValue() - 1, time.getYear() - 1900, time.getDayOfWeek().ordinal(),
                                     time.getDayOfYear(), 0);
                     continue;
                 } catch (DateTimeException e) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
index 1c929edaefe02a2a67214fabea519029792f1e77..3883d7ba9515f1b3213b6294cd5e5b8468ae1f18 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -35,6 +35,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
 import com.oracle.truffle.api.dsl.Cached;
@@ -609,12 +610,13 @@ public class EnvFunctions {
             casts.arg("env").mustBe(REnvironment.class, Message.NOT_AN_ENVIRONMENT);
         }
 
-        private BranchProfile frameSlotBranchProfile;
+        @CompilationFinal private BranchProfile frameSlotBranchProfile;
 
         @TruffleBoundary
         @Specialization
         protected Object makeActiveBinding(RSymbol sym, RFunction fun, REnvironment env) {
             if (frameSlotBranchProfile == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
                 frameSlotBranchProfile = BranchProfile.create();
             }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
index 589957931b9e004908c86a8c8e179fa72438065d..41a88e9b7e122875e265287329a7cf4e3245338a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -167,7 +167,7 @@ public class RRuntime {
 
     public static final String OP_NAMESPACE_SCOPE_EXPORTED = "::";
 
-    public static final RSymbol DEFERRED_DEFAULT_MARKER = new RSymbol("__Deferred_Default_Marker__");
+    public static final RSymbol DEFERRED_DEFAULT_MARKER = RSymbol.install("__Deferred_Default_Marker__");
 
     public static final String R_TARGET = "target";
     public static final String R_DOT_TARGET = ".target";
@@ -184,7 +184,7 @@ public class RRuntime {
     public static final String R_SRCFILE = "srcfile";
 
     public static final String NULL = "NULL";
-    public static final RSymbol PSEUDO_NULL = new RSymbol("\u0001NULL\u0001");
+    public static final RSymbol PSEUDO_NULL = RSymbol.install("\u0001NULL\u0001");
     public static final String UNBOUND = "UNBOUND";
 
     @CompilationFinal(dimensions = 1) private static final String[] rawStringCache = new String[256];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index 4d2214df1c02417d30f4c278add801cdc54dd65d..131261bdbcadb195a67839841f5e971ac0f5ee19 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, 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
@@ -618,7 +618,7 @@ public final class RDataFactory {
 
         public final RSymbol createSymbol(String name) {
             assert Utils.isInterned(name);
-            return traceDataCreated(new RSymbol(name));
+            return traceDataCreated(RSymbol.install(name));
         }
 
         /*
@@ -1197,7 +1197,7 @@ public final class RDataFactory {
 
     public static RSymbol createSymbol(String name) {
         assert Utils.isInterned(name);
-        return traceDataCreated(new RSymbol(name));
+        return traceDataCreated(RSymbol.install(name));
     }
 
     /*
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
index 8f4bc9a99b1ab10abef07b05c514614fafe3da45..acf61beac80b4fda379e5b6517a6084091d2608f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -215,6 +215,14 @@ public class RPromise extends RObject implements RTypedValue {
         this.value = newValue;
     }
 
+    /**
+     * Promises to constants can be optimized, which means that they only hold the value, but do not
+     * need to keep the frame and will never need the frame.
+     */
+    public boolean isOptimized() {
+        return this.execFrame == null;
+    }
+
     /**
      * Returns {@code true} if this promise has been evaluated?
      */
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSymbol.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSymbol.java
index ad8f31449e1039194392bc5b23d1f525e9bc34cc..903fd638fde1b7af7ef77d0d6d91db62ea5939ca 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSymbol.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSymbol.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -22,6 +22,12 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.ValueType;
 import com.oracle.truffle.r.runtime.RType;
 
@@ -32,14 +38,24 @@ import com.oracle.truffle.r.runtime.RType;
 @ValueType
 public final class RSymbol extends RAttributeStorage {
 
+    /**
+     * Note: GnuR caches all symbols and some packages rely on their identity.
+     */
+    private static final ConcurrentHashMap<String, RSymbol> symbolTable = new ConcurrentHashMap<>();
+
     public static final RSymbol MISSING = RDataFactory.createSymbol("");
 
     private final String name;
 
-    public RSymbol(String name) {
+    private RSymbol(String name) {
         this.name = name;
     }
 
+    public static RSymbol install(String name) {
+        CompilerAsserts.neverPartOfCompilation();
+        return symbolTable.computeIfAbsent(name, RSymbol::new);
+    }
+
     @Override
     public RType getRType() {
         return RType.Symbol;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
index f65913a8cd94b99ae1ea3cfad3a33298ae275f7e..8bc97e9541f25710bfa63ed68ae7826661a1d3f6 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
@@ -105,7 +105,8 @@ public class DLL {
 
         @Override
         public void beforeDispose(RContext contextArg) {
-            if (!isShareDLLKind(context.getKind())) {
+            // Note: the first entry should be RLib
+            if (!isShareDLLKind(context.getKind()) && list.size() > 1) {
                 RootCallTarget closeCallTarget = DLCloseRootNode.create(contextArg);
                 for (int i = 1; i < list.size(); i++) {
                     DLLInfo dllInfo = list.get(i);
@@ -341,7 +342,9 @@ public class DLL {
                 data[3] = rnt.dotSymbol.numArgs;
                 klass[0] = rnt.nst.name() + "Routine";
             }
-            return RDataFactory.createList(data, n > 3 ? NAMES_4_VEC : NAMES_3_VEC);
+            RList result = RDataFactory.createList(data, n > 3 ? NAMES_4_VEC : NAMES_3_VEC);
+            result.setClassAttr(RDataFactory.createStringVector(klass, RDataFactory.COMPLETE_VECTOR));
+            return result;
         }
     }
 
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
index cf85ab25b37bee4c3d962a1907f945a09187c62d..37a36ada6542ff5b75b6ffaa2ebfee172d9c3279 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R
@@ -114,3 +114,8 @@ for(i in seq(5000)) {
 # Following code calls Rf_eval with a language object that contains a promise instead of the expected function
 set.seed(42)
 rffi.RfEvalWithPromiseInPairList()
+
+# CAR/CDR tests
+rffi.CAR(NULL)
+rffi.CDR(NULL)
+invisible(rffi.CAR(as.symbol('a'))) # TODO: printing CHARSEXP not implemented in FastR
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 0b0edf26d2e95aab427b005ab75b9a49b2247d73..f1573834db43b803314f84bbb2b0bf2a351c7d46 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -5780,6 +5780,10 @@ Error in .Internal(as.POSIXlt(, 1)) : argument 1 is empty
 #.Internal(as.POSIXlt(2, ))
 Error in .Internal(as.POSIXlt(2, )) : argument 2 is empty
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt#
+#{ q <- Sys.time(); as.vector(unclass(as.POSIXct(as.POSIXlt(q))) - unclass(q)) }
+[1] 0
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt1#
 #argv <- list(structure(c(2147483648.4, 2147483648.8), class = c('POSIXct', 'POSIXt'), tzone = ''), ''); .Internal(as.POSIXlt(argv[[1]], argv[[2]]))
 [1] "2038-01-19 03:14:08 GMT" "2038-01-19 03:14:08 GMT"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asPOSIXlt.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asPOSIXlt.java
index eec124843f68e15f9f428b858505bf64deedb105..fcab2aa69722a50bdff80345438519aacad9a6b3 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asPOSIXlt.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asPOSIXlt.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -76,5 +76,6 @@ public class TestBuiltin_asPOSIXlt extends TestBase {
     public void testasPOSIXlt() {
         assertEval(Output.MayIgnoreErrorContext, ".Internal(as.POSIXlt(, 1))");
         assertEval(Output.MayIgnoreErrorContext, ".Internal(as.POSIXlt(2, ))");
+        assertEval("{ q <- Sys.time(); as.vector(unclass(as.POSIXct(as.POSIXlt(q))) - unclass(q)) }");
     }
 }