Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/runtime/internal/cast.d

Revision 443:44f08170f4ef, 5.3 kB (checked in by Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>, 4 years ago)

Removed tango from the repository and instead added a runtime dir with the files needed to patch and build tango from svn.
Reworked the LLVMDC specific pragmas.

Line 
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 //debug = PRINTF;
31 debug(PRINTF) int printf(char*, ...);
32
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     debug(PRINTF) printf("toObject(%p)\n", p);
44     if (p)
45     {
46         o = cast(Object)p;
47         debug(PRINTF) printf("o = %p\n", o);
48         debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p);
49         ClassInfo oc = o.classinfo;
50         debug(PRINTF) printf("oc = %p\n", oc);
51         Interface *pi = **cast(Interface ***)p;
52         debug(PRINTF) printf("pi = %p\n", pi);
53
54         /* Interface.offset lines up with ClassInfo.name.ptr,
55          * so we rely on pointers never being less than 64K,
56          * and interface vtable offsets never being greater.
57          */
58         if (pi.offset < 0x10000)
59         {
60             debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
61             o = cast(Object)(p - pi.offset);
62         }
63     }
64     debug(PRINTF) printf("toObject = %p\n", o);
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
77     debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr);
78     if (p)
79     {
80         Interface *pi = **cast(Interface ***)p;
81
82         debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
83         o = cast(Object)(p - pi.offset);
84         return _d_dynamic_cast(o, c);
85     }
86     debug(PRINTF) printf("_d_interface_cast = %p\n", o);
87     return o;
88 }
89
90 Object _d_dynamic_cast(Object o, ClassInfo c)
91 {   ClassInfo oc;
92     size_t offset = 0;
93
94     debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
95
96     if (o)
97     {
98         oc = o.classinfo;
99         if (_d_isbaseof2(oc, c, offset))
100         {
101             debug(PRINTF) printf("\toffset = %d\n", offset);
102             o = cast(Object)(cast(void*)o + offset);
103         }
104         else
105             o = null;
106     }
107     //printf("\tresult = %p\n", o);
108     debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
109     return o;
110 }
111
112 int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
113 {   int i;
114
115     debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
116
117     if (oc is c)
118         return 1;
119     do
120     {
121         debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
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;
129             debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
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 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.