Mercurial > projects > ldc
annotate tango/lib/compiler/llvmdc/cast.d @ 163:a8cd9bc1021a trunk
[svn r179] lots and lots of fixes, much more of tango now compiles/works.
author | lindquist |
---|---|
date | Mon, 05 May 2008 07:36:29 +0200 |
parents | 336ec4f4bbb3 |
children |
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 | |
143
336ec4f4bbb3
[svn r147] tango.io.Console is now working. True this time :) Yay!
lindquist
parents:
140
diff
changeset
|
30 //debug = PRINTF; |
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
|
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; | |
137 | 43 debug(PRINTF) printf("toObject(%p)\n", p); |
132 | 44 if (p) |
45 { | |
46 o = cast(Object)p; | |
137 | 47 debug(PRINTF) printf("o = %p\n", o); |
48 debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p); | |
132 | 49 ClassInfo oc = o.classinfo; |
137 | 50 debug(PRINTF) printf("oc = %p\n", oc); |
132 | 51 Interface *pi = **cast(Interface ***)p; |
137 | 52 debug(PRINTF) printf("pi = %p\n", pi); |
132 | 53 |
54 /* Interface.offset lines up with ClassInfo.name.ptr, | |
55 * so we rely on pointers never being less than 64K, | |
137 | 56 * and interface vtable offsets never being greater. |
132 | 57 */ |
58 if (pi.offset < 0x10000) | |
59 { | |
137 | 60 debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset); |
132 | 61 o = cast(Object)(p - pi.offset); |
62 } | |
63 } | |
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
|
64 debug(PRINTF) printf("toObject = %p\n", o); |
132 | 65 return o; |
66 } | |
67 | |
68 | |
69 /************************************* | |
70 * Attempts to cast Object o to class c. | |
71 * Returns o if successful, null if not. | |
72 */ | |
73 | |
74 Object _d_interface_cast(void* p, ClassInfo c) | |
75 { Object o; | |
76 | |
137 | 77 debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr); |
132 | 78 if (p) |
79 { | |
80 Interface *pi = **cast(Interface ***)p; | |
81 | |
137 | 82 debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset); |
132 | 83 o = cast(Object)(p - pi.offset); |
84 return _d_dynamic_cast(o, c); | |
85 } | |
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
|
86 debug(PRINTF) printf("_d_interface_cast = %p\n", o); |
132 | 87 return o; |
88 } | |
89 | |
90 Object _d_dynamic_cast(Object o, ClassInfo c) | |
91 { ClassInfo oc; | |
92 size_t offset = 0; | |
93 | |
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
|
94 debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr); |
132 | 95 |
96 if (o) | |
97 { | |
98 oc = o.classinfo; | |
99 if (_d_isbaseof2(oc, c, offset)) | |
100 { | |
137 | 101 debug(PRINTF) printf("\toffset = %d\n", offset); |
132 | 102 o = cast(Object)(cast(void*)o + offset); |
103 } | |
104 else | |
105 o = null; | |
106 } | |
107 //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
|
108 debug(PRINTF) printf("_d_dynamic_cast = %p\n", o); |
132 | 109 return o; |
110 } | |
111 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
112 int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) |
132 | 113 { int i; |
114 | |
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
|
115 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
|
116 |
132 | 117 if (oc is c) |
118 return 1; | |
119 do | |
120 { | |
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
|
121 debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length); |
132 | 122 if (oc.base is c) |
123 return 1; | |
124 for (i = 0; i < oc.interfaces.length; i++) | |
125 { | |
126 ClassInfo ic; | |
127 | |
128 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
|
129 debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr); |
132 | 130 if (ic is c) |
131 { offset = cast(size_t)oc.interfaces[i].offset; | |
132 return 1; | |
133 } | |
134 } | |
135 for (i = 0; i < oc.interfaces.length; i++) | |
136 { | |
137 ClassInfo ic; | |
138 | |
139 ic = oc.interfaces[i].classinfo; | |
140 if (_d_isbaseof2(ic, c, offset)) | |
141 { offset = cast(size_t)oc.interfaces[i].offset; | |
142 return 1; | |
143 } | |
144 } | |
145 oc = oc.base; | |
146 } while (oc); | |
147 return 0; | |
148 } | |
149 | |
150 int _d_isbaseof(ClassInfo oc, ClassInfo c) | |
151 { int i; | |
152 | |
153 if (oc is c) | |
154 return 1; | |
155 do | |
156 { | |
157 if (oc.base is c) | |
158 return 1; | |
159 for (i = 0; i < oc.interfaces.length; i++) | |
160 { | |
161 ClassInfo ic; | |
162 | |
163 ic = oc.interfaces[i].classinfo; | |
164 if (ic is c || _d_isbaseof(ic, c)) | |
165 return 1; | |
166 } | |
167 oc = oc.base; | |
168 } while (oc); | |
169 return 0; | |
170 } | |
171 | |
172 /********************************* | |
173 * Find the vtbl[] associated with Interface ic. | |
174 */ | |
175 | |
176 void *_d_interface_vtbl(ClassInfo ic, Object o) | |
177 { int i; | |
178 ClassInfo oc; | |
179 | |
180 //printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic); | |
181 | |
182 assert(o); | |
183 | |
184 oc = o.classinfo; | |
185 for (i = 0; i < oc.interfaces.length; i++) | |
186 { | |
187 ClassInfo oic; | |
188 | |
189 oic = oc.interfaces[i].classinfo; | |
190 if (oic is ic) | |
191 { | |
192 return cast(void *)oc.interfaces[i].vtbl; | |
193 } | |
194 } | |
195 assert(0); | |
196 } |