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