Bug 1309799 - Generate StringFromIPCMessageType and use it in MessageChannel::MaybeHandleError. r?billm
MozReview-Commit-ID: HSuAAM0JdjS
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -2033,17 +2033,17 @@ MessageChannel::MaybeHandleError(Result
default:
NS_RUNTIMEABORT("unknown Result code");
return false;
}
char reason[512];
SprintfLiteral(reason,"(msgtype=0x%X,name=%s) %s",
- aMsg.type(), aMsg.name(), errorMsg);
+ aMsg.type(), StringFromIPCMessageType(aMsg.type()), errorMsg);
PrintErrorMessage(mSide, channelName, reason);
mListener->OnProcessingError(code, reason);
return false;
}
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -259,25 +259,25 @@ AnnotateCrashReportWithErrno(const char*
nsCString(tag),
nsPrintfCString("%d", error));
}
#endif
void
LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
const char* aContextDescription,
- const char* aMessageDescription,
+ uint32_t aMessageId,
MessageDirection aDirection)
{
nsPrintfCString logMessage("[time: %" PRId64 "][%d%s%d] [%s] %s %s\n",
PR_Now(), base::GetCurrentProcId(),
aDirection == MessageDirection::eReceiving ? "<-" : "->",
aOtherPid, aTopLevelProtocol,
aContextDescription,
- aMessageDescription);
+ StringFromIPCMessageType(aMessageId));
#ifdef ANDROID
__android_log_write(ANDROID_LOG_INFO, "GeckoIPC", logMessage.get());
#endif
fputs(logMessage.get(), stderr);
}
void
ProtocolErrorBreakpoint(const char* aMsg)
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -294,17 +294,17 @@ LoggingEnabledFor(const char *aTopLevelP
enum class MessageDirection {
eSending,
eReceiving,
};
MOZ_NEVER_INLINE void
LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
const char* aContextDescription,
- const char* aMessageDescription,
+ uint32_t aMessageId,
MessageDirection aDirection);
MOZ_NEVER_INLINE void
ProtocolErrorBreakpoint(const char* aMsg);
// The code generator calls this function for errors which come from the
// methods of protocols. Doing this saves codesize by making the error
// cases significantly smaller.
@@ -565,16 +565,18 @@ CreateEndpoints(const PrivateIPDLInterfa
return NS_OK;
}
void
TableToArray(const nsTHashtable<nsPtrHashKey<void>>& aTable,
nsTArray<void*>& aArray);
+const char* StringFromIPCMessageType(uint32_t aMessageType);
+
} // namespace ipc
template<typename Protocol>
class ManagedContainer : public nsTHashtable<nsPtrHashKey<Protocol>>
{
typedef nsTHashtable<nsPtrHashKey<Protocol>> BaseClass;
public:
--- a/ipc/ipdl/ipdl.py
+++ b/ipc/ipdl/ipdl.py
@@ -41,16 +41,17 @@ options, files = op.parse_args()
headersdir = options.headersdir
cppdir = options.cppdir
includedirs = [ os.path.abspath(incdir) for incdir in options.includedirs ]
if not len(files):
op.error("No IPDL files specified")
ipcmessagestartpath = os.path.join(headersdir, 'IPCMessageStart.h')
+ipc_msgtype_name_path = os.path.join(cppdir, 'IPCMessageTypeName.cpp')
# Compiling the IPDL files can take a long time, even on a fast machine.
# Check to see whether we need to do any work.
latestipdlmod = max(os.stat(f).st_mtime
for f in itertools.chain(files,
iter_modules_in_path(mozpath.dirname(__file__))))
def outputModTime(f):
@@ -99,16 +100,17 @@ def alloutputfiles():
earliestoutputmod = min(outputModTime(f) for f in alloutputfiles())
if latestipdlmod < earliestoutputmod:
sys.exit(0)
log(2, 'Generated C++ headers will be generated relative to "%s"', headersdir)
log(2, 'Generated C++ sources will be generated in "%s"', cppdir)
+allmessages = {}
allprotocols = []
def normalizedFilename(f):
if f == '-':
return '<stdin>'
return f
# First pass: parse and type-check all protocols
@@ -138,21 +140,21 @@ for f in files:
ipdl.genipdl(ast, codedir)
# Second pass: generate code
for f in files:
# Read from parser cache
filename = normalizedFilename(f)
ast = ipdl.parse(None, filename, includedirs=includedirs)
ipdl.gencxx(filename, ast, headersdir, cppdir)
-
+
if ast.protocol:
+ allmessages[ast.protocol.name] = ipdl.genmsgenum(ast)
allprotocols.append('%sMsgStart' % ast.protocol.name)
-
allprotocols.sort()
ipcmsgstart = StringIO()
print >>ipcmsgstart, """
// CODE GENERATED by ipdl.py. Do not edit.
#ifndef IPCMessageStart_h
@@ -169,9 +171,62 @@ print >>ipcmsgstart, """
LastMsgIndex
};
static_assert(LastMsgIndex <= 65536, "need to update IPC_MESSAGE_MACRO");
#endif // ifndef IPCMessageStart_h
"""
+ipc_msgtype_name = StringIO()
+print >>ipc_msgtype_name, """
+// CODE GENERATED by ipdl.py. Do not edit.
+#include <cstdint>
+
+#include "IPCMessageStart.h"
+
+using std::uint32_t;
+
+namespace {
+
+enum IPCMessages {
+"""
+
+for protocol in sorted(allmessages.keys()):
+ for (msg, num) in allmessages[protocol].idnums:
+ if num:
+ print >>ipc_msgtype_name, " %s = %s," % (msg, num)
+ elif not msg.endswith('End'):
+ print >>ipc_msgtype_name, " %s__%s," % (protocol, msg)
+
+print >>ipc_msgtype_name, """
+};
+
+} // anonymous namespace
+
+namespace mozilla {
+namespace ipc {
+
+const char* StringFromIPCMessageType(uint32_t aMessageType)
+{
+ switch (aMessageType) {
+"""
+
+for protocol in sorted(allmessages.keys()):
+ for (msg, num) in allmessages[protocol].idnums:
+ if num or msg.endswith('End'):
+ continue
+ print >>ipc_msgtype_name, """
+ case %s__%s:
+ return "%s::%s";""" % (protocol, msg, protocol, msg)
+
+print >>ipc_msgtype_name, """
+ default:
+ return "???";
+ }
+}
+
+} // namespace ipc
+} // namespace mozilla
+"""
+
ipdl.writeifmodified(ipcmsgstart.getvalue(), ipcmessagestartpath)
+ipdl.writeifmodified(ipc_msgtype_name.getvalue(), ipc_msgtype_name_path)
--- a/ipc/ipdl/ipdl/__init__.py
+++ b/ipc/ipdl/ipdl/__init__.py
@@ -3,17 +3,17 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified' ]
import os, sys
from cStringIO import StringIO
from ipdl.cgen import IPDLCodeGen
-from ipdl.lower import LowerToCxx
+from ipdl.lower import LowerToCxx, msgenums
from ipdl.parser import Parser
from ipdl.type import TypeCheck
from ipdl.cxx.cgen import CxxCodeGen
def parse(specstring, filename='/stdin', includedirs=[ ], errout=sys.stderr):
'''Return an IPDL AST if parsing was successful. Print errors to |errout|
@@ -54,16 +54,19 @@ def gencxx(ipdlfilename, ast, outheaders
CxxCodeGen(tempfile).cgen(ast)
writeifmodified(tempfile.getvalue(), filename)
def genipdl(ast, outdir):
return IPDLCodeGen().cgen(ast)
+def genmsgenum(ast):
+ return msgenums(ast.protocol, pretty=True)
+
def writeifmodified(contents, file):
dir = os.path.dirname(file)
os.path.exists(dir) or os.makedirs(dir)
oldcontents = None
if os.path.exists(file):
fd = open(file, 'rb')
oldcontents = fd.read()
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1460,16 +1460,29 @@ with some new IPDL/C++ nodes that are tu
def visitTransitionStmt(self, ts):
name = ts.state.decl.progname
ts.state.decl.cxxname = name
ts.state.decl.cxxenum = ExprVar(self.protocolName +'::'+ name)
##-----------------------------------------------------------------------------
+def msgenums(protocol, pretty=False):
+ msgenum = TypeEnum('MessageType')
+ msgstart = _messageStartName(protocol.decl.type) +' << 16'
+ msgenum.addId(protocol.name + 'Start', msgstart)
+
+ for md in protocol.messageDecls:
+ msgenum.addId(md.prettyMsgName() if pretty else md.msgId())
+ if md.hasReply():
+ msgenum.addId(md.prettyReplyName() if pretty else md.replyId())
+
+ msgenum.addId(protocol.name +'End')
+ return msgenum
+
class _GenerateProtocolCode(ipdl.ast.Visitor):
'''Creates code common to both the parent and child actors.'''
def __init__(self):
self.protocol = None # protocol we're generating a class for
self.hdrfile = None # what will become Protocol.h
self.cppfile = None # what will become Protocol.cpp
self.cppIncludeHeaders = []
self.structUnionDefns = []
@@ -1658,27 +1671,17 @@ class _GenerateProtocolCode(ipdl.ast.Vis
startstate = p.transitionStmts[0].state.decl.cxxname
else:
startstate = _nullState().name
stateenum.addId(_startState().name, startstate)
ns.addstmts([ StmtDecl(Decl(stateenum,'')), Whitespace.NL ])
# spit out message type enum and classes
- msgenum = TypeEnum('MessageType')
- msgstart = _messageStartName(self.protocol.decl.type) +' << 16'
- msgenum.addId(self.protocol.name + 'Start', msgstart)
- #msgenum.addId(self.protocol.name +'PreStart', '('+ msgstart +') - 1')
-
- for md in p.messageDecls:
- msgenum.addId(md.msgId())
- if md.hasReply():
- msgenum.addId(md.replyId())
-
- msgenum.addId(self.protocol.name +'End')
+ msgenum = msgenums(self.protocol)
ns.addstmts([ StmtDecl(Decl(msgenum, '')), Whitespace.NL ])
tfDecl, tfDefn = _splitFuncDeclDefn(self.genTransitionFunc())
ns.addstmts([ tfDecl, Whitespace.NL ])
self.funcDefns.append(tfDefn)
for md in p.messageDecls:
decls = []
@@ -5190,25 +5193,16 @@ class _GenerateProtocolActorCode(ipdl.as
def deserializeMessage(self, md, side, errfn):
msgvar = self.msgvar
itervar = self.itervar
msgexpr = ExprAddrOf(msgvar)
isctor = md.decl.type.isCtor()
stmts = ([
- # this is kind of naughty, but the only two other options
- # are forwarding the message name (yuck) or making the
- # IPDL|*Channel abstraction leak more
- StmtExpr(ExprCall(
- ExprSelect(
- ExprCast(msgvar, Type('Message', ref=1), const=1),
- '.', 'set_name'),
- args=[ ExprLiteral.String(md.prettyMsgName(self.protocol.name
- +'::')) ])),
self.logMessage(md, msgexpr, 'Received ',
receiving=True),
self.profilerLabel('Recv', md.decl.progname),
Whitespace.NL
])
if 0 == len(md.params):
return stmts
@@ -5361,17 +5355,17 @@ class _GenerateProtocolActorCode(ipdl.as
actorname = _actorName(self.protocol.name, self.side)
return _ifLogging(ExprLiteral.String(actorname),
[ StmtExpr(ExprCall(
ExprVar('mozilla::ipc::LogMessageForProtocol'),
args=[ ExprLiteral.String(actorname),
self.protocol.callOtherPid(actor),
ExprLiteral.String(pfx),
- ExprCall(ExprSelect(msgptr, '->', 'name')),
+ ExprCall(ExprSelect(msgptr, '->', 'type')),
ExprVar('mozilla::ipc::MessageDirection::eReceiving'
if receiving
else 'mozilla::ipc::MessageDirection::eSending') ])) ])
def profilerLabel(self, tag, msgname):
return StmtExpr(ExprCall(ExprVar('PROFILER_LABEL'),
[ ExprLiteral.String('IPDL::' + self.protocol.name),
ExprLiteral.String(tag + msgname),
--- a/ipc/ipdl/moz.build
+++ b/ipc/ipdl/moz.build
@@ -4,13 +4,16 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG['MOZ_IPDL_TESTS']:
DIRS += ['test']
include('/ipc/chromium/chromium-config.mozbuild')
+# Generated by ipdl.py
+SOURCES += ['!IPCMessageTypeName.cpp']
+
FINAL_LIBRARY = 'xul'
# We #include some things in the dom/plugins/ directory that rely on
# toolkit libraries.
CXXFLAGS += CONFIG['TK_CFLAGS']