#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;
+ };
+
+// ::System::Object create_wrapper(
- 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, ORBMM> *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, ::System::RunTime::ORBMM> *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();
}
}