From 162bcbe20500026d447471ea289485cc94fcef05 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 3 Jul 2007 20:23:22 -0500 Subject: [PATCH] xfer to odin --- doc/orb/exceptions | 4 ++ idlcomp/languages/c++/Makefile | 2 +- idlcomp/languages/c++/interface-caller.cc | 2 +- idlcomp/languages/c++/marshall.cc | 16 +++++ idlcomp/languages/c++/server.cc | 4 +- idlcomp/vtable-sample.h | 2 +- include/c++/orb.h | 88 ++++++++++++++++++++++- lib/c++/orb.cc | 10 +-- 8 files changed, 116 insertions(+), 12 deletions(-) create mode 100644 doc/orb/exceptions create mode 100644 idlcomp/languages/c++/marshall.cc diff --git a/doc/orb/exceptions b/doc/orb/exceptions new file mode 100644 index 0000000..99f5b60 --- /dev/null +++ b/doc/orb/exceptions @@ -0,0 +1,4 @@ +Exceptions are encoded as a 32-bit objlist length (in IDs), followed +by the objlist, followed by padding if necessary to be aligned on a +64-bit boundary, followed by the exception vstruct (encoded as when +invoking a method). diff --git a/idlcomp/languages/c++/Makefile b/idlcomp/languages/c++/Makefile index e7c666b..0bd489c 100644 --- a/idlcomp/languages/c++/Makefile +++ b/idlcomp/languages/c++/Makefile @@ -1,5 +1,5 @@ DIR := languages/c++/ DIRS += $(DIR) -RAW_CXXFILES := main interface-caller server +RAW_CXXFILES := main interface-caller server marshall BUILDCXXFILES += $(RAW_CXXFILES:%=$(DIR)%) diff --git a/idlcomp/languages/c++/interface-caller.cc b/idlcomp/languages/c++/interface-caller.cc index 7f8d393..4d17670 100644 --- a/idlcomp/languages/c++/interface-caller.cc +++ b/idlcomp/languages/c++/interface-caller.cc @@ -283,7 +283,7 @@ void CPPFile::output_downcast(Interface *iface, Interface *super) << indent << "\treinterpret_cast< ::System::_i_Object *>(oldptr._ptr);\n" << indent << "return " << name << "(reinterpret_cast< " << iname << " *>\n" - << indent << "\t(::System::RunTime::downcast(_llptr, " + << indent << "\t(::System::RunTime::downcast(_llptr, " << name << "_ns::_guid.l)));\n"; indent.indent_level--; diff --git a/idlcomp/languages/c++/marshall.cc b/idlcomp/languages/c++/marshall.cc new file mode 100644 index 0000000..1e0c87a --- /dev/null +++ b/idlcomp/languages/c++/marshall.cc @@ -0,0 +1,16 @@ +// C++ Marshalling +// +// This software is copyright (c) 2007 Scott Wood . +// +// 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" + diff --git a/idlcomp/languages/c++/server.cc b/idlcomp/languages/c++/server.cc index 35a2135..f773e6f 100644 --- a/idlcomp/languages/c++/server.cc +++ b/idlcomp/languages/c++/server.cc @@ -291,8 +291,8 @@ void cpp_output_iface_table_entry(Interface *super, void *arg) ctx.f << ctx.indent; cpp_output_name(ctx.f, super); - ctx.f << "_ns::_guid.l,\n" - << ctx.indent + ctx.f << "_ns::_info,\n" + << ctx.indent << (ctx.cla->concrete_iface->super_to_chain(super) - ctx.chain) * target->pointer_size << '\n'; diff --git a/idlcomp/vtable-sample.h b/idlcomp/vtable-sample.h index db3fd34..a62633c 100644 --- a/idlcomp/vtable-sample.h +++ b/idlcomp/vtable-sample.h @@ -1,7 +1,7 @@ #include struct IFaceTable { - unsigned char *guid; + const IFaceInfo *info; ptrdiff_t offset; }; diff --git a/include/c++/orb.h b/include/c++/orb.h index 23f0b72..30c4157 100644 --- a/include/c++/orb.h +++ b/include/c++/orb.h @@ -4,6 +4,10 @@ #include #include #include +#include + +#include +#include namespace System { struct _i_Object; @@ -125,6 +129,71 @@ namespace System { return new_arr; } }; + + template + struct GrowableArray : public MutableArray { + using MutableArray::ptr; + using MutableArray::count; + size_t bufsize; + + GrowableArray() + { + bufsize = 0; + } + + GrowableArray(NullArray na) : MutableArray(na) + { + bufsize = 0; + } + + GrowableArray(T *PTR, size_t COUNT) : MutableArray(PTR, COUNT) + { + bufsize = COUNT; + } + + GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) : + MutableArray(PTR, COUNT) + { + bufsize = BUFSIZE; + } + + GrowableArray(MutableArray &ma) : MutableArray(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 struct Array { const T *ptr; @@ -239,8 +308,10 @@ namespace System { return ret; } + struct IFaceInfo; + struct IFaceTable { - const unsigned long *const guid; + const IFaceInfo *info; const ptrdiff_t offset; }; @@ -322,7 +393,19 @@ namespace System { Segment0 seg0; InvokeMethod invoke; }; - + + struct IFaceInfo { + static const uint8_t *guid; + int (*marshall)(GrowableArray &buf, + GrowableArray &objlist, + ParamInfoBlock::Segment *segs, + int nsegs); + void (*unmarshall)(Array buf, + Array 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 @@ -355,6 +438,7 @@ inline void *operator new[](size_t len, ::System::RunTime::ORBMM *orbmm, 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) { diff --git a/lib/c++/orb.cc b/lib/c++/orb.cc index 852919b..31f5cf3 100644 --- a/lib/c++/orb.cc +++ b/lib/c++/orb.cc @@ -30,15 +30,15 @@ namespace RunTime { // 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; } -- 2.39.2