Loading ipc/ipdl/ipdl/ast.py +12 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ class Visitor: spawns.accept(self) for bridges in p.bridgesStmts: bridges.accept(self) for opens in p.opensStmts: opens.accept(self) for mgr in p.managers: mgr.accept(self) for managed in p.managesStmts: Loading @@ -95,6 +97,9 @@ class Visitor: def visitBridgesStmt(self, bridges): pass def visitOpensStmt(self, opens): pass def visitManager(self, mgr): pass Loading Loading @@ -269,6 +274,7 @@ class Protocol(NamespacedNode): self.sendSemantics = ASYNC self.spawnsStmts = [ ] self.bridgesStmts = [ ] self.opensStmts = [ ] self.managers = [ ] self.managesStmts = [ ] self.messageDecls = [ ] Loading Loading @@ -304,6 +310,12 @@ class BridgesStmt(Node): self.parentSide = parentSide self.childSide = childSide class OpensStmt(Node): def __init__(self, loc, side, proto): Node.__init__(self, loc) self.side = side self.proto = proto class Manager(Node): def __init__(self, loc, managerName): Node.__init__(self, loc) Loading ipc/ipdl/ipdl/parser.py +17 −2 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ reserved = set(( 'manages', 'namespace', 'nullable', 'opens', 'or', 'parent', 'protocol', Loading Loading @@ -343,7 +344,7 @@ def p_ProtocolBody(p): p[0] = p[1] ##-------------------- ## spawns/bridges stmts ## spawns/bridges/opens stmts def p_SpawnsStmtsOpt(p): """SpawnsStmtsOpt : SpawnsStmt SpawnsStmtsOpt Loading @@ -370,7 +371,7 @@ def p_AsOpt(p): def p_BridgesStmtsOpt(p): """BridgesStmtsOpt : BridgesStmt BridgesStmtsOpt | ManagersStmtOpt""" | OpensStmtsOpt""" if 2 == len(p): p[0] = p[1] else: Loading @@ -381,6 +382,20 @@ def p_BridgesStmt(p): """BridgesStmt : BRIDGES ID ',' ID ';'""" p[0] = BridgesStmt(locFromTok(p, 1), p[2], p[4]) def p_OpensStmtsOpt(p): """OpensStmtsOpt : OpensStmt OpensStmtsOpt | ManagersStmtOpt""" if 2 == len(p): p[0] = p[1] else: p[2].opensStmts.insert(0, p[1]) p[0] = p[2] def p_OpensStmt(p): """OpensStmt : PARENT OPENS ID ';' | CHILD OPENS ID ';'""" p[0] = OpensStmt(locFromTok(p, 1), p[1], p[3]) ##-------------------- ## manager/manages stmts Loading ipc/ipdl/ipdl/type.py +105 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,7 @@ class ProtocolType(IPDLType): self.qname = qname self.sendSemantics = sendSemantics self.spawns = set() # ProtocolType self.opens = set() # ProtocolType self.managers = set() # ProtocolType self.manages = [ ] self.stateless = stateless Loading @@ -313,6 +314,10 @@ class ProtocolType(IPDLType): assert self.isToplevel() and ptype.isToplevel() self.spawns.add(ptype) def addOpen(self, ptype): assert self.isToplevel() and ptype.isToplevel() self.opens.add(ptype) def managedBy(self, mgr): self.managers = mgr Loading Loading @@ -773,6 +778,9 @@ class GatherDecls(TcheckVisitor): for bridges in p.bridgesStmts: bridges.accept(self) for opens in p.opensStmts: opens.accept(self) seenmgrs = set() for mgr in p.managers: if mgr.name in seenmgrs: Loading Loading @@ -923,6 +931,14 @@ class GatherDecls(TcheckVisitor): bridges.parentSide = lookup(bridges.parentSide) bridges.childSide = lookup(bridges.childSide) def visitOpensStmt(self, opens): pname = opens.proto opens.proto = self.symtab.lookup(pname) if opens.proto is None: self.error(opens.loc, "opened protocol `%s' has not been declared", pname) def visitManager(self, mgr): mgrdecl = self.symtab.lookup(mgr.name) Loading Loading @@ -1230,6 +1246,11 @@ class CheckTypes(TcheckVisitor): "protocol `%s' is not top-level and so cannot declare |bridges|", pname) if len(p.opensStmts) and not ptype.isToplevel(): self.error(p.decl.loc, "protocol `%s' is not top-level and so cannot declare |opens|", pname) for mgrtype in ptype.managers: if mgrtype is not None and ptype.needsMoreJuiceThan(mgrtype): self.error( Loading Loading @@ -1298,6 +1319,23 @@ class CheckTypes(TcheckVisitor): parentType.name(), childType.name()) def visitOpensStmt(self, opens): if not self.ptype.isToplevel(): self.error(opens.loc, "only top-level protocols can have |opens| statements; `%s' cannot", self.ptype.name()) return openedType = opens.proto.type if not (openedType.isIPDL() and openedType.isProtocol() and openedType.isToplevel()): self.error(opens.loc, "cannot open non-top-level-protocol `%s'", openedType.name()) else: self.ptype.addOpen(openedType) def visitManagesStmt(self, mgs): pdecl = mgs.manager.decl ptype, pname = pdecl.type, pdecl.shortname Loading Loading @@ -1467,11 +1505,20 @@ class BridgeEdge: self.parent, self.bridgeProto.name(), self.child) def __str__(self): return repr(self) class OpensEdge: def __init__(self, opener, openedProto): self.opener = opener # Actor self.openedProto = openedProto # ProtocolType def __repr__(self): return '(%r)--opens-->(%s)'% (self.opener, self.openedProto.name()) def __str__(self): return repr(self) # "singleton" class with state that persists across type checking of # all protocols class ProcessGraph: processes = set() # set(Process) bridges = { } # ProtocolType -> [ BridgeEdge ] opens = { } # ProtocolType -> [ OpensEdge ] actorToProcess = { } # Actor -> Process visitedSpawns = set() # set(ActorType) visitedBridges = set() # set(ActorType) Loading Loading @@ -1510,6 +1557,27 @@ class ProcessGraph: for bridge in edges: yield bridge @classmethod def opensOf(cls, openedP): return cls.opens.get(openedP, []) @classmethod def opensEndpointsOf(cls, ptype, side): actor = Actor(ptype, side) endpoints = [] for o in cls.iteropens(): if actor == o.opener: endpoints.append(Actor(o.openedProto, o.opener.side)) elif actor == o.opener.other(): endpoints.append(Actor(o.openedProto, o.opener.other().side)) return endpoints @classmethod def iteropens(cls): for edges in cls.opens.itervalues(): for opens in edges: yield opens @classmethod def spawn(cls, spawner, remoteSpawn): localSpawn = remoteSpawn.other() Loading @@ -1519,10 +1587,27 @@ class ProcessGraph: @classmethod def bridge(cls, parent, child, bridgeP): bridgeParent = Actor(bridgeP, 'parent') parentProcess = ProcessGraph.getProcess(parent) parentProcess.merge(ProcessGraph.getProcess(bridgeParent)) bridgeChild = Actor(bridgeP, 'child') childProcess = ProcessGraph.getProcess(child) childProcess.merge(ProcessGraph.getProcess(bridgeChild)) if bridgeP not in cls.bridges: cls.bridges[bridgeP] = [ ] cls.bridges[bridgeP].append(BridgeEdge(bridgeP, parent, child)) @classmethod def open(cls, opener, opened, openedP): remoteOpener, remoteOpened, = opener.other(), opened.other() openerProcess = ProcessGraph.getProcess(opener) openerProcess.merge(ProcessGraph.getProcess(opened)) remoteOpenerProcess = ProcessGraph.getProcess(remoteOpener) remoteOpenerProcess.merge(ProcessGraph.getProcess(remoteOpened)) if openedP not in cls.opens: cls.opens[openedP] = [ ] cls.opens[openedP].append(OpensEdge(opener, openedP)) class BuildProcessGraph(TcheckVisitor): class findSpawns(TcheckVisitor): Loading Loading @@ -1629,6 +1714,22 @@ class BuildProcessGraph(TcheckVisitor): ProcessGraph.bridge(parentSideActor, childSideActor, bridgeProto) def visitOpensStmt(self, opens): openedP = opens.proto.type opener = Actor(self.visiting, opens.side) opened = Actor(openedP, opens.side) # The picture here is: # [ opener | opened ] (process 1) # | | # | | # [ remoteOpener | remoteOpened ] (process 2) # # An opens stmt tells us that the pairs |opener|/|opened| # and |remoteOpener|/|remoteOpened| are each in the same # process. ProcessGraph.open(opener, opened, openedP) class CheckProcessGraph(TcheckVisitor): def __init__(self, errors): Loading @@ -1647,6 +1748,10 @@ class CheckProcessGraph(TcheckVisitor): for bridgeList in ProcessGraph.bridges.itervalues(): for bridge in bridgeList: print ' ', bridge print 'Opens' for opensList in ProcessGraph.opens.itervalues(): for opens in opensList: print ' ', opens ##----------------------------------------------------------------------------- Loading Loading
ipc/ipdl/ipdl/ast.py +12 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ class Visitor: spawns.accept(self) for bridges in p.bridgesStmts: bridges.accept(self) for opens in p.opensStmts: opens.accept(self) for mgr in p.managers: mgr.accept(self) for managed in p.managesStmts: Loading @@ -95,6 +97,9 @@ class Visitor: def visitBridgesStmt(self, bridges): pass def visitOpensStmt(self, opens): pass def visitManager(self, mgr): pass Loading Loading @@ -269,6 +274,7 @@ class Protocol(NamespacedNode): self.sendSemantics = ASYNC self.spawnsStmts = [ ] self.bridgesStmts = [ ] self.opensStmts = [ ] self.managers = [ ] self.managesStmts = [ ] self.messageDecls = [ ] Loading Loading @@ -304,6 +310,12 @@ class BridgesStmt(Node): self.parentSide = parentSide self.childSide = childSide class OpensStmt(Node): def __init__(self, loc, side, proto): Node.__init__(self, loc) self.side = side self.proto = proto class Manager(Node): def __init__(self, loc, managerName): Node.__init__(self, loc) Loading
ipc/ipdl/ipdl/parser.py +17 −2 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ reserved = set(( 'manages', 'namespace', 'nullable', 'opens', 'or', 'parent', 'protocol', Loading Loading @@ -343,7 +344,7 @@ def p_ProtocolBody(p): p[0] = p[1] ##-------------------- ## spawns/bridges stmts ## spawns/bridges/opens stmts def p_SpawnsStmtsOpt(p): """SpawnsStmtsOpt : SpawnsStmt SpawnsStmtsOpt Loading @@ -370,7 +371,7 @@ def p_AsOpt(p): def p_BridgesStmtsOpt(p): """BridgesStmtsOpt : BridgesStmt BridgesStmtsOpt | ManagersStmtOpt""" | OpensStmtsOpt""" if 2 == len(p): p[0] = p[1] else: Loading @@ -381,6 +382,20 @@ def p_BridgesStmt(p): """BridgesStmt : BRIDGES ID ',' ID ';'""" p[0] = BridgesStmt(locFromTok(p, 1), p[2], p[4]) def p_OpensStmtsOpt(p): """OpensStmtsOpt : OpensStmt OpensStmtsOpt | ManagersStmtOpt""" if 2 == len(p): p[0] = p[1] else: p[2].opensStmts.insert(0, p[1]) p[0] = p[2] def p_OpensStmt(p): """OpensStmt : PARENT OPENS ID ';' | CHILD OPENS ID ';'""" p[0] = OpensStmt(locFromTok(p, 1), p[1], p[3]) ##-------------------- ## manager/manages stmts Loading
ipc/ipdl/ipdl/type.py +105 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,7 @@ class ProtocolType(IPDLType): self.qname = qname self.sendSemantics = sendSemantics self.spawns = set() # ProtocolType self.opens = set() # ProtocolType self.managers = set() # ProtocolType self.manages = [ ] self.stateless = stateless Loading @@ -313,6 +314,10 @@ class ProtocolType(IPDLType): assert self.isToplevel() and ptype.isToplevel() self.spawns.add(ptype) def addOpen(self, ptype): assert self.isToplevel() and ptype.isToplevel() self.opens.add(ptype) def managedBy(self, mgr): self.managers = mgr Loading Loading @@ -773,6 +778,9 @@ class GatherDecls(TcheckVisitor): for bridges in p.bridgesStmts: bridges.accept(self) for opens in p.opensStmts: opens.accept(self) seenmgrs = set() for mgr in p.managers: if mgr.name in seenmgrs: Loading Loading @@ -923,6 +931,14 @@ class GatherDecls(TcheckVisitor): bridges.parentSide = lookup(bridges.parentSide) bridges.childSide = lookup(bridges.childSide) def visitOpensStmt(self, opens): pname = opens.proto opens.proto = self.symtab.lookup(pname) if opens.proto is None: self.error(opens.loc, "opened protocol `%s' has not been declared", pname) def visitManager(self, mgr): mgrdecl = self.symtab.lookup(mgr.name) Loading Loading @@ -1230,6 +1246,11 @@ class CheckTypes(TcheckVisitor): "protocol `%s' is not top-level and so cannot declare |bridges|", pname) if len(p.opensStmts) and not ptype.isToplevel(): self.error(p.decl.loc, "protocol `%s' is not top-level and so cannot declare |opens|", pname) for mgrtype in ptype.managers: if mgrtype is not None and ptype.needsMoreJuiceThan(mgrtype): self.error( Loading Loading @@ -1298,6 +1319,23 @@ class CheckTypes(TcheckVisitor): parentType.name(), childType.name()) def visitOpensStmt(self, opens): if not self.ptype.isToplevel(): self.error(opens.loc, "only top-level protocols can have |opens| statements; `%s' cannot", self.ptype.name()) return openedType = opens.proto.type if not (openedType.isIPDL() and openedType.isProtocol() and openedType.isToplevel()): self.error(opens.loc, "cannot open non-top-level-protocol `%s'", openedType.name()) else: self.ptype.addOpen(openedType) def visitManagesStmt(self, mgs): pdecl = mgs.manager.decl ptype, pname = pdecl.type, pdecl.shortname Loading Loading @@ -1467,11 +1505,20 @@ class BridgeEdge: self.parent, self.bridgeProto.name(), self.child) def __str__(self): return repr(self) class OpensEdge: def __init__(self, opener, openedProto): self.opener = opener # Actor self.openedProto = openedProto # ProtocolType def __repr__(self): return '(%r)--opens-->(%s)'% (self.opener, self.openedProto.name()) def __str__(self): return repr(self) # "singleton" class with state that persists across type checking of # all protocols class ProcessGraph: processes = set() # set(Process) bridges = { } # ProtocolType -> [ BridgeEdge ] opens = { } # ProtocolType -> [ OpensEdge ] actorToProcess = { } # Actor -> Process visitedSpawns = set() # set(ActorType) visitedBridges = set() # set(ActorType) Loading Loading @@ -1510,6 +1557,27 @@ class ProcessGraph: for bridge in edges: yield bridge @classmethod def opensOf(cls, openedP): return cls.opens.get(openedP, []) @classmethod def opensEndpointsOf(cls, ptype, side): actor = Actor(ptype, side) endpoints = [] for o in cls.iteropens(): if actor == o.opener: endpoints.append(Actor(o.openedProto, o.opener.side)) elif actor == o.opener.other(): endpoints.append(Actor(o.openedProto, o.opener.other().side)) return endpoints @classmethod def iteropens(cls): for edges in cls.opens.itervalues(): for opens in edges: yield opens @classmethod def spawn(cls, spawner, remoteSpawn): localSpawn = remoteSpawn.other() Loading @@ -1519,10 +1587,27 @@ class ProcessGraph: @classmethod def bridge(cls, parent, child, bridgeP): bridgeParent = Actor(bridgeP, 'parent') parentProcess = ProcessGraph.getProcess(parent) parentProcess.merge(ProcessGraph.getProcess(bridgeParent)) bridgeChild = Actor(bridgeP, 'child') childProcess = ProcessGraph.getProcess(child) childProcess.merge(ProcessGraph.getProcess(bridgeChild)) if bridgeP not in cls.bridges: cls.bridges[bridgeP] = [ ] cls.bridges[bridgeP].append(BridgeEdge(bridgeP, parent, child)) @classmethod def open(cls, opener, opened, openedP): remoteOpener, remoteOpened, = opener.other(), opened.other() openerProcess = ProcessGraph.getProcess(opener) openerProcess.merge(ProcessGraph.getProcess(opened)) remoteOpenerProcess = ProcessGraph.getProcess(remoteOpener) remoteOpenerProcess.merge(ProcessGraph.getProcess(remoteOpened)) if openedP not in cls.opens: cls.opens[openedP] = [ ] cls.opens[openedP].append(OpensEdge(opener, openedP)) class BuildProcessGraph(TcheckVisitor): class findSpawns(TcheckVisitor): Loading Loading @@ -1629,6 +1714,22 @@ class BuildProcessGraph(TcheckVisitor): ProcessGraph.bridge(parentSideActor, childSideActor, bridgeProto) def visitOpensStmt(self, opens): openedP = opens.proto.type opener = Actor(self.visiting, opens.side) opened = Actor(openedP, opens.side) # The picture here is: # [ opener | opened ] (process 1) # | | # | | # [ remoteOpener | remoteOpened ] (process 2) # # An opens stmt tells us that the pairs |opener|/|opened| # and |remoteOpener|/|remoteOpened| are each in the same # process. ProcessGraph.open(opener, opened, openedP) class CheckProcessGraph(TcheckVisitor): def __init__(self, errors): Loading @@ -1647,6 +1748,10 @@ class CheckProcessGraph(TcheckVisitor): for bridgeList in ProcessGraph.bridges.itervalues(): for bridge in bridgeList: print ' ', bridge print 'Opens' for opensList in ProcessGraph.opens.itervalues(): for opens in opensList: print ' ', opens ##----------------------------------------------------------------------------- Loading