Bug 570099: Allow Shmems to be used in IPDL structs. r=benjamn
authorChris Jones <jones.chris.g@gmail.com>
Wed, 23 Jun 2010 13:59:07 -0500
changeset 44201 b6064d9b85b3bc3c66af6ce058e195972594353b
parent 44200 b149725f51da976770d7a344b1e09c5f3d08125d
child 44202 0fe7c3b4c0e5a96bbd704cefb831364d633cc0e6
push idunknown
push userunknown
push dateunknown
reviewersbenjamn
bugs570099
milestone1.9.3a6pre
Bug 570099: Allow Shmems to be used in IPDL structs. r=benjamn
ipc/glue/Shmem.h
ipc/ipdl/ipdl/lower.py
ipc/ipdl/test/cxx/PTestDataStructures.ipdl
--- a/ipc/glue/Shmem.h
+++ b/ipc/glue/Shmem.h
@@ -140,16 +140,27 @@ public:
   {
     mSegment = aRhs.mSegment;
     mData = aRhs.mData;
     mSize = aRhs.mSize;
     mId = aRhs.mId;
     return *this;
   }
 
+  bool operator==(const Shmem& aRhs) const
+  {
+    // need to compare IDs because of AdoptShmem(); two Shmems might
+    // refer to the same segment but with different IDs for different
+    // protocol trees.  (NB: it's possible for this method to
+    // spuriously return true if AdoptShmem() gives the same ID for
+    // two protocol trees, but I don't think that can cause any
+    // problems since the Shmems really would be indistinguishable.)
+    return mSegment == aRhs.mSegment && mId == aRhs.mId;
+  }
+
   // Returns whether this Shmem is writable by you, and thus whether you can
   // transfer writability to another actor.
   bool
   IsWritable() const
   {
     return mSegment != NULL;
   }
 
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -600,16 +600,23 @@ class _StructField(_CompoundTypeComponen
     def refExpr(self, thisexpr=None):
         ref = self.memberVar()
         if thisexpr is not None:
             ref = ExprSelect(thisexpr, '.', ref.name)
         if self.recursive:
             ref = ExprDeref(ref)
         return ref
 
+    def constRefExpr(self, thisexpr=None):
+        # sigh, gross hack
+        refexpr = self.refExpr(thisexpr)
+        if 'Shmem' == self.ipdltype.name():
+            refexpr = ExprCast(refexpr, Type('Shmem', ref=1), const=1)
+        return refexpr
+
     def argVar(self):
         return ExprVar('_'+ self.name)
 
     def memberVar(self):
         return ExprVar(self.name + '_')
 
     def initStmts(self):
         if self.recursive:
@@ -1483,16 +1490,22 @@ stmt.  Some types generate both kinds.''
         return self.visitStructOrUnionType(t, TypeVisitor.visitStructType)
 
     def visitUnionType(self, t):
         return self.visitStructOrUnionType(t, TypeVisitor.visitUnionType)
 
     def visitArrayType(self, t):
         return TypeVisitor.visitArrayType(self, t)
 
+    def visitShmemType(self, s):
+        if s in self.visited: return
+        self.visited.add(s)
+        self.usingTypedefs.append(Typedef(Type('mozilla::ipc::Shmem'),
+                                          'Shmem'))
+
     def visitVoidType(self, v): assert 0
     def visitMessageType(self, v): assert 0
     def visitProtocolType(self, v): assert 0
     def visitStateType(self, v): assert 0
 
 
 def _generateCxxStruct(sd):
     ''' '''
@@ -1582,19 +1595,21 @@ def _generateCxxStruct(sd):
     # const field1& f1() const
     for f in sd.fields:
         get = MethodDefn(MethodDecl(f.getMethod().name,
                                     params=[ ],
                                     ret=f.refType(),
                                     force_inline=1))
         get.addstmt(StmtReturn(f.refExpr()))
 
-        getconst = deepcopy(get)
-        getconst.decl.ret = f.constRefType()
-        getconst.decl.const = 1
+        getconstdecl = deepcopy(get.decl)
+        getconstdecl.ret = f.constRefType()
+        getconstdecl.const = 1
+        getconst = MethodDefn(getconstdecl)
+        getconst.addstmt(StmtReturn(f.constRefExpr()))
 
         struct.addstmts([ get, getconst, Whitespace.NL ])
 
     # private:
     struct.addstmt(Label.PRIVATE)
 
     # Init()
     init = MethodDefn(MethodDecl(initvar.name))
--- a/ipc/ipdl/test/cxx/PTestDataStructures.ipdl
+++ b/ipc/ipdl/test/cxx/PTestDataStructures.ipdl
@@ -82,16 +82,21 @@ struct Attrs {
     SpecificAttrs specific;
 };
 struct SetAttrs {
     PTestDataStructuresSub x;
     Attrs attrs;
 };
 union Op { null_t; SetAttrs; };
 
+struct ShmemStruct {
+    int i;
+    Shmem mem;
+};
+
 } // namespace _foo
 } // namespace mozilla
 
 namespace mozilla {
 namespace _ipdltest {
 
 sync protocol PTestDataStructures {
     manages PTestDataStructuresSub;