5 using ::System::Exceptions::Std;
7 // This function could be made to do a binary search if we can
8 // manage to somehow sort the IFaceTables...
10 uintptr_t downcast(::System::_i_Object *obj,
11 const unsigned long *new_guid)
16 void unsupported_long_size();
18 if (sizeof(long) != 4 && sizeof(long) != 8)
19 unsupported_long_size();
21 IFaceTable *tbl = obj->info->concrete_IFaceTable;
22 unsigned long new_guid_first = *new_guid;
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
32 if (tbl->guid[0] == new_guid_first &&
33 tbl->guid[1] == new_guid[1] &&
35 (tbl->guid[2] == new_guid[2] &&
36 tbl->guid[3] == new_guid[3])))
40 if (__builtin_expect(!tbl->guid, 0))
44 uintptr_t ptr = reinterpret_cast<uintptr_t>(obj);
46 ptr += obj->info->concrete;
56 unsigned long get_pc()
58 return reinterpret_cast<unsigned long>(__builtin_return_address(0));
61 void exception_to_array(::System::VStruct *ex, Array<uint8_t> *ar)
63 ar->ptr = reinterpret_cast<uint8_t *>(ex);
64 ar->count = ex->_infoptr->structlen;
67 void handle_message(ParameterInfoBlock *pib)
69 Message *msg = reinterpret_cast<Message *>(pib->segments[0].ptr);
71 switch (seg0->opcode) {
72 case Segment0::InvokeMethod: {
73 if (pib->segments[0].len < sizeof(InvokeMessage))
74 throw_idl(ShortMessage, 0, pib->segments[0].len,
75 sizeof(InvokeMessage));
77 ID obj = pib->objlist[0];
84 throw_idl(InvalidOpcode, seg0->opcode);
90 extern "C" handle_message(ParameterInfoaBlock *pib, Array<uint8_t> *ex_arr)
93 ::System::RunTime::handle_message(pib);
96 catch (::System::Exception *ex) {
97 exception_to_array(ex, ex_arr);
101 assertl(0, Assert::Always);