comparison druntime/src/compiler/dmd/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
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * Implementation of array assignment support routines.
3 *
4 * Copyright: Copyright Digital Mars 2004 - 2009.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
6 * Authors: Walter Bright, Sean Kelly
7 *
8 * Copyright Digital Mars 2004 - 2009.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or copy at
11 * http://www.boost.org/LICENSE_1_0.txt)
12 */
13 module rt.cast_;
14
15 extern (C):
16
17 /******************************************
18 * Given a pointer:
19 * If it is an Object, return that Object.
20 * If it is an interface, return the Object implementing the interface.
21 * If it is null, return null.
22 * Else, undefined crash
23 */
24
25 Object _d_toObject(void* p)
26 { Object o;
27
28 if (p)
29 {
30 o = cast(Object)p;
31 ClassInfo oc = o.classinfo;
32 Interface *pi = **cast(Interface ***)p;
33
34 /* Interface.offset lines up with ClassInfo.name.ptr,
35 * so we rely on pointers never being less than 64K,
36 * and Objects never being greater.
37 */
38 if (pi.offset < 0x10000)
39 {
40 //printf("\tpi.offset = %d\n", pi.offset);
41 o = cast(Object)(p - pi.offset);
42 }
43 }
44 return o;
45 }
46
47
48 /*************************************
49 * Attempts to cast Object o to class c.
50 * Returns o if successful, null if not.
51 */
52
53 Object _d_interface_cast(void* p, ClassInfo c)
54 { Object o;
55
56 //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
57 if (p)
58 {
59 Interface *pi = **cast(Interface ***)p;
60
61 //printf("\tpi.offset = %d\n", pi.offset);
62 o = cast(Object)(p - pi.offset);
63 return _d_dynamic_cast(o, c);
64 }
65 return o;
66 }
67
68 Object _d_dynamic_cast(Object o, ClassInfo c)
69 { ClassInfo oc;
70 size_t offset = 0;
71
72 //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
73
74 if (o)
75 {
76 oc = o.classinfo;
77 if (_d_isbaseof2(oc, c, offset))
78 {
79 //printf("\toffset = %d\n", offset);
80 o = cast(Object)(cast(void*)o + offset);
81 }
82 else
83 o = null;
84 }
85 //printf("\tresult = %p\n", o);
86 return o;
87 }
88
89 int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout size_t offset)
90 { int i;
91
92 if (oc is c)
93 return 1;
94 do
95 {
96 if (oc.base is c)
97 return 1;
98 for (i = 0; i < oc.interfaces.length; i++)
99 {
100 ClassInfo ic;
101
102 ic = oc.interfaces[i].classinfo;
103 if (ic is c)
104 { offset = oc.interfaces[i].offset;
105 return 1;
106 }
107 }
108 for (i = 0; i < oc.interfaces.length; i++)
109 {
110 ClassInfo ic;
111
112 ic = oc.interfaces[i].classinfo;
113 if (_d_isbaseof2(ic, c, offset))
114 { offset = oc.interfaces[i].offset;
115 return 1;
116 }
117 }
118 oc = oc.base;
119 } while (oc);
120 return 0;
121 }
122
123 int _d_isbaseof(ClassInfo oc, ClassInfo c)
124 { int i;
125
126 if (oc is c)
127 return 1;
128 do
129 {
130 if (oc.base is c)
131 return 1;
132 for (i = 0; i < oc.interfaces.length; i++)
133 {
134 ClassInfo ic;
135
136 ic = oc.interfaces[i].classinfo;
137 if (ic is c || _d_isbaseof(ic, c))
138 return 1;
139 }
140 oc = oc.base;
141 } while (oc);
142 return 0;
143 }
144
145 /*********************************
146 * Find the vtbl[] associated with Interface ic.
147 */
148
149 void *_d_interface_vtbl(ClassInfo ic, Object o)
150 { int i;
151 ClassInfo oc;
152
153 //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
154
155 assert(o);
156
157 oc = o.classinfo;
158 for (i = 0; i < oc.interfaces.length; i++)
159 {
160 ClassInfo oic;
161
162 oic = oc.interfaces[i].classinfo;
163 if (oic is ic)
164 {
165 return cast(void *)oc.interfaces[i].vtbl;
166 }
167 }
168 assert(0);
169 }