+
+namespace Arch {
+namespace Priv {
+ struct OrbRegs {
+ u32 ds, es;
+
+ union {
+ System::RunTime::ParamInfoBlock *pib;
+ ulong exptr;
+ };
+
+ union {
+ ulong caller;
+ ulong exlen;
+ };
+
+ ulong eip, cs, eflags, user_esp, user_ss;
+ };
+}}
+
+extern "C" void x86_invoke_method(Arch::Priv::OrbRegs *regs)
+{
+ assert(regs->cs & 3);
+ printf("x86_invoke_method %p\n", regs->pib);
+
+ try {
+ ORB::invoke_method(regs->pib, regs->user_esp);
+ }
+
+ catch (SystemException &se) {
+ // Copy exception to user
+ // If an exception is thrown during dispatch, it must be
+ // with the caller's address space, and user_esp must be
+ // the caller's.
+
+ printf("sys exception\n");
+
+ typedef System::Exceptions::NativeCodeExceptionOriginInfo OriginInfo;
+ OriginInfo *oi = OriginInfo::downcast(se.origin);
+
+ if (oi)
+ printf("PC %llx\n", oi->pc);
+ }
+
+ catch (...) {
+ printf("other exception\n");
+ }
+}
+
+extern "C" void x86_return_from_method(Arch::Priv::OrbRegs *regs)
+{
+ assert(regs->cs & 3);
+ regs->user_esp = ORB::return_from_method(regs->exptr, regs->exlen);
+}