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 103415 d47636be8facc7f0ab6ef011b38911c6af050eb2
parent 103382 54fdedb218f858cda41f4c45d91dc8ee46d998e5
child 103416 ff3e4559bfa3ef05eafe613cffb505df920fba20
push id23348
push userryanvm@gmail.com
push dateSun, 26 Aug 2012 02:09:16 +0000
treeherdermozilla-central@b3cce81fef1a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs636063
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;
+};