]> git.buserror.net Git - polintos/scott/priv.git/blobdiff - include/c++/orb.h
Explicitly set unsigned long array size in GUID union.
[polintos/scott/priv.git] / include / c++ / orb.h
index d215427ffa96fcb82e6b4fdf11f5d6d12ca4c196..fa2f54846379c067e84acbfff1e3a8a93028c75d 100644 (file)
@@ -4,6 +4,12 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <string.h>
+#include <limits.h>
+
+#include <lowlevel/barriers.h>
+#include <lowlevel/bitops.h>
+
+#include <util/array.h>
 
 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<typename T> 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<typename T> 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<T> ma)
-                       {
-                               ptr = ma.ptr;
-                               count = ma.count;
-                       }
-                       
-                       MutableArray<T> constcast()
-                       {
-                               MutableArray<T> ma;
-                               ma.ptr = const_cast<T>(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<T> copy()
-                       {
-                               MutableArray<T> 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<uint8_t> countarray(const char *ptr)
-               {
-                       Array<uint8_t> ret;
-                       ret.ptr = reinterpret_cast<const uint8_t *>(ptr);
-                       ret.count = strlen(ptr);
-                       return ret;
-               }
-
-               static inline MutableArray<uint8_t> countarray(char *ptr)
-               {
-                       MutableArray<uint8_t> ret;
-                       ret.ptr = reinterpret_cast<uint8_t *>(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<ID, ORBMM> 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<uint8_t, ORBMM> &buf;
+                       GrowableArray<ID, ORBMM> &objlist;
+                       GrowableArray<NewObject, ORBMM> &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 {
-               static inline 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