--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -133,38 +133,16 @@ def _actorState(actor):
return ExprSelect(actor, '->', 'mState')
def _backstagePass():
return ExprCall(ExprVar('mozilla::ipc::PrivateIPDLInterface'))
def _iterType(ptr):
return Type('PickleIterator', ptr=ptr)
-def _nullState(proto=None):
- pfx = ''
- if proto is not None: pfx = proto.name() +'::'
- return ExprVar(pfx +'__Null')
-
-def _deadState(proto=None):
- pfx = ''
- if proto is not None: pfx = proto.name() +'::'
- return ExprVar(pfx +'__Dead')
-
-def _dyingState(proto=None):
- pfx = ''
- if proto is not None: pfx = proto.name() +'::'
- return ExprVar(pfx +'__Dying')
-
-def _startState(proto=None, fq=False):
- pfx = ''
- if proto:
- if fq: pfx = proto.fullname() +'::'
- else: pfx = proto.name() +'::'
- return ExprVar(pfx +'__Start')
-
def _deleteId():
return ExprVar('Msg___delete____ID')
def _deleteReplyId():
return ExprVar('Reply___delete____ID')
def _lookupListener(idexpr):
return ExprCall(ExprVar('Lookup'), args=[ idexpr ])
@@ -1072,16 +1050,27 @@ def _subtreeUsesShmem(p):
ptype = p.decl.type
for mgd in ptype.manages:
if ptype is not mgd:
if _subtreeUsesShmem(mgd._ast):
return True
return False
+def _stateType(hasReentrantDelete):
+ if hasReentrantDelete:
+ return Type('mozilla::ipc::ReEntrantDeleteState')
+ else:
+ return Type('mozilla::ipc::State')
+
+def _startState(hasReentrantDelete):
+ pfx = _stateType(hasReentrantDelete).name + '::'
+ return ExprVar(pfx + 'Start')
+
+
class Protocol(ipdl.ast.Protocol):
def cxxTypedefs(self):
return self.decl.cxxtypedefs
def channelSel(self):
if self.decl.type.isToplevel(): return '.'
return '->'
@@ -1192,26 +1181,33 @@ class Protocol(ipdl.ast.Protocol):
return ExprCall(ExprVar('Id'))
def stateVar(self, actorThis=None):
if actorThis is not None:
return ExprSelect(actorThis, '->', 'mState')
return ExprVar('mState')
def fqStateType(self):
- return Type(self.decl.type.name() +'::State')
+ return _stateType(self.decl.type.hasReentrantDelete)
def startState(self):
- return _startState(self.decl.type)
+ return _startState(self.decl.type.hasReentrantDelete)
def nullState(self):
- return _nullState(self.decl.type)
+ pfx = self.fqStateType().name + '::'
+ return ExprVar(pfx + 'Null')
def deadState(self):
- return _deadState(self.decl.type)
+ pfx = self.fqStateType().name + '::'
+ return ExprVar(pfx + 'Dead')
+
+ def dyingState(self):
+ assert self.decl.type.hasReentrantDelete
+ pfx = self.fqStateType().name + '::'
+ return ExprVar(pfx + 'Dying')
def managerVar(self, thisexpr=None):
assert thisexpr is not None or not self.decl.type.isToplevel()
mvar = ExprCall(ExprVar('Manager'), args=[])
if thisexpr is not None:
mvar = ExprCall(ExprSelect(thisexpr, '->', 'Manager'), args=[])
return mvar
@@ -1565,28 +1561,16 @@ class _GenerateProtocolCode(ipdl.ast.Vis
ns = Namespace(self.protocol.name)
self.hdrfile.addthing(_putInNamespaces(ns, p.namespaces))
ns.addstmt(Whitespace.NL)
edecl, edefn = _splitFuncDeclDefn(self.genEndpointFunc())
ns.addstmts([ edecl, Whitespace.NL ])
self.funcDefns.append(edefn)
- # state information
- stateenum = TypeEnum('State')
- # NB: __Dead is the first state on purpose, so that it has
- # value '0'
- stateenum.addId(_deadState().name)
- stateenum.addId(_nullState().name)
- if self.protocol.decl.type.hasReentrantDelete:
- stateenum.addId(_dyingState().name)
- stateenum.addId(_startState().name, _nullState().name)
-
- ns.addstmts([ StmtDecl(Decl(stateenum,'')), Whitespace.NL ])
-
# spit out message type enum and classes
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)
@@ -1651,51 +1635,51 @@ class _GenerateProtocolCode(ipdl.ast.Vis
# bool Transition(MessageType msg, State* next)
# The state we are transitioning from is stored in *next.
msgtypevar = ExprVar('msg')
nextvar = ExprVar('next')
transitionfunc = FunctionDefn(FunctionDecl(
'Transition',
params=[ Decl(Type('MessageType'), msgtypevar.name),
- Decl(Type('State', ptr=1), nextvar.name) ],
+ Decl(Type(self.protocol.fqStateType().name, ptr=1), nextvar.name) ],
ret=Type.VOID))
fromswitch = StmtSwitch(ExprDeref(nextvar))
# special case for Null
nullerrorblock = Block()
if ptype.hasDelete:
ifdelete = StmtIf(ExprBinary(_deleteId(), '==', msgtypevar))
if ptype.hasReentrantDelete:
- nextState = _dyingState()
+ nextState = self.protocol.dyingState()
else:
- nextState = _deadState()
+ nextState = self.protocol.deadState()
ifdelete.addifstmt(
StmtExpr(ExprAssn(ExprDeref(nextvar), nextState)))
nullerrorblock.addstmt(ifdelete)
nullerrorblock.addstmt(StmtBreak())
- fromswitch.addcase(CaseLabel(_nullState().name), nullerrorblock)
+ fromswitch.addcase(CaseLabel(self.protocol.nullState().name), nullerrorblock)
# special case for Dead
deadblock = Block()
deadblock.addstmts([
_logicError('__delete__()d actor'),
StmtBreak() ])
- fromswitch.addcase(CaseLabel(_deadState().name), deadblock)
+ fromswitch.addcase(CaseLabel(self.protocol.deadState().name), deadblock)
# special case for Dying
if ptype.hasReentrantDelete:
dyingblock = Block()
ifdelete = StmtIf(ExprBinary(_deleteReplyId(), '==', msgtypevar))
ifdelete.addifstmt(
- StmtExpr(ExprAssn(ExprDeref(nextvar), _deadState())))
+ StmtExpr(ExprAssn(ExprDeref(nextvar), self.protocol.deadState())))
dyingblock.addstmt(ifdelete)
dyingblock.addstmt(StmtBreak())
- fromswitch.addcase(CaseLabel(_dyingState().name), dyingblock)
+ fromswitch.addcase(CaseLabel(self.protocol.dyingState().name), dyingblock)
unreachedblock = Block()
unreachedblock.addstmts([
_logicError('corrupted actor state'),
StmtBreak() ])
fromswitch.addcase(DefaultLabel(), unreachedblock)
transitionfunc.addstmt(fromswitch)
@@ -3056,16 +3040,19 @@ class _GenerateProtocolActorCode(ipdl.as
# FIXME: all actors impl Iface for now
if ptype.isManager() or 1:
self.hdrfile.addthing(CppDirective('include', '"base/id_map.h"'))
self.hdrfile.addthings([
CppDirective('include', '"mozilla/ipc/MessageChannel.h"'),
Whitespace.NL ])
+ self.hdrfile.addthings([
+ CppDirective('include', '"mozilla/ipc/ProtocolUtils.h"'),
+ Whitespace.NL ])
hasAsyncReturns = False
for md in p.messageDecls:
if md.hasAsyncReturns():
hasAsyncReturns = True
break
inherits = []
@@ -3122,18 +3109,16 @@ class _GenerateProtocolActorCode(ipdl.as
self.cls.addstmt(Label.PROTECTED)
for typedef in p.cxxTypedefs():
self.cls.addstmt(typedef)
for typedef in self.includedActorTypedefs:
self.cls.addstmt(typedef)
self.cls.addstmt(Whitespace.NL)
- self.cls.addstmts([ Typedef(p.fqStateType(), 'State'), Whitespace.NL ])
-
if hasAsyncReturns:
self.cls.addstmt(Label.PUBLIC)
for md in p.messageDecls:
if self.sendsMessage(md) and md.hasAsyncReturns():
self.cls.addstmt(
Typedef(_makePromise(md.returns, self.side),
md.promiseName()))
if self.receivesMessage(md) and md.hasAsyncReturns():
@@ -3395,17 +3380,17 @@ class _GenerateProtocolActorCode(ipdl.as
method.addstmts([ routedecl, routeif, Whitespace.NL ])
# in the event of an Interrupt delete message, we want to loudly complain about
# messages that are received that are not a reply to the original message
if ptype.hasReentrantDelete:
msgVar = ExprVar(params[0].name)
ifdying = StmtIf(ExprBinary(
- ExprBinary(ExprVar('mState'), '==', _dyingState(ptype)),
+ ExprBinary(ExprVar('mState'), '==', self.protocol.dyingState()),
'&&',
ExprBinary(
ExprBinary(ExprCall(ExprSelect(msgVar, '.', 'is_reply')), '!=', ExprLiteral.TRUE),
'||',
ExprBinary(ExprCall(ExprSelect(msgVar, '.', 'is_interrupt')), '!=', ExprLiteral.TRUE))))
ifdying.addifstmts([_fatalError('incoming message racing with actor deletion'),
StmtReturn(_Result.Processed)])
method.addstmt(ifdying)
@@ -3614,17 +3599,17 @@ class _GenerateProtocolActorCode(ipdl.as
# we're toplevel
self.cls.addstmts([ deallocsubtree, Whitespace.NL ])
if ptype.isToplevel():
deallocself = MethodDefn(MethodDecl(deallocselfvar.name, methodspec=MethodSpec.VIRTUAL))
self.cls.addstmts([ deallocself, Whitespace.NL ])
## private members
- self.cls.addstmt(StmtDecl(Decl(Type('State'), p.stateVar().name)))
+ self.cls.addstmt(StmtDecl(Decl(self.protocol.fqStateType(), p.stateVar().name)))
for managed in ptype.manages:
self.cls.addstmts([
StmtDecl(Decl(
p.managedVarType(managed, self.side),
p.managedVar(managed, self.side).name)) ])
def implementManagerIface(self):
@@ -3897,17 +3882,17 @@ class _GenerateProtocolActorCode(ipdl.as
return [
self.failIfNullActor(actorvar, errfn, msg="Error constructing actor %s" % actortype.name() + self.side.capitalize()),
StmtExpr(setmanager),
StmtExpr(_callInsertManagedActor(
self.protocol.managedVar(md.decl.type.constructedType(),
self.side),
actorvar)),
StmtExpr(ExprAssn(_actorState(actorvar),
- _startState(actorproto, fq=1)))
+ _startState(md.decl.type.cdtype.hasReentrantDelete)))
]
def failCtorIf(self, md, cond):
actorvar = md.actorDecl().var()
type = md.decl.type.constructedType()
failif = StmtIf(cond)
if self.side=='child':