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