]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/c++/orb.cc
xfer to laptop
[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 //      ::System::Object create_wrapper(
52
53         namespace Priv {
54                 typedef void (*MethodEntry)(ParamInfoBlock *pib);
55
56                 struct Object {
57                         MethodEntry entry;
58                         void *ptr; // pointer to the class interface
59                 };
60
61                 typedef ::Util::RadixTree<Object, ID, 6> ObjTable;
62 //              ObjTable objtable;
63
64                 unsigned long get_pc()
65                 {
66                         return reinterpret_cast<unsigned long>(__builtin_return_address(0));
67                 }
68
69                 void exception_to_array(::System::VStruct *ex, Array<uint8_t> *ar)
70                 {
71                         // FIXME: marshall struct
72                 }
73                 
74                 void handle_message(ParamInfoBlock *pib)
75                 {
76                         Message *msg = reinterpret_cast<Message *>(pib->segments[0].ptr);
77                 
78                         switch (msg->seg0.opcode) {
79                                 case Segment0::InvokeMethod: {
80                                         if (pib->segments[0].len < sizeof(InvokeMethod))
81                                                 throw_idl(ShortMessage, 0, pib->segments[0].len,
82                                                           sizeof(InvokeMethod));
83         
84 //                                      ID obj = pib->objlist[0];
85                                         break;
86                                 }
87                                 
88                                 default:
89                                         throw_idl(InvalidOpcode, msg->seg0.opcode);
90                         }
91                 }
92         }
93 }}
94
95 extern "C" void abort();
96
97 extern "C" void handle_message(::System::RunTime::ParamInfoBlock *pib,
98                                ::System::RunTime::Array<uint8_t> *ex_arr)
99 {
100         try {
101                 ::System::RunTime::Priv::handle_message(pib);
102         }
103         
104         catch (::System::Exceptions::Exception &ex) {
105                 ::System::RunTime::Priv::exception_to_array(&ex, ex_arr);
106         }
107         
108         catch (...) {
109                 abort();
110         }
111 }