Mercurial > projects > ldc
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 } |