]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/c++/orb.cc
xfer to odin
[polintos/scott/priv.git] / lib / c++ / orb.cc
1 #include <System.h>
2 #include <util/radix.h>
3
4 namespace System {
5 namespace RunTime {
6         using namespace ::System::Exceptions::Std;
7
8         // This function could be made to do a binary search if we can
9         // manage to somehow sort the IFaceTables...
10
11         uintptr_t downcast(::System::_i_Object *obj,
12                            const unsigned long *new_guid)
13         {
14                 if (!obj)
15                         return 0;
16
17                 void unsupported_long_size();
18
19                 if (sizeof(long) != 4 && sizeof(long) != 8)
20                         unsupported_long_size();
21
22                 IFaceTable *tbl = obj->info->concrete_IFaceTable;
23                 unsigned long new_guid_first = *new_guid;
24                 
25                 // This doesn't use guids_equal(), as that would eliminate the
26                 // ability to cache the first word of new_guid.  The compiler
27                 // *might* do it anyway, but this code was written before
28                 // guids_equal existed, and I don't want to risk removing an
29                 // optimization by changing it now without testing how GCC
30                 // behaves.
31                 
32                 while (true) {
33                         if (tbl->info->guid[0] == new_guid_first &&
34                             tbl->info->guid[1] == new_guid[1] &&
35                             (sizeof(long) == 8 ||
36                              (tbl->info->guid[2] == new_guid[2] &&
37                               tbl->info->guid[3] == new_guid[3])))
38                                 break;                          
39
40                         tbl++;
41                         if (__builtin_expect(!tbl->info->guid, 0))
42                                 return 0;
43                 }
44         
45                 uintptr_t ptr = reinterpret_cast<uintptr_t>(obj);
46                 
47                 ptr += obj->info->concrete;
48                 ptr += tbl->offset;
49                 
50                 return ptr;
51         };
52         
53
54         namespace Priv {
55                 typedef void (*MethodEntry)(ParamInfoBlock *pib);
56
57                 struct Object {
58                         MethodEntry entry;
59                         void *ptr; // pointer to the class interface
60                 };
61
62                 typedef Util::RadixTree<Object, ID, 6> ObjTable;
63                 ObjTable objtable;
64
65                 unsigned long get_pc()
66                 {
67                         return reinterpret_cast<unsigned long>(__builtin_return_address(0));
68                 }
69
70                 void exception_to_array(::System::VStruct *ex, Array<uint8_t> *ar)
71                 {
72                         // FIXME
73 //                      ar->ptr = reinterpret_cast<uint8_t *>(ex);
74 //                      ar->count = ex->_infoptr->structlen;
75                 }
76                 
77                 void handle_message(ParamInfoBlock *pib)
78                 {
79                         Message *msg = reinterpret_cast<Message *>(pib->segments[0].ptr);
80                 
81                         switch (msg->seg0.opcode) {
82                                 case Segment0::InvokeMethod: {
83                                         if (pib->segments[0].len < sizeof(InvokeMethod))
84                                                 throw_idl(ShortMessage, 0, pib->segments[0].len,
85                                                           sizeof(InvokeMethod));
86         
87                 //                      ID obj = pib->objlist[0];
88                                         
89                                         
90                                         break;
91                                 }
92                                 
93                                 default:
94                                         throw_idl(InvalidOpcode, msg->seg0.opcode);
95                         }
96                 }
97         }
98 }}
99
100 extern "C" void abort();
101
102 extern "C" void handle_message(::System::RunTime::ParamInfoBlock *pib,
103                                ::System::RunTime::Array<uint8_t> *ex_arr)
104 {
105         try {
106                 ::System::RunTime::Priv::handle_message(pib);
107         }
108         
109         catch (::System::Exceptions::Exception *ex) {
110                 ::System::RunTime::Priv::exception_to_array(ex, ex_arr);
111         }
112         
113         catch (...) {
114                 abort();
115         }
116 }