eax: pointer to exception, or NULL if none
edx: length of exception segment, if any
-GUID hash retrieval:
+GUID SHA-1 hash retrieval:
eax: object id
- edx: 16-byte buffer
+ edx: 20-byte buffer
Call the 32-bit address stored at 0x7fff000c.
Object references are encoded as pointer-sized offsets into the
objlist array.
+Virtual structs are prefaced with a header, which consists of
+the following, in order:
+1. 128-bit GUID of the most derived vstruct type
+2. 160-bit SHA-1 of the vstruct type info
+3. 32-bit objlist-offset of an introspection object
+4. 32-bit length of vstruct, including header, and all referenced
+data chunks, which must be contiguously appended to the vstruct body
+5. 32-bit reserved field
+
+The requirement for all referenced data chunks to be contiguous with
+the vstruct means that scatter-gather and zero-copy cannot be done;
+however, it prevents the loss of derived-type data when only a base
+type is known at unmarshalling time (the derived-type data could
+later be accessed through introspection, or be passed to another
+process that does know the derived type). For this reason, vstructs
+should generally not be used to pass large chunks of data.
+
+The introspection object reference may be NULL; in this case, the
+SHA-1 field is ignored.
+
Op1: Get Interface List
-----------------------
struct NewObject {
- u32 guid_hash[4]; // Interface GUID checksum
+ u32 guid_hash[5]; // SHA-1 hash of Interface GUIDs
u32 id; // Filled in by ORB
u32 reserved[3]; // must be zero
};
// Length of inheritance chain; 1 for System.VStruct
const int chainlen;
-
- // Size of concrete vstruct
-
- const int structlen;
};
uintptr_t downcast(::System::_i_Object *obj,
const unsigned long *new_guid);
- typedef u64 GUID[2];
+ typedef uint64_t GUID[2];
// FIXME: use above typedef
static inline bool guids_equal(const unsigned long *guid1,
return false;
#endif
}
-
- typedef void (*MethodEntry)(ParamInfoBlock *pib);
-
- struct Object {
- MethodEntry entry;
- void *ptr; // pointer to the class interface
- };
-
- typedef Util::RadixTree<Object, ID, 6> ObjTable;
}
};
}
throw T(NULL, NULL, \
new(::System::RunTime::orbmm) \
::System::Exceptions::NativeCodeExceptionOriginInfo \
- (::System::RunTime::get_pc()), \
+ (::System::RunTime::Priv::get_pc()), \
::System::RunTime::Priv::in_kernel(), ##args); \
} while (0)
throw T(new(::System::RunTime::orbmm) typeof(oldex)(oldex), NULL, \
new(::System::RunTime::orbmm) \
::System::Exceptions::NativeCodeExceptionOriginInfo \
- (::System::RunTime::get_pc()), \
+ (::System::RunTime::Priv::get_pc()), \
::System::RunTime::Priv::in_kernel(), ##args); \
} while (0)
#endif
#ifndef _UTIL_ASSERT_H
#define _UTIL_ASSERT_H
+#ifndef _UTIL_ASSERT_LEVEL
+#define _UTIL_ASSERT_LEVEL 1
+#endif
+
namespace Assert {
enum {
Always = 0,
#ifndef _UTIL_RADIX_H
#define _UTIL_RADIX_H
-#include <assert.h>
#include <stddef.h>
#include <stdint.h>
-
#include <lowlevel/bitops.h>
namespace Util {
return (key >> shift) & (dir_size - 1);
}
- static uint key_to_offset(Key key)
+ static unsigned int key_to_offset(Key key)
{
return key & (node_size - 1);
}
printf("invoke_method: pib %p\n", user_pib);
ParamInfoBlock pib = Arch::copyin(user_pib);
- printf("objlist len %lu\n", pib.objlist_len);
+ printf("objlist len %u\n", pib.objlist_len);
if (pib.objlist_len == 0)
throw_idl(InvalidArgument, 0, countarray("no objects"));
u8 *copy = new(orbmm) u8[pib.copy_size];
ParamInfoBlock *dpib = reinterpret_cast<ParamInfoBlock *>
(args + piboff);
- dpib->objlist = reinterpret_cast<uintptr_t *>(args + datalen);
+ dpib->objlist = reinterpret_cast<ID *>(args + datalen);
copy_ids_to_kern(dpib, &pib, ids);
copy_data(args, args, pib.buffer_size, dpib, &pib, ~0U, Segment::In);
#include <System.h>
+#include <util/radix.h>
namespace System {
namespace RunTime {
- using ::System::Exceptions::Std;
+ using namespace ::System::Exceptions::Std;
// 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 unsigned long *new_guid)
{
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()
void exception_to_array(::System::VStruct *ex, Array<uint8_t> *ar)
{
- ar->ptr = reinterpret_cast<uint8_t *>(ex);
- ar->count = ex->_infoptr->structlen;
+ // FIXME: marshall struct
}
-
- void handle_message(ParameterInfoBlock *pib)
+
+ void handle_message(ParamInfoBlock *pib)
{
Message *msg = reinterpret_cast<Message *>(pib->segments[0].ptr);
- switch (seg0->opcode) {
+ switch (msg->seg0.opcode) {
case Segment0::InvokeMethod: {
- if (pib->segments[0].len < sizeof(InvokeMessage))
+ if (pib->segments[0].len < sizeof(InvokeMethod))
throw_idl(ShortMessage, 0, pib->segments[0].len,
- sizeof(InvokeMessage));
+ sizeof(InvokeMethod));
- ID obj = pib->objlist[0];
+// ID obj = pib->objlist[0];
break;
}
default:
- throw_idl(InvalidOpcode, seg0->opcode);
+ throw_idl(InvalidOpcode, msg->seg0.opcode);
}
}
}
}}
-extern "C" handle_message(ParameterInfoaBlock *pib, Array<uint8_t> *ex_arr)
+extern "C" void abort();
+
+extern "C" void handle_message(::System::RunTime::ParamInfoBlock *pib,
+ ::System::RunTime::Array<uint8_t> *ex_arr)
{
try {
- ::System::RunTime::handle_message(pib);
+ ::System::RunTime::Priv::handle_message(pib);
}
- catch (::System::Exception *ex) {
- exception_to_array(ex, ex_arr);
+ catch (::System::Exceptions::Exception &ex) {
+ ::System::RunTime::Priv::exception_to_array(&ex, ex_arr);
}
catch (...) {
- assertl(0, Assert::Always);
+ abort();
}
}