X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=lib%2Fc%2B%2B%2Forb.cc;fp=lib%2Fc%2B%2B%2Forb.cc;h=26f3fc2731b4a74039a3fe84e1726b49b7925136;hp=a1f10a51da2add8555e39fc1f002ad5b691c2d86;hb=d32da4b91b9a403ae9d65c48fbb25c1abbb5083f;hpb=f413d22bf73f826dacc8881cbfb902e77aa1a84d diff --git a/lib/c++/orb.cc b/lib/c++/orb.cc index a1f10a5..26f3fc2 100644 --- a/lib/c++/orb.cc +++ b/lib/c++/orb.cc @@ -1,55 +1,103 @@ #include 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 ::System::Exceptions::Std; - uintptr_t downcast(::System::_i_Object *obj, - const unsigned long *new_guid) - { - if (!obj) - return 0; + // This function could be made to do a binary search if we can + // manage to somehow sort the IFaceTables... - 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. - - while (true) { - if (tbl->guid[0] == 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++; - if (__builtin_expect(!tbl->guid, 0)) - return 0; - } + uintptr_t downcast(::System::_i_Object *obj, + const unsigned long *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; - uintptr_t ptr = reinterpret_cast(obj); - - ptr += obj->info->concrete; - ptr += tbl->offset; - - return ptr; - }; + // 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->guid[0] == 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++; + if (__builtin_expect(!tbl->guid, 0)) + return 0; + } + + uintptr_t ptr = reinterpret_cast(obj); + + ptr += obj->info->concrete; + ptr += tbl->offset; + + return ptr; + }; + + + namespace Priv { + ObjTable objtable; + unsigned long get_pc() { return reinterpret_cast(__builtin_return_address(0)); } + + void exception_to_array(::System::VStruct *ex, Array *ar) + { + ar->ptr = reinterpret_cast(ex); + ar->count = ex->_infoptr->structlen; + } + + void handle_message(ParameterInfoBlock *pib) + { + Message *msg = reinterpret_cast(pib->segments[0].ptr); + + switch (seg0->opcode) { + case Segment0::InvokeMethod: { + if (pib->segments[0].len < sizeof(InvokeMessage)) + throw_idl(ShortMessage, 0, pib->segments[0].len, + sizeof(InvokeMessage)); + + ID obj = pib->objlist[0]; + + + break; + } + + default: + throw_idl(InvalidOpcode, seg0->opcode); + } + } + } +}} + +extern "C" handle_message(ParameterInfoaBlock *pib, Array *ex_arr) +{ + try { + ::System::RunTime::handle_message(pib); + } + + catch (::System::Exception *ex) { + exception_to_array(ex, ex_arr); + } + + catch (...) { + assertl(0, Assert::Always); } }