X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Forb.h;h=fa2f54846379c067e84acbfff1e3a8a93028c75d;hp=31348f2227a3f6680ac31e8ce281c464468ea32b;hb=c935c41d1f2969dae860cdb16127779d2970a0e3;hpb=e4560eb81e14ff6ce67752591ea63ad58bfc45be diff --git a/include/c++/orb.h b/include/c++/orb.h index 31348f2..fa2f548 100644 --- a/include/c++/orb.h +++ b/include/c++/orb.h @@ -4,6 +4,12 @@ #include #include #include +#include + +#include +#include + +#include namespace System { struct _i_Object; @@ -13,237 +19,118 @@ namespace System { } namespace RunTime { + using namespace ::Util::Arrays; + class ORBMM { - void *priv; + static void *priv; public: - class AllocGroup { - friend class ORBMM; - }; - typedef ::System::Mem::Region Region; - ORBMM(); - - void *alloc(size_t size, int refs = 1); - void retain(void *ptr, int refs = 1); - void release(void *ptr, int refs = 1); - void add_region(Region region, bool unmap_orig, int refs = 1); + static void *alloc(size_t size, int refs = 1); + static void retain(void *ptr, int refs = 1); + static void release(void *ptr, int refs = 1); + static void add_region(Region region, bool unmap_orig, int refs = 1); }; - extern ORBMM *orbmm; - - // FIXME: should be an IDL exception - struct ArrayException - { + struct IFaceInfo; + typedef uint32_t ID; + + struct IFaceTable { + const IFaceInfo *info; + const ptrdiff_t offset; }; - class NullArray { + union GUID { + unsigned char c[16]; + unsigned long l[16 / sizeof(unsigned long)]; }; - - static const NullArray nullarray = {}; - - template struct MutableArray { - T *ptr; - size_t count; - - bool valid_index(size_t index) - { - return index >= 0 && index < count; - } - - T &operator[](size_t index) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(index)) - throw ArrayException(); -#endif - - return ptr[index]; - } - - MutableArray() - { - ptr = NULL; - count = 0; - } - - MutableArray(NullArray na) - { - ptr = NULL; - count = 0; - } - - MutableArray(T *PTR, size_t COUNT) - { - ptr = PTR; - count = COUNT; - } - - MutableArray &slice_nocheck(size_t first, size_t newcount) - { - MutableArray ret; - ret.ptr = ptr + first; - ret.count = newcount; - return ret; - } - MutableArray &slice_nocheck(size_t first) - { - MutableArray ret; - ret.ptr = ptr + first; - ret.count = count - first; - return ret; - } + uintptr_t downcast(::System::_i_Object *obj, const GUID *new_guid); - MutableArray &slice(size_t first, size_t count) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(first) || !valid_index(first + count - 1)) - throw ArrayException(); -#endif - - return slice_nocheck(first, count); - } + // FIXME: use above typedef + static inline bool guids_equal(const unsigned long *guid1, + const unsigned long *guid2) + { + return (guid1[0] == guid2[0] && + guid1[1] == guid2[1] && + (sizeof(long) == 8 || + (guid1[2] == guid2[2] && + guid1[3] == guid2[3]))); + } + + struct ParamInfoBlock { + uint32_t buffer_size; + uint32_t copy_size; + ID *objlist, *newobj; + uint32_t objlist_len, newobj_len; + uint32_t num_segments; - MutableArray &slice(size_t first) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(first)) - throw ArrayException(); -#endif + struct Segment { + uint8_t *ptr; + uintptr_t len; + uintptr_t flags; + uintptr_t reserved; - return slice_nocheck(first); - } - - MutableArray copy() - { - MutableArray new_arr; - new_arr.ptr = new(orbmm) T[count]; - new_arr.count = count; - memcpy(new_arr.ptr, ptr, count); - return new_arr; - } + enum { + In = 1, + Out = 2, + Inline = 4, + Copy = 8 + }; + } segments[0]; }; - - template struct Array { - const T *ptr; - size_t count; - bool valid_index(size_t index) - { - return index >= 0 && index < count; - } - - const T &operator[](size_t index) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(index)) - throw ArrayException(); -#endif + struct Segment0 { + enum { + InvokeMethod = 0, + GetIFaces = 1, + ReturnIFaces = 2, + }; - return ptr[index]; - } - - Array() - { - ptr = NULL; - count = 0; - } - - Array(NullArray na) - { - ptr = NULL; - count = 0; - } - - Array(const T *PTR, size_t COUNT) - { - ptr = PTR; - count = COUNT; - } - - Array(MutableArray ma) - { - ptr = ma.ptr; - count = ma.count; - } - - MutableArray constcast() - { - MutableArray ma; - ma.ptr = const_cast(ptr); - ma.count = count; - return ma; - } - - Array &slice_nocheck(size_t first, size_t newcount) - { - Array ret; - ret.ptr = ptr + first; - ret.count = newcount; - return ret; - } - - Array &slice_nocheck(size_t first) - { - Array ret; - ret.ptr = ptr + first; - ret.count = count - first; - return ret; - } - - Array &slice(size_t first, size_t count) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(first) || !valid_index(first + count - 1)) - throw ArrayException(); -#endif - - return slice_nocheck(first, count); - } - - Array &slice(size_t first) - { -#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK - if (!valid_index(first)) - throw ArrayException(); -#endif + union { + struct { + uint8_t opcode; + }; - return slice_nocheck(first); - } + unsigned long pad; + }; + }; - MutableArray copy() - { - MutableArray new_arr; - new_arr.ptr = new(orbmm) T[count]; - new_arr.count = count; - memcpy(new_arr.ptr, ptr, count); - return new_arr; - } + struct InvokeMethod { + Segment0 seg0; + uint32_t iface; + uint32_t method; + uint8_t args[0]; }; - - static inline Array countarray(const char *ptr) - { - Array ret; - ret.ptr = reinterpret_cast(ptr); - ret.count = strlen(ptr); - return ret; - } - - static inline MutableArray countarray(char *ptr) - { - MutableArray ret; - ret.ptr = reinterpret_cast(ptr); - ret.count = strlen(ptr); - return ret; - } - struct IFaceTable { - const unsigned long *const guid; - const ptrdiff_t offset; + union Message { + Segment0 seg0; + InvokeMethod invoke; + }; + + struct IFaceInfo { + const GUID *guid; + void (*invoke)(Array objlist, + ParamInfoBlock::Segment *segs, + int nsegs); + ::System::_i_Object *(*wrapper)(ID id); }; + struct NewObject { + uint32_t guid_hash[5]; // SHA-1 hash of Interface GUIDs + uint32_t id; + uint32_t reserved[3]; // must be zero + }; + + struct MarshCtx { + GrowableArray &buf; + GrowableArray &objlist; + GrowableArray &newobjlist; + ParamInfoBlock::Segment *segs; + int nsegs; + }; + struct VStructInfo { // List of GUIDs of the struct and its superstructs, // starting with System.VStruct and ending with @@ -254,78 +141,42 @@ namespace System { // Length of inheritance chain; 1 for System.VStruct const int chainlen; + + int (*marshall)(MarshCtx &ctx); + void (*unmarshall)(MarshCtx &ctx); }; - - uintptr_t downcast(::System::_i_Object *obj, - const unsigned long *new_guid); - static inline bool guids_equal(const unsigned long *guid1, - const unsigned long *guid2) - { - return (guid1[0] == guid2[0] && - guid1[1] == guid2[1] && - (sizeof(long) == 8 || - (guid1[2] == guid2[2] && - guid1[3] == guid2[3]))); - } - - // Return the caller's PC. It'd be nice if GCC had a builtin for - // the current PC, so that a simple relocation could be used rather - // than a function call. OPT: put this in lowlevel-lib, so that - // architectures can provide a faster version. - - unsigned long get_pc(); - - struct ParamInfoBlock { - uintptr_t buffer_size; - uintptr_t copy_size; - uintptr_t *objlist_ptr; - uintptr_t objlist_len; - uintptr_t num_segments; + namespace Priv { + // Return the caller's PC. It'd be nice if GCC had a builtin for + // the current PC, so that a simple relocation could be used rather + // than a function call. OPT: put this in lowlevel-lib, so that + // architectures can provide a faster version. + + unsigned long get_pc(); - struct Segment { - void *ptr; - uintptr_t len; - uintptr_t flags; - uintptr_t reserved; - } segments[0]; - }; - } - - namespace Priv { - bool in_kernel() - { + static inline bool in_kernel() + { #ifdef _KERNEL - return true; + return true; #else - return false; + return false; #endif + } + } }; } -inline void *operator new(size_t len, ::System::RunTime::ORBMM *orbmm, +inline void *operator new(size_t len, ::System::RunTime::ORBMM orbmm, int refs = 1) { - return orbmm->alloc(len, refs); + return ::System::RunTime::ORBMM::alloc(len, refs); } -inline void *operator new[](size_t len, ::System::RunTime::ORBMM *orbmm, +inline void *operator new[](size_t len, ::System::RunTime::ORBMM orbmm, int refs = 1) { - return orbmm->alloc(len, refs); -} - -inline void operator delete(void *ptr, ::System::RunTime::ORBMM *orbmm, - int refs = 1) -{ - orbmm->release(ptr, refs); -} - -inline void operator delete[](void *ptr, ::System::RunTime::ORBMM *orbmm, - int refs = 1) -{ - orbmm->release(ptr, refs); + return ::System::RunTime::ORBMM::alloc(len, refs); } // This is a macro rather than an inline template function so that the @@ -339,18 +190,18 @@ inline void operator delete[](void *ptr, ::System::RunTime::ORBMM *orbmm, #ifndef POLINTOS_NO_THROW_IDL #define throw_idl(T, args...) do { \ throw T(NULL, NULL, \ - new(::System::RunTime::orbmm) \ + new(::System::RunTime::ORBMM()) \ ::System::Exceptions::NativeCodeExceptionOriginInfo \ - (::System::RunTime::get_pc()), \ - ::System::Priv::in_kernel(), ##args); \ + (::System::RunTime::Priv::get_pc()), \ + ::System::RunTime::Priv::in_kernel(), ##args); \ } while (0) #define rethrow_idl(oldex, T, args...) do { \ - throw T(new(::System::RunTime::orbmm) typeof(oldex)(oldex), NULL, \ - new(::System::RunTime::orbmm) \ + throw T(new(::System::RunTime::ORBMM()) typeof(oldex)(oldex), NULL, \ + new(::System::RunTime::ORBMM()) \ ::System::Exceptions::NativeCodeExceptionOriginInfo \ - (::System::RunTime::get_pc()), \ - ::System::Priv::in_kernel(), ##args); \ + (::System::RunTime::Priv::get_pc()), \ + ::System::RunTime::Priv::in_kernel(), ##args); \ } while (0) #endif