Mercurial > projects > ldc
annotate tango/lib/compiler/llvmdc/cast.d @ 136:0e28624814e8 trunk
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author | lindquist |
---|---|
date | Thu, 17 Jan 2008 03:15:12 +0100 |
parents | 44a95ac7368a |
children | ce7b81fb957f |
rev | line source |
---|---|
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 | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
30 debug = PRINTF; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
31 debug(PRINTF) int printf(char*, ...); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
32 |
132 | 33 /****************************************** |
34 * Given a pointer: | |
35 * If it is an Object, return that Object. | |
36 * If it is an interface, return the Object implementing the interface. | |
37 * If it is null, return null. | |
38 * Else, undefined crash | |
39 */ | |
40 | |
41 Object _d_toObject(void* p) | |
42 { Object o; | |
43 | |
44 if (p) | |
45 { | |
46 o = cast(Object)p; | |
47 ClassInfo oc = o.classinfo; | |
48 Interface *pi = **cast(Interface ***)p; | |
49 | |
50 /* Interface.offset lines up with ClassInfo.name.ptr, | |
51 * so we rely on pointers never being less than 64K, | |
52 * and Objects never being greater. | |
53 */ | |
54 if (pi.offset < 0x10000) | |
55 { | |
56 //printf("\tpi.offset = %d\n", pi.offset); | |
57 o = cast(Object)(p - pi.offset); | |
58 } | |
59 } | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
60 debug(PRINTF) printf("toObject = %p\n", o); |
132 | 61 return o; |
62 } | |
63 | |
64 | |
65 /************************************* | |
66 * Attempts to cast Object o to class c. | |
67 * Returns o if successful, null if not. | |
68 */ | |
69 | |
70 Object _d_interface_cast(void* p, ClassInfo c) | |
71 { Object o; | |
72 | |
73 //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name); | |
74 if (p) | |
75 { | |
76 Interface *pi = **cast(Interface ***)p; | |
77 | |
78 //printf("\tpi.offset = %d\n", pi.offset); | |
79 o = cast(Object)(p - pi.offset); | |
80 return _d_dynamic_cast(o, c); | |
81 } | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
82 debug(PRINTF) printf("_d_interface_cast = %p\n", o); |
132 | 83 return o; |
84 } | |
85 | |
86 Object _d_dynamic_cast(Object o, ClassInfo c) | |
87 { ClassInfo oc; | |
88 size_t offset = 0; | |
89 | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
90 debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr); |
132 | 91 |
92 if (o) | |
93 { | |
94 oc = o.classinfo; | |
95 if (_d_isbaseof2(oc, c, offset)) | |
96 { | |
97 //printf("\toffset = %d\n", offset); | |
98 o = cast(Object)(cast(void*)o + offset); | |
99 } | |
100 else | |
101 o = null; | |
102 } | |
103 //printf("\tresult = %p\n", o); | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
104 debug(PRINTF) printf("_d_dynamic_cast = %p\n", o); |
132 | 105 return o; |
106 } | |
107 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
108 int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) |
132 | 109 { int i; |
110 | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
111 debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
112 |
132 | 113 if (oc is c) |
114 return 1; | |
115 do | |
116 { | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
117 debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length); |
132 | 118 if (oc.base is c) |
119 return 1; | |
120 for (i = 0; i < oc.interfaces.length; i++) | |
121 { | |
122 ClassInfo ic; | |
123 | |
124 ic = oc.interfaces[i].classinfo; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
125 debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr); |
132 | 126 if (ic is c) |
127 { offset = cast(size_t)oc.interfaces[i].offset; | |
128 return 1; | |
129 } | |
130 } | |
131 for (i = 0; i < oc.interfaces.length; i++) | |
132 { | |
133 ClassInfo ic; | |
134 | |
135 ic = oc.interfaces[i].classinfo; | |
136 if (_d_isbaseof2(ic, c, offset)) | |
137 { offset = cast(size_t)oc.interfaces[i].offset; | |
138 return 1; | |
139 } | |
140 } | |
141 oc = oc.base; | |
142 } while (oc); | |
143 return 0; | |
144 } | |
145 | |
146 int _d_isbaseof(ClassInfo oc, ClassInfo c) | |
147 { int i; | |
148 | |
149 if (oc is c) | |
150 return 1; | |
151 do | |
152 { | |
153 if (oc.base is c) | |
154 return 1; | |
155 for (i = 0; i < oc.interfaces.length; i++) | |
156 { | |
157 ClassInfo ic; | |
158 | |
159 ic = oc.interfaces[i].classinfo; | |
160 if (ic is c || _d_isbaseof(ic, c)) | |
161 return 1; | |
162 } | |
163 oc = oc.base; | |
164 } while (oc); | |
165 return 0; | |
166 } | |
167 | |
168 /********************************* | |
169 * Find the vtbl[] associated with Interface ic. | |
170 */ | |
171 | |
172 void *_d_interface_vtbl(ClassInfo ic, Object o) | |
173 { int i; | |
174 ClassInfo oc; | |
175 | |
176 //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic); | |
177 | |
178 assert(o); | |
179 | |
180 oc = o.classinfo; | |
181 for (i = 0; i < oc.interfaces.length; i++) | |
182 { | |
183 ClassInfo oic; | |
184 | |
185 oic = oc.interfaces[i].classinfo; | |
186 if (oic is ic) | |
187 { | |
188 return cast(void *)oc.interfaces[i].vtbl; | |
189 } | |
190 } | |
191 assert(0); | |
192 } |