#include <stdint.h>
#include <stddef.h>
#include <string.h>
+#include <limits.h>
+
+#include <lowlevel/barriers.h>
+#include <lowlevel/bitops.h>
namespace System {
struct _i_Object;
return new_arr;
}
};
+
+ template<typename T>
+ struct GrowableArray : public MutableArray<T> {
+ using MutableArray<T>::ptr;
+ using MutableArray<T>::count;
+ size_t bufsize;
+
+ GrowableArray()
+ {
+ bufsize = 0;
+ }
+
+ GrowableArray(NullArray na) : MutableArray<T>(na)
+ {
+ bufsize = 0;
+ }
+
+ GrowableArray(T *PTR, size_t COUNT) : MutableArray<T>(PTR, COUNT)
+ {
+ bufsize = COUNT;
+ }
+
+ GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) :
+ MutableArray<T>(PTR, COUNT)
+ {
+ bufsize = BUFSIZE;
+ }
+
+ GrowableArray(MutableArray<T> &ma) : MutableArray<T>(ma)
+ {
+ bufsize = count;
+ }
+
+ void grow(size_t newsize)
+ {
+ if (newsize <= bufsize)
+ return;
+
+ T *oldptr = ptr;
+ T *newptr = new(orbmm) T[newsize];
+ memcpy(newptr, ptr, count * sizeof(T));
+ ptr = newptr;
+ ll_smp_membar_store_after_store();
+ bufsize = newsize;
+ // FIXME: Should release imply membar?
+ ll_smp_membar_any_after_store();
+ orbmm->release(oldptr);
+ }
+
+ // Caller must sync against all writers.
+ void append(T *newptr, size_t len, size_t max = ULONG_MAX)
+ {
+ if (count + len < count)
+ throw ArrayException();
+
+ if (count + len > max)
+ throw ArrayException();
+
+ if (count + len > bufsize)
+ grow(ll_get_order_round_up(count + len));
+
+ memcpy(ptr + count, newptr, len * sizeof(T));
+ count += len;
+ }
+ };
template<typename T> struct Array {
const T *ptr;
return ret;
}
+ struct IFaceInfo;
+
struct IFaceTable {
- const unsigned long *const guid;
+ const IFaceInfo *info;
const ptrdiff_t offset;
};
// 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);
+ union GUID {
+ unsigned char c[16];
+ unsigned long l[];
+ };
- typedef u64 GUID[2];
+ uintptr_t downcast(::System::_i_Object *obj, const GUID *new_guid);
// FIXME: use above typedef
static inline bool guids_equal(const unsigned long *guid1,
Segment0 seg0;
InvokeMethod invoke;
};
-
+
+ struct IFaceInfo {
+ const GUID *guid;
+ int (*marshall)(GrowableArray<uint8_t> &buf,
+ GrowableArray<ID> &objlist,
+ ParamInfoBlock::Segment *segs,
+ int nsegs);
+ void (*unmarshall)(Array<uint8_t> buf,
+ Array<ID> objlist,
+ ParamInfoBlock::Segment *segs,
+ int nsegs);
+ };
+
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
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;
}
};
}
return orbmm->alloc(len, refs);
}
+// FIXME: This isn't safe on anything with a descructor.
inline void operator delete(void *ptr, ::System::RunTime::ORBMM *orbmm,
int refs = 1)
{
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