132
|
1 /*
|
|
2 * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
|
|
3 * Written by Walter Bright
|
|
4 *
|
|
5 * This software is provided 'as-is', without any express or implied
|
|
6 * warranty. In no event will the authors be held liable for any damages
|
|
7 * arising from the use of this software.
|
|
8 *
|
|
9 * Permission is granted to anyone to use this software for any purpose,
|
|
10 * including commercial applications, and to alter it and redistribute it
|
|
11 * freely, in both source and binary form, subject to the following
|
|
12 * restrictions:
|
|
13 *
|
|
14 * o The origin of this software must not be misrepresented; you must not
|
|
15 * claim that you wrote the original software. If you use this software
|
|
16 * in a product, an acknowledgment in the product documentation would be
|
|
17 * appreciated but is not required.
|
|
18 * o Altered source versions must be plainly marked as such, and must not
|
|
19 * be misrepresented as being the original software.
|
|
20 * o This notice may not be removed or altered from any source
|
|
21 * distribution.
|
|
22 */
|
|
23
|
|
24 /*
|
|
25 * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
|
|
26 */
|
|
27
|
|
28 extern (C):
|
|
29
|
|
30 /******************************************
|
|
31 * Given a pointer:
|
|
32 * If it is an Object, return that Object.
|
|
33 * If it is an interface, return the Object implementing the interface.
|
|
34 * If it is null, return null.
|
|
35 * Else, undefined crash
|
|
36 */
|
|
37
|
|
38 Object _d_toObject(void* p)
|
|
39 { Object o;
|
|
40
|
|
41 if (p)
|
|
42 {
|
|
43 o = cast(Object)p;
|
|
44 ClassInfo oc = o.classinfo;
|
|
45 Interface *pi = **cast(Interface ***)p;
|
|
46
|
|
47 /* Interface.offset lines up with ClassInfo.name.ptr,
|
|
48 * so we rely on pointers never being less than 64K,
|
|
49 * and Objects never being greater.
|
|
50 */
|
|
51 if (pi.offset < 0x10000)
|
|
52 {
|
|
53 //printf("\tpi.offset = %d\n", pi.offset);
|
|
54 o = cast(Object)(p - pi.offset);
|
|
55 }
|
|
56 }
|
|
57 return o;
|
|
58 }
|
|
59
|
|
60
|
|
61 /*************************************
|
|
62 * Attempts to cast Object o to class c.
|
|
63 * Returns o if successful, null if not.
|
|
64 */
|
|
65
|
|
66 Object _d_interface_cast(void* p, ClassInfo c)
|
|
67 { Object o;
|
|
68
|
|
69 //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
|
|
70 if (p)
|
|
71 {
|
|
72 Interface *pi = **cast(Interface ***)p;
|
|
73
|
|
74 //printf("\tpi.offset = %d\n", pi.offset);
|
|
75 o = cast(Object)(p - pi.offset);
|
|
76 return _d_dynamic_cast(o, c);
|
|
77 }
|
|
78 return o;
|
|
79 }
|
|
80
|
|
81 Object _d_dynamic_cast(Object o, ClassInfo c)
|
|
82 { ClassInfo oc;
|
|
83 size_t offset = 0;
|
|
84
|
|
85 //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
|
|
86
|
|
87 if (o)
|
|
88 {
|
|
89 oc = o.classinfo;
|
|
90 if (_d_isbaseof2(oc, c, offset))
|
|
91 {
|
|
92 //printf("\toffset = %d\n", offset);
|
|
93 o = cast(Object)(cast(void*)o + offset);
|
|
94 }
|
|
95 else
|
|
96 o = null;
|
|
97 }
|
|
98 //printf("\tresult = %p\n", o);
|
|
99 return o;
|
|
100 }
|
|
101
|
|
102 int _d_isbaseof2(ClassInfo oc, ClassInfo c, inout size_t offset)
|
|
103 { int i;
|
|
104
|
|
105 if (oc is c)
|
|
106 return 1;
|
|
107 do
|
|
108 {
|
|
109 if (oc.base is c)
|
|
110 return 1;
|
|
111 for (i = 0; i < oc.interfaces.length; i++)
|
|
112 {
|
|
113 ClassInfo ic;
|
|
114
|
|
115 ic = oc.interfaces[i].classinfo;
|
|
116 if (ic is c)
|
|
117 { offset = cast(size_t)oc.interfaces[i].offset;
|
|
118 return 1;
|
|
119 }
|
|
120 }
|
|
121 for (i = 0; i < oc.interfaces.length; i++)
|
|
122 {
|
|
123 ClassInfo ic;
|
|
124
|
|
125 ic = oc.interfaces[i].classinfo;
|
|
126 if (_d_isbaseof2(ic, c, offset))
|
|
127 { offset = cast(size_t)oc.interfaces[i].offset;
|
|
128 return 1;
|
|
129 }
|
|
130 }
|
|
131 oc = oc.base;
|
|
132 } while (oc);
|
|
133 return 0;
|
|
134 }
|
|
135
|
|
136 int _d_isbaseof(ClassInfo oc, ClassInfo c)
|
|
137 { int i;
|
|
138
|
|
139 if (oc is c)
|
|
140 return 1;
|
|
141 do
|
|
142 {
|
|
143 if (oc.base is c)
|
|
144 return 1;
|
|
145 for (i = 0; i < oc.interfaces.length; i++)
|
|
146 {
|
|
147 ClassInfo ic;
|
|
148
|
|
149 ic = oc.interfaces[i].classinfo;
|
|
150 if (ic is c || _d_isbaseof(ic, c))
|
|
151 return 1;
|
|
152 }
|
|
153 oc = oc.base;
|
|
154 } while (oc);
|
|
155 return 0;
|
|
156 }
|
|
157
|
|
158 /*********************************
|
|
159 * Find the vtbl[] associated with Interface ic.
|
|
160 */
|
|
161
|
|
162 void *_d_interface_vtbl(ClassInfo ic, Object o)
|
|
163 { int i;
|
|
164 ClassInfo oc;
|
|
165
|
|
166 //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
|
|
167
|
|
168 assert(o);
|
|
169
|
|
170 oc = o.classinfo;
|
|
171 for (i = 0; i < oc.interfaces.length; i++)
|
|
172 {
|
|
173 ClassInfo oic;
|
|
174
|
|
175 oic = oc.interfaces[i].classinfo;
|
|
176 if (oic is ic)
|
|
177 {
|
|
178 return cast(void *)oc.interfaces[i].vtbl;
|
|
179 }
|
|
180 }
|
|
181 assert(0);
|
|
182 }
|