--- /dev/null
+// C++ Marshalling
+//
+// This software is copyright (c) 2007 Scott Wood <scott@buserror.net>.
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors or contributors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is hereby granted to everyone, free of charge, to use, copy,
+// modify, prepare derivative works of, publish, distribute, perform,
+// sublicense, and/or sell copies of the Software, provided that the above
+// copyright notice and disclaimer of warranty be included in all copies or
+// substantial portions of this software.
+
+#include "c++.h"
+
#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;
};
Segment0 seg0;
InvokeMethod invoke;
};
-
+
+ struct IFaceInfo {
+ static const uint8_t *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 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)
{
// behaves.
while (true) {
- if (tbl->guid[0] == new_guid_first &&
- tbl->guid[1] == new_guid[1] &&
+ if (tbl->info->guid[0] == new_guid_first &&
+ tbl->info->guid[1] == new_guid[1] &&
(sizeof(long) == 8 ||
- (tbl->guid[2] == new_guid[2] &&
- tbl->guid[3] == new_guid[3])))
+ (tbl->info->guid[2] == new_guid[2] &&
+ tbl->info->guid[3] == new_guid[3])))
break;
tbl++;
- if (__builtin_expect(!tbl->guid, 0))
+ if (__builtin_expect(!tbl->info->guid, 0))
return 0;
}