зеркало из https://github.com/mozilla/gecko-dev.git
Bug 540111, part 3: Allow IPDL actors to be managed by one of a set of possible managers. r=bent
This commit is contained in:
Родитель
eefb2c4602
Коммит
d30cfaf796
|
@ -66,8 +66,8 @@ class Visitor:
|
|||
def visitProtocol(self, p):
|
||||
for namespace in p.namespaces:
|
||||
namespace.accept(self)
|
||||
if p.manager is not None:
|
||||
p.manager.accept(self)
|
||||
for mgr in p.managers:
|
||||
mgr.accept(self)
|
||||
for managed in p.managesStmts:
|
||||
managed.accept(self)
|
||||
for msgDecl in p.messageDecls:
|
||||
|
@ -78,7 +78,7 @@ class Visitor:
|
|||
def visitNamespace(self, ns):
|
||||
pass
|
||||
|
||||
def visitManagerStmt(self, mgr):
|
||||
def visitManager(self, mgr):
|
||||
pass
|
||||
|
||||
def visitManagesStmt(self, mgs):
|
||||
|
@ -249,6 +249,7 @@ class Protocol(NamespacedNode):
|
|||
def __init__(self, loc):
|
||||
NamespacedNode.__init__(self, loc)
|
||||
self.sendSemantics = ASYNC
|
||||
self.managers = [ ]
|
||||
self.managesStmts = [ ]
|
||||
self.messageDecls = [ ]
|
||||
self.transitionStmts = [ ]
|
||||
|
@ -268,7 +269,7 @@ class UnionDecl(NamespacedNode):
|
|||
NamespacedNode.__init__(self, loc, name)
|
||||
self.components = components
|
||||
|
||||
class ManagerStmt(Node):
|
||||
class Manager(Node):
|
||||
def __init__(self, loc, managerName):
|
||||
Node.__init__(self, loc)
|
||||
self.name = managerName
|
||||
|
|
|
@ -1307,7 +1307,8 @@ class Protocol(ipdl.ast.Protocol):
|
|||
T=Type(self.fqListenerName()))
|
||||
|
||||
def _ipdlmgrtype(self):
|
||||
return self.decl.type.manager
|
||||
assert 1 == len(self.decl.type.managers)
|
||||
for mgr in self.decl.type.managers: return mgr
|
||||
|
||||
def managerActorType(self, side, ptr=0):
|
||||
return Type(_actorName(self._ipdlmgrtype().name(), side),
|
||||
|
@ -2552,7 +2553,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
|
||||
friends = _FindFriends().findFriends(p.decl.type)
|
||||
if p.decl.type.isManaged():
|
||||
friends.add(p.decl.type.manager)
|
||||
friends.update(p.decl.type.managers)
|
||||
|
||||
# |friend| managed actors so that they can call our Dealloc*()
|
||||
friends.update(p.decl.type.manages)
|
||||
|
@ -2697,13 +2698,15 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
self.cls.addstmts([ closemeth, Whitespace.NL ])
|
||||
|
||||
if not p.decl.type.isToplevel():
|
||||
## manager()
|
||||
managertype = p.managerActorType(self.side, ptr=1)
|
||||
managermeth = MethodDefn(MethodDecl(
|
||||
p.managerMethod().name, ret=managertype))
|
||||
managermeth.addstmt(StmtReturn(p.managerVar()))
|
||||
if 1 == len(p.managers):
|
||||
## manager()
|
||||
managertype = p.managerActorType(self.side, ptr=1)
|
||||
managermeth = MethodDefn(MethodDecl(
|
||||
p.managerMethod().name, ret=managertype))
|
||||
managermeth.addstmt(StmtReturn(
|
||||
ExprCast(p.managerVar(), managertype, static=1)))
|
||||
|
||||
self.cls.addstmts([ managermeth, Whitespace.NL ])
|
||||
self.cls.addstmts([ managermeth, Whitespace.NL ])
|
||||
|
||||
## managed[T]()
|
||||
for managed in p.decl.type.manages:
|
||||
|
@ -3015,7 +3018,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
elif p.decl.type.isManaged():
|
||||
self.cls.addstmts([
|
||||
StmtDecl(Decl(_actorIdType(), p.idVar().name)),
|
||||
StmtDecl(Decl(p.managerActorType(self.side, ptr=1),
|
||||
StmtDecl(Decl(p.managerInterfaceType(ptr=1),
|
||||
p.managerVar().name))
|
||||
])
|
||||
if p.usesShmem():
|
||||
|
|
|
@ -302,11 +302,11 @@ def p_ComponentTypes(p):
|
|||
p[0] = p[1]
|
||||
|
||||
def p_ProtocolDefn(p):
|
||||
"""ProtocolDefn : OptionalSendSemanticsQual PROTOCOL ID '{' ManagerStmtOpt ManagesStmts OptionalMessageDecls TransitionStmts '}' ';'"""
|
||||
"""ProtocolDefn : OptionalSendSemanticsQual PROTOCOL ID '{' ManagersStmtOpt ManagesStmts OptionalMessageDecls TransitionStmts '}' ';'"""
|
||||
protocol = Protocol(locFromTok(p, 2))
|
||||
protocol.name = p[3]
|
||||
protocol.sendSemantics = p[1]
|
||||
protocol.manager = p[5]
|
||||
protocol.managers = p[5]
|
||||
protocol.addManagesStmts(p[6])
|
||||
protocol.addMessageDecls(p[7])
|
||||
protocol.addTransitionStmts(p[8])
|
||||
|
@ -321,13 +321,22 @@ def p_ManagesStmts(p):
|
|||
p[1].append(p[2])
|
||||
p[0] = p[1]
|
||||
|
||||
def p_ManagerStmtOpt(p):
|
||||
"""ManagerStmtOpt : MANAGER ID ';'
|
||||
| """
|
||||
def p_ManagersStmtOpt(p):
|
||||
"""ManagersStmtOpt : MANAGER ManagerList ';'
|
||||
| """
|
||||
if 1 == len(p):
|
||||
p[0] = None
|
||||
p[0] = [ ]
|
||||
else:
|
||||
p[0] = ManagerStmt(locFromTok(p, 1), p[2])
|
||||
p[0] = p[2]
|
||||
|
||||
def p_ManagerList(p):
|
||||
"""ManagerList : ID
|
||||
| ManagerList OR ID"""
|
||||
if 2 == len(p):
|
||||
p[0] = [ Manager(locFromTok(p, 1), p[1]) ]
|
||||
else:
|
||||
p[1].append(Manager(locFromTok(p, 3), p[3]))
|
||||
p[0] = p[1]
|
||||
|
||||
def p_ManagesStmt(p):
|
||||
"""ManagesStmt : MANAGES ID ';'"""
|
||||
|
|
|
@ -237,7 +237,7 @@ class ProtocolType(IPDLType):
|
|||
def __init__(self, qname, sendSemantics, stateless=False):
|
||||
self.qname = qname
|
||||
self.sendSemantics = sendSemantics
|
||||
self.manager = None
|
||||
self.managers = set() # ProtocolType
|
||||
self.manages = [ ]
|
||||
self.stateless = stateless
|
||||
def isProtocol(self): return True
|
||||
|
@ -247,23 +247,31 @@ class ProtocolType(IPDLType):
|
|||
def fullname(self):
|
||||
return str(self.qname)
|
||||
|
||||
def addManager(self, mgrtype):
|
||||
assert mgrtype.isIPDL() and mgrtype.isProtocol()
|
||||
self.managers.add(mgrtype)
|
||||
|
||||
def managedBy(self, mgr):
|
||||
self.manager = mgr
|
||||
self.managers = mgr
|
||||
|
||||
def toplevel(self):
|
||||
if self.isToplevel():
|
||||
return self
|
||||
return self.manager.toplevel()
|
||||
for mgr in self.managers:
|
||||
return mgr.toplevel()
|
||||
|
||||
def isManagerOf(self, pt):
|
||||
for managed in self.manages:
|
||||
if pt is managed:
|
||||
return True
|
||||
return False
|
||||
def isManagedBy(self, pt):
|
||||
return pt in self.managers
|
||||
|
||||
def isManager(self):
|
||||
return len(self.manages) > 0
|
||||
def isManaged(self):
|
||||
return self.manager is not None
|
||||
return 0 < len(self.managers)
|
||||
def isToplevel(self):
|
||||
return not self.isManaged()
|
||||
|
||||
|
@ -596,15 +604,22 @@ class GatherDecls(TcheckVisitor):
|
|||
# protocol scope
|
||||
self.symtab.enterScope(p)
|
||||
|
||||
if p.manager is not None:
|
||||
p.manager.of = p
|
||||
p.manager.accept(self)
|
||||
seenmgrs = set()
|
||||
for mgr in p.managers:
|
||||
if mgr.name in seenmgrs:
|
||||
self.error(mgr.loc, "manager `%s' appears multiple times",
|
||||
mgr.name)
|
||||
continue
|
||||
|
||||
seenmgrs.add(mgr.name)
|
||||
mgr.of = p
|
||||
mgr.accept(self)
|
||||
|
||||
for managed in p.managesStmts:
|
||||
managed.manager = p
|
||||
managed.accept(self)
|
||||
|
||||
if p.manager is None and 0 == len(p.messageDecls):
|
||||
if 0 == len(p.managers) and 0 == len(p.messageDecls):
|
||||
self.error(p.loc,
|
||||
"top-level protocol `%s' cannot be empty",
|
||||
p.name)
|
||||
|
@ -619,8 +634,8 @@ class GatherDecls(TcheckVisitor):
|
|||
if not dtordecl:
|
||||
self.error(
|
||||
p.loc,
|
||||
"destructor declaration `delete(...)' required for managed protocol `%s'",
|
||||
p.name)
|
||||
"destructor declaration `%s(...)' required for managed protocol `%s'",
|
||||
_DELETE_MSG, p.name)
|
||||
|
||||
for managed in p.managesStmts:
|
||||
mgdname = managed.name
|
||||
|
@ -722,7 +737,7 @@ class GatherDecls(TcheckVisitor):
|
|||
self.symtab.exitScope(p)
|
||||
|
||||
|
||||
def visitManagerStmt(self, mgr):
|
||||
def visitManager(self, mgr):
|
||||
mgrdecl = self.symtab.lookup(mgr.name)
|
||||
pdecl = mgr.of.decl
|
||||
assert pdecl
|
||||
|
@ -741,9 +756,8 @@ class GatherDecls(TcheckVisitor):
|
|||
"entity `%s' referenced as |manager| of `%s' is not of `protocol' type; instead it is of type `%s'",
|
||||
mgrname, pname, mgrdecl.type.typename())
|
||||
else:
|
||||
assert pdecl.type.manager is None
|
||||
mgr.decl = mgrdecl
|
||||
pdecl.type.manager = mgrdecl.type
|
||||
pdecl.type.addManager(mgrdecl.type)
|
||||
|
||||
|
||||
def visitManagesStmt(self, mgs):
|
||||
|
@ -946,15 +960,14 @@ class CheckTypes(TcheckVisitor):
|
|||
|
||||
|
||||
def visitProtocol(self, p):
|
||||
# check that we require no more "power" than our manager protocol
|
||||
# check that we require no more "power" than our manager protocols
|
||||
ptype, pname = p.decl.type, p.decl.shortname
|
||||
mgrtype = ptype.manager
|
||||
if mgrtype is not None and ptype.needsMoreJuiceThan(mgrtype):
|
||||
mgrname = p.manager.decl.shortname
|
||||
self.error(
|
||||
p.decl.loc,
|
||||
"protocol `%s' requires more powerful send semantics than its manager `%s' provides",
|
||||
pname, mgrname)
|
||||
for mgrtype in ptype.managers:
|
||||
if mgrtype is not None and ptype.needsMoreJuiceThan(mgrtype):
|
||||
self.error(
|
||||
p.decl.loc,
|
||||
"protocol `%s' requires more powerful send semantics than its manager `%s' provides",
|
||||
pname, mgrtype.name())
|
||||
|
||||
# XXX currently we don't require a delete() message of top-level
|
||||
# actors. need to let experience guide this decision
|
||||
|
@ -980,21 +993,19 @@ class CheckTypes(TcheckVisitor):
|
|||
loc = mgs.loc
|
||||
|
||||
# we added this information; sanity check it
|
||||
for managed in ptype.manages:
|
||||
if managed is mgstype:
|
||||
break
|
||||
else:
|
||||
assert False
|
||||
assert ptype.isManagerOf(mgstype)
|
||||
|
||||
# check that the "managed" protocol agrees
|
||||
if mgstype.manager is not ptype:
|
||||
if not mgstype.isManagedBy(ptype):
|
||||
self.error(
|
||||
loc,
|
||||
"|manages| declaration in protocol `%s' does not match any |manager| declaration in protocol `%s'",
|
||||
pname, mgsname)
|
||||
|
||||
|
||||
def visitManagerStmt(self, mgr):
|
||||
def visitManager(self, mgr):
|
||||
# FIXME/bug 541126: check that the protocol graph is acyclic
|
||||
|
||||
pdecl = mgr.of.decl
|
||||
ptype, pname = pdecl.type, pdecl.shortname
|
||||
|
||||
|
@ -1002,7 +1013,7 @@ class CheckTypes(TcheckVisitor):
|
|||
mgrtype, mgrname = mgrdecl.type, mgrdecl.shortname
|
||||
|
||||
# we added this information; sanity check it
|
||||
assert ptype.manager is mgrtype
|
||||
assert ptype.isManagedBy(mgrtype)
|
||||
|
||||
loc = mgr.loc
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче