diff druntime/src/compiler/ldc/cast_.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/druntime/src/compiler/ldc/cast_.d	Tue Jun 02 17:43:06 2009 +0100
@@ -0,0 +1,169 @@
+/**
+ * Implementation of array assignment support routines.
+ *
+ * Copyright: Copyright Digital Mars 2004 - 2009.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
+ * Authors:   Walter Bright, Sean Kelly
+ *
+ *          Copyright Digital Mars 2004 - 2009.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.cast_;
+
+extern (C):
+
+/******************************************
+ * Given a pointer:
+ *      If it is an Object, return that Object.
+ *      If it is an interface, return the Object implementing the interface.
+ *      If it is null, return null.
+ *      Else, undefined crash
+ */
+
+Object _d_toObject(void* p)
+{   Object o;
+
+    if (p)
+    {
+        o = cast(Object)p;
+        ClassInfo oc = o.classinfo;
+        Interface *pi = **cast(Interface ***)p;
+
+        /* Interface.offset lines up with ClassInfo.name.ptr,
+         * so we rely on pointers never being less than 64K,
+         * and Objects never being greater.
+         */
+        if (pi.offset < 0x10000)
+        {
+            //printf("\tpi.offset = %d\n", pi.offset);
+            o = cast(Object)(p - pi.offset);
+        }
+    }
+    return o;
+}
+
+
+/*************************************
+ * Attempts to cast Object o to class c.
+ * Returns o if successful, null if not.
+ */
+
+Object _d_interface_cast(void* p, ClassInfo c)
+{   Object o;
+
+    //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
+    if (p)
+    {
+        Interface *pi = **cast(Interface ***)p;
+
+        //printf("\tpi.offset = %d\n", pi.offset);
+        o = cast(Object)(p - pi.offset);
+        return _d_dynamic_cast(o, c);
+    }
+    return o;
+}
+
+Object _d_dynamic_cast(Object o, ClassInfo c)
+{   ClassInfo oc;
+    size_t offset = 0;
+
+    //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
+
+    if (o)
+    {
+        oc = o.classinfo;
+        if (_d_isbaseof2(oc, c, offset))
+        {
+            //printf("\toffset = %d\n", offset);
+            o = cast(Object)(cast(void*)o + offset);
+        }
+        else
+            o = null;
+    }
+    //printf("\tresult = %p\n", o);
+    return o;
+}
+
+int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout size_t offset)
+{   int i;
+
+    if (oc is c)
+        return 1;
+    do
+    {
+        if (oc.base is c)
+            return 1;
+        for (i = 0; i < oc.interfaces.length; i++)
+        {
+            ClassInfo ic;
+
+            ic = oc.interfaces[i].classinfo;
+            if (ic is c)
+            {   offset = oc.interfaces[i].offset;
+                return 1;
+            }
+        }
+        for (i = 0; i < oc.interfaces.length; i++)
+        {
+            ClassInfo ic;
+
+            ic = oc.interfaces[i].classinfo;
+            if (_d_isbaseof2(ic, c, offset))
+            {   offset = oc.interfaces[i].offset;
+                return 1;
+            }
+        }
+        oc = oc.base;
+    } while (oc);
+    return 0;
+}
+
+int _d_isbaseof(ClassInfo oc, ClassInfo c)
+{   int i;
+
+    if (oc is c)
+        return 1;
+    do
+    {
+        if (oc.base is c)
+            return 1;
+        for (i = 0; i < oc.interfaces.length; i++)
+        {
+            ClassInfo ic;
+
+            ic = oc.interfaces[i].classinfo;
+            if (ic is c || _d_isbaseof(ic, c))
+                return 1;
+        }
+        oc = oc.base;
+    } while (oc);
+    return 0;
+}
+
+/*********************************
+ * Find the vtbl[] associated with Interface ic.
+ */
+
+void *_d_interface_vtbl(ClassInfo ic, Object o)
+{   int i;
+    ClassInfo oc;
+
+    //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
+
+    assert(o);
+
+    oc = o.classinfo;
+    for (i = 0; i < oc.interfaces.length; i++)
+    {
+        ClassInfo oic;
+
+        oic = oc.interfaces[i].classinfo;
+        if (oic is ic)
+        {
+            return cast(void *)oc.interfaces[i].vtbl;
+        }
+    }
+    assert(0);
+}