Bug 636063, part 1: Frontend support for |compress|d messages. r=bent
authorChris Jones <jones.chris.g@gmail.com>
Sat, 25 Aug 2012 01:25:08 -0700
changeset 105448 d47636be8facc7f0ab6ef011b38911c6af050eb2
parent 105415 54fdedb218f858cda41f4c45d91dc8ee46d998e5
child 105449 ff3e4559bfa3ef05eafe613cffb505df920fba20
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbent
bugs636063
milestone17.0a1
Bug 636063, part 1: Frontend support for |compress|d messages. r=bent
ipc/ipdl/ipdl/ast.py
ipc/ipdl/ipdl/parser.py
ipc/ipdl/ipdl/type.py
ipc/ipdl/test/ipdl/error/compressCtor.ipdl
ipc/ipdl/test/ipdl/error/compressCtorManagee.ipdl
ipc/ipdl/test/ipdl/error/rpcMessageCompress.ipdl
ipc/ipdl/test/ipdl/error/syncMessageCompress.ipdl
ipc/ipdl/test/ipdl/ok/messageCompress.ipdl
--- a/ipc/ipdl/ipdl/ast.py
+++ b/ipc/ipdl/ipdl/ast.py
@@ -310,16 +310,17 @@ class ManagesStmt(Node):
 class MessageDecl(Node):
     def __init__(self, loc):
         Node.__init__(self, loc)
         self.name = None
         self.sendSemantics = ASYNC
         self.direction = None
         self.inParams = [ ]
         self.outParams = [ ]
+        self.compress = ''
 
     def addInParams(self, inParamsList):
         self.inParams += inParamsList
 
     def addOutParams(self, outParamsList):
         self.outParams += outParamsList
 
     def hasReply(self):
--- a/ipc/ipdl/ipdl/parser.py
+++ b/ipc/ipdl/ipdl/parser.py
@@ -116,16 +116,17 @@ def locFromTok(p, num):
 reserved = set((
         'answer',
         'as',
         'async',
         'both',
         'bridges',
         'call',
         'child',
+        'compress',
         '__delete__',
         'delete',                       # reserve 'delete' to prevent its use
         'goto',
         'include',
         'manager',
         'manages',
         'namespace',
         'nullable',
@@ -479,23 +480,25 @@ def p_MessageDecl(p):
 
     if Parser.current.direction is None:
         _error(msg.loc, 'missing message direction')
     msg.direction = Parser.current.direction
 
     p[0] = msg
 
 def p_MessageBody(p):
-    """MessageBody : MessageId MessageInParams MessageOutParams"""
+    """MessageBody : MessageId MessageInParams MessageOutParams OptionalMessageCompress"""
     # FIXME/cjones: need better loc info: use one of the quals
     loc, name = p[1]
     msg = MessageDecl(loc)
     msg.name = name
     msg.addInParams(p[2])
     msg.addOutParams(p[3])
+    msg.compress = p[4]
+
     p[0] = msg
 
 def p_MessageId(p):
     """MessageId : ID
                  | __DELETE__
                  | DELETE
                  | '~' ID"""
     loc = locFromTok(p, 1)
@@ -512,16 +515,24 @@ def p_MessageInParams(p):
 def p_MessageOutParams(p):
     """MessageOutParams : RETURNS '(' ParamList ')'
                         | """
     if 1 == len(p):
         p[0] = [ ]
     else:
         p[0] = p[3]
 
+def p_OptionalMessageCompress(p):
+    """OptionalMessageCompress : COMPRESS
+                               | """
+    if 1 == len(p):
+        p[0] = ''
+    else:
+        p[0] = 'compress'
+
 ##--------------------
 ## State machine
 
 def p_TransitionStmtsOpt(p):
     """TransitionStmtsOpt : TransitionStmt TransitionStmtsOpt
                           |"""
     if 1 == len(p):
         # we fill in |loc| in the Protocol rule
--- a/ipc/ipdl/ipdl/type.py
+++ b/ipc/ipdl/ipdl/type.py
@@ -223,27 +223,28 @@ class StateType(IPDLType):
     def isState(self): return True
     def name(self):
         return self.name
     def fullname(self):
         return self.name()
 
 class MessageType(IPDLType):
     def __init__(self, sendSemantics, direction,
-                 ctor=False, dtor=False, cdtype=None):
+                 ctor=False, dtor=False, cdtype=None, compress=False):
         assert not (ctor and dtor)
         assert not (ctor or dtor) or type is not None
 
         self.sendSemantics = sendSemantics
         self.direction = direction
         self.params = [ ]
         self.returns = [ ]
         self.ctor = ctor
         self.dtor = dtor
         self.cdtype = cdtype
+        self.compress = compress
     def isMessage(self): return True
 
     def isCtor(self): return self.ctor
     def isDtor(self): return self.dtor
     def constructedType(self):  return self.cdtype
 
     def isIn(self): return self.direction is IN
     def isOut(self): return self.direction is OUT
@@ -1063,17 +1064,18 @@ class GatherDecls(TcheckVisitor):
             isdtor = True
             cdtype = self.currentProtocolDecl.type
 
 
         # enter message scope
         self.symtab.enterScope(md)
 
         msgtype = MessageType(md.sendSemantics, md.direction,
-                              ctor=isctor, dtor=isdtor, cdtype=cdtype)
+                              ctor=isctor, dtor=isdtor, cdtype=cdtype,
+                              compress=(md.compress == 'compress'))
 
         # replace inparam Param nodes with proper Decls
         def paramToDecl(param):
             ptname = param.typespec.basename()
             ploc = param.typespec.loc
 
             ptdecl = self.symtab.lookup(ptname)
             if ptdecl is None:
@@ -1453,16 +1455,23 @@ class CheckTypes(TcheckVisitor):
                 mname, pname)
 
         if mtype.isAsync() and len(mtype.returns):
             # XXX/cjones could modify grammar to disallow this ...
             self.error(loc,
                        "asynchronous message `%s' declares return values",
                        mname)
 
+        if (mtype.compress and
+            (not mtype.isAsync() or mtype.isCtor() or mtype.isDtor())):
+            self.error(
+                loc,
+                "message `%s' in protocol `%s' requests compression but is not async or is special (ctor or dtor)",
+                mname[:-len('constructor')], pname)
+
         if mtype.isCtor() and not ptype.isManagerOf(mtype.constructedType()):
             self.error(
                 loc,
                 "ctor for protocol `%s', which is not managed by protocol `%s'", 
                 mname[:-len('constructor')], pname)
 
 
     def visitTransition(self, t):
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/error/compressCtor.ipdl
@@ -0,0 +1,8 @@
+include protocol compressCtorManagee;
+
+rpc protocol compressCtor {
+    manages compressCtorManagee;
+
+parent:
+    async compressCtorManagee() compress;
+};
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/error/compressCtorManagee.ipdl
@@ -0,0 +1,8 @@
+include protocol compressCtor;
+
+rpc protocol compressCtorManagee {
+    manager compressCtor;
+
+child:
+    async __delete__() compress;
+};
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/error/rpcMessageCompress.ipdl
@@ -0,0 +1,6 @@
+rpc protocol rpcMessageCompress {
+parent:
+    rpc foo() compress;
+child:
+    rpc bar() compress;
+};
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/error/syncMessageCompress.ipdl
@@ -0,0 +1,4 @@
+sync protocol syncMessageCompress {
+parent:
+    sync foo() compress;
+};
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/ok/messageCompress.ipdl
@@ -0,0 +1,4 @@
+rpc protocol messageCompress {
+child:
+    async foo() compress;
+};