]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/c++/orb.cc
f922a7fbbe440c4a5a36a25fcfdbd7494f8d8226
[polintos/scott/priv.git] / lib / c++ / orb.cc
1 #include <System.h>
2
3 namespace System {
4         namespace RunTime {
5                 // This function could be made to do a binary search if we can
6                 // manage to somehow sort the IFaceTables...
7
8                 uintptr_t downcast(::System::_i_Object *obj,
9                                    const unsigned long *new_guid)
10                 {
11                         if (!obj)
12                                 return 0;
13
14                         void unsupported_long_size();
15
16                         if (sizeof(long) != 4 && sizeof(long) != 8)
17                                 unsupported_long_size();
18
19                         IFaceTable *tbl = obj->info->concrete_IFaceTable;
20                         unsigned long new_guid_first = *new_guid;
21                         
22                         // This doesn't use guids_equal(), as that would eliminate the
23                         // ability to cache the first word of new_guid.  The compiler
24                         // *might* do it anyway, but this code was written before
25                         // guids_equal existed, and I don't want to risk removing an
26                         // optimization by changing it now without testing how GCC
27                         // behaves.
28                         
29                         do {
30                                 if (*tbl->guid == new_guid_first &&
31                                     tbl->guid[1] == new_guid[1] &&
32                                     (sizeof(long) == 8 ||
33                                      (tbl->guid[2] == new_guid[2] &&
34                                       tbl->guid[3] == new_guid[3])))
35                                         break;                          
36
37                                 tbl++;
38                         } while (tbl->guid);
39                         
40                         uintptr_t ptr = reinterpret_cast<uintptr_t>(obj);
41                         
42                         ptr += obj->info->concrete;
43                         ptr += tbl->offset;
44                         
45                         return ptr;
46                 };
47                 
48                 unsigned long get_pc()
49                 {
50                         return reinterpret_cast<unsigned long>(__builtin_return_address(0));
51                 }
52         }
53 }