]> git.buserror.net Git - polintos/scott/priv.git/blobdiff - lib/c++/orb.cc
fixes/cleanup
[polintos/scott/priv.git] / lib / c++ / orb.cc
index f922a7fbbe440c4a5a36a25fcfdbd7494f8d8226..8533f52347146f677a142a539cca850b675819e3 100644 (file)
 #include <System.h>
+#include <util/radix.h>
 
 namespace System {
-       namespace RunTime {
-               // This function could be made to do a binary search if we can
-               // manage to somehow sort the IFaceTables...
+namespace RunTime {
+       using namespace ::System::Exceptions::Std;
 
-               uintptr_t downcast(::System::_i_Object *obj,
-                                  const unsigned long *new_guid)
-               {
-                       if (!obj)
+       // This function could be made to do a binary search if we can
+       // manage to somehow sort the IFaceTables...
+       uintptr_t downcast(::System::_i_Object *obj, const GUID *new_guid)
+       {
+               if (!obj)
+                       return 0;
+
+               void unsupported_long_size();
+
+               if (sizeof(long) != 4 && sizeof(long) != 8)
+                       unsupported_long_size();
+
+               IFaceTable *tbl = obj->info->concrete_IFaceTable;
+               unsigned long new_guid_first = new_guid->l[0];
+               
+               // This doesn't use guids_equal(), as that would eliminate the
+               // ability to cache the first word of new_guid.  The compiler
+               // *might* do it anyway, but this code was written before
+               // guids_equal existed, and I don't want to risk removing an
+               // optimization by changing it now without testing how GCC
+               // behaves.
+               
+               while (true) {
+                       if (tbl->info->guid->l[0] == new_guid_first &&
+                           tbl->info->guid->l[1] == new_guid->l[1] &&
+                           (sizeof(long) == 8 ||
+                            (tbl->info->guid->l[2] == new_guid->l[2] &&
+                             tbl->info->guid->l[3] == new_guid->l[3])))
+                               break;                          
+
+                       tbl++;
+                       if (__builtin_expect(!tbl->info->guid->l[0], 0))
                                return 0;
+               }
+       
+               uintptr_t ptr = reinterpret_cast<uintptr_t>(obj);
+               
+               ptr += obj->info->concrete;
+               ptr += tbl->offset;
+               
+               return ptr;
+       };
 
-                       void unsupported_long_size();
-
-                       if (sizeof(long) != 4 && sizeof(long) != 8)
-                               unsupported_long_size();
-
-                       IFaceTable *tbl = obj->info->concrete_IFaceTable;
-                       unsigned long new_guid_first = *new_guid;
-                       
-                       // This doesn't use guids_equal(), as that would eliminate the
-                       // ability to cache the first word of new_guid.  The compiler
-                       // *might* do it anyway, but this code was written before
-                       // guids_equal existed, and I don't want to risk removing an
-                       // optimization by changing it now without testing how GCC
-                       // behaves.
-                       
-                       do {
-                               if (*tbl->guid == new_guid_first &&
-                                   tbl->guid[1] == new_guid[1] &&
-                                   (sizeof(long) == 8 ||
-                                    (tbl->guid[2] == new_guid[2] &&
-                                     tbl->guid[3] == new_guid[3])))
-                                       break;                          
-
-                               tbl++;
-                       } while (tbl->guid);
-                       
-                       uintptr_t ptr = reinterpret_cast<uintptr_t>(obj);
-                       
-                       ptr += obj->info->concrete;
-                       ptr += tbl->offset;
-                       
-                       return ptr;
+       namespace Priv {
+               typedef void (*MethodEntry)(ParamInfoBlock *pib);
+
+               struct Object {
+                       MethodEntry entry;
+                       void *ptr; // pointer to the class interface
                };
-               
+
+               typedef ::Util::RadixTree<Object, ID, 6> ObjTable;
+//             ObjTable objtable;
+
                unsigned long get_pc()
                {
                        return reinterpret_cast<unsigned long>(__builtin_return_address(0));
                }
+
+               void exception_to_array(::System::VStruct *ex, Array<uint8_t> *ar)
+               {
+                       // FIXME: marshall struct
+               }
+               
+               void handle_message(ParamInfoBlock *pib)
+               {
+                       Message *msg = reinterpret_cast<Message *>(pib->segments[0].ptr);
+               
+                       switch (msg->seg0.opcode) {
+                               case Segment0::InvokeMethod: {
+                                       if (pib->segments[0].len < sizeof(InvokeMethod))
+                                               throw_idl(ShortMessage, 0, pib->segments[0].len,
+                                                         sizeof(InvokeMethod));
+       
+//                                     ID obj = pib->objlist[0];
+                                       break;
+                               }
+                               
+                               default:
+                                       throw_idl(InvalidOpcode, msg->seg0.opcode);
+                       }
+               }
+       }
+}}
+
+extern "C" void abort();
+
+extern "C" void handle_message(::System::RunTime::ParamInfoBlock *pib,
+                               ::System::RunTime::Array<uint8_t> *ex_arr)
+{
+       try {
+               ::System::RunTime::Priv::handle_message(pib);
+       }
+       
+       catch (::System::Exceptions::Exception &ex) {
+               ::System::RunTime::Priv::exception_to_array(&ex, ex_arr);
+       }
+       
+       catch (...) {
+               abort();
        }
 }