--- a/ipc/ipdl/ipdl/cxx/ast.py
+++ b/ipc/ipdl/ipdl/cxx/ast.py
@@ -462,84 +462,86 @@ class Inherit(Node):
self.type = type
self.viz = viz
class FriendClassDecl(Node):
def __init__(self, friend):
Node.__init__(self)
self.friend = friend
+# Python2 polyfill for Python3's Enum() functional API.
+def make_enum(name, members_str):
+ members_list = members_str.split()
+ members_dict = {}
+ member_value = 1
+ for member in members_list:
+ members_dict[member] = member_value
+ member_value += 1
+ return type(name, (), members_dict)
+
+MethodSpec = make_enum('MethodSpec', 'NONE VIRTUAL PURE OVERRIDE STATIC')
+
class MethodDecl(Node):
def __init__(self, name, params=[ ], ret=Type('void'),
- virtual=0, const=0, pure=0, static=0, warn_unused=0,
+ methodspec=MethodSpec.NONE, const=0, warn_unused=0,
inline=0, force_inline=0, never_inline=0,
- typeop=None, override=0,
- T=None):
- assert not (virtual and static)
- assert not pure or virtual # pure => virtual
- assert not override or virtual # override => virtual
- assert not (override and pure)
- assert not (static and typeop)
+ typeop=None, T=None):
assert not (name and typeop)
assert name is None or isinstance(name, str)
assert not isinstance(ret, list)
for decl in params: assert not isinstance(decl, str)
assert not isinstance(T, int)
assert not (inline and never_inline)
assert not (force_inline and never_inline)
if typeop is not None:
+ assert methodspec == MethodSpec.NONE
ret = None
Node.__init__(self)
self.name = name
self.params = params # [ Param ]
self.ret = ret # Type or None
- self.virtual = virtual # bool
+ self.methodspec = methodspec # enum
self.const = const # bool
- self.pure = pure # bool
- self.override = override # bool
- self.static = static # bool
self.warn_unused = warn_unused # bool
self.force_inline = (force_inline or T) # bool
self.inline = inline # bool
self.never_inline = never_inline # bool
self.typeop = typeop # Type or None
self.T = T # Type or None
self.only_for_definition = False
def __deepcopy__(self, memo):
return MethodDecl(
self.name,
params=copy.deepcopy(self.params, memo),
ret=copy.deepcopy(self.ret, memo),
- virtual=self.virtual,
+ methodspec=self.methodspec,
const=self.const,
- pure=self.pure,
- override=self.override,
- static=self.static,
warn_unused=self.warn_unused,
inline=self.inline,
force_inline=self.force_inline,
never_inline=self.never_inline,
typeop=copy.deepcopy(self.typeop, memo),
T=copy.deepcopy(self.T, memo))
class MethodDefn(Block):
def __init__(self, decl):
Block.__init__(self)
self.decl = decl
class FunctionDecl(MethodDecl):
def __init__(self, name, params=[ ], ret=Type('void'),
- static=0, warn_unused=0,
+ methodspec=MethodSpec.NONE, warn_unused=0,
inline=0, force_inline=0,
T=None):
+ assert methodspec == MethodSpec.NONE or methodspec == MethodSpec.STATIC
MethodDecl.__init__(self, name, params=params, ret=ret,
- static=static, warn_unused=warn_unused,
+ methodspec=methodspec, warn_unused=warn_unused,
inline=inline, force_inline=force_inline,
T=T)
class FunctionDefn(MethodDefn):
def __init__(self, decl):
MethodDefn.__init__(self, decl)
class ConstructorDecl(MethodDecl):
@@ -554,28 +556,29 @@ class ConstructorDecl(MethodDecl):
self.explicit)
class ConstructorDefn(MethodDefn):
def __init__(self, decl, memberinits=[ ]):
MethodDefn.__init__(self, decl)
self.memberinits = memberinits
class DestructorDecl(MethodDecl):
- def __init__(self, name, virtual=0, override=0, force_inline=0, inline=0):
+ def __init__(self, name, methodspec=MethodSpec.NONE, force_inline=0, inline=0):
+ # C++ allows pure or override destructors, but ipdl cgen does not.
+ assert methodspec == MethodSpec.NONE or methodspec == MethodSpec.VIRTUAL
MethodDecl.__init__(self, name, params=[ ], ret=None,
- virtual=virtual,
+ methodspec=methodspec,
force_inline=force_inline, inline=inline)
def __deepcopy__(self, memo):
return DestructorDecl(self.name,
- virtual=self.virtual,
+ methodspec=self.methodspec,
force_inline=self.force_inline,
inline=self.inline)
-
class DestructorDefn(MethodDefn):
def __init__(self, decl): MethodDefn.__init__(self, decl)
##------------------------------
# expressions
class ExprVar(Node):
def __init__(self, name):
assert isinstance(name, str)
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -2735,80 +2735,83 @@ class _GenerateProtocolActorCode(ipdl.as
if self.receivesMessage(md):
# generate Recv/Answer* interface
implicit = (not isdtor)
returnsems = 'resolver' if md.decl.type.isAsync() else 'out'
recvDecl = MethodDecl(
md.recvMethod().name,
params=md.makeCxxParams(paramsems='move', returnsems=returnsems,
side=self.side, implicit=implicit),
- ret=Type('mozilla::ipc::IPCResult'), virtual=1)
+ ret=Type('mozilla::ipc::IPCResult'),
+ methodspec=MethodSpec.VIRTUAL)
if isctor or isdtor:
defaultRecv = MethodDefn(recvDecl)
defaultRecv.addstmt(StmtReturn(ExprCall(ExprVar('IPC_OK'))))
self.cls.addstmt(defaultRecv)
else:
- recvDecl.pure = 1
+ recvDecl.methodspec = MethodSpec.PURE
self.cls.addstmt(StmtDecl(recvDecl))
for md in p.messageDecls:
managed = md.decl.type.constructedType()
if not ptype.isManagerOf(managed) or md.decl.type.isDtor():
continue
# add the Alloc/Dealloc interface for managed actors
actortype = md.actorDecl().bareType(self.side)
self.cls.addstmt(StmtDecl(MethodDecl(
_allocMethod(managed, self.side).name,
params=md.makeCxxParams(side=self.side, implicit=0),
- ret=actortype,
- virtual=1, pure=1)))
+ ret=actortype, methodspec=MethodSpec.PURE)))
self.cls.addstmt(StmtDecl(MethodDecl(
_deallocMethod(managed, self.side).name,
params=[ Decl(actortype, 'aActor') ],
- ret=Type.BOOL,
- virtual=1, pure=1)))
+ ret=Type.BOOL, methodspec=MethodSpec.PURE)))
# ActorDestroy() method; default is no-op
+ if self.side == 'parent':
+ methodspec = MethodSpec.PURE
+ else:
+ methodspec = MethodSpec.VIRTUAL
+
self.cls.addstmts([
Whitespace.NL,
MethodDefn(MethodDecl(
_destroyMethod().name,
params=[ Decl(_DestroyReason.Type(), 'aWhy') ],
- ret=Type.VOID,
- virtual=1, pure=(self.side == 'parent'))),
+ ret=Type.VOID, methodspec=methodspec)),
Whitespace.NL
])
if ptype.isToplevel():
# void ProcessingError(code); default to no-op
processingerror = MethodDefn(
MethodDecl(p.processingErrorVar().name,
params=[ Param(_Result.Type(), 'aCode'),
Param(Type('char', const=1, ptr=1), 'aReason') ],
- virtual=1, override=1))
+ methodspec=MethodSpec.OVERRIDE))
# bool ShouldContinueFromReplyTimeout(); default to |true|
shouldcontinue = MethodDefn(
MethodDecl(p.shouldContinueFromTimeoutVar().name,
- ret=Type.BOOL, virtual=1, override=1))
+ ret=Type.BOOL, methodspec=MethodSpec.OVERRIDE))
shouldcontinue.addstmt(StmtReturn.TRUE)
# void Entered*()/Exited*(); default to no-op
entered = MethodDefn(
- MethodDecl(p.enteredCxxStackVar().name, virtual=1, override=1))
+ MethodDecl(p.enteredCxxStackVar().name, methodspec=MethodSpec.OVERRIDE))
exited = MethodDefn(
- MethodDecl(p.exitedCxxStackVar().name, virtual=1, override=1))
+ MethodDecl(p.exitedCxxStackVar().name, methodspec=MethodSpec.OVERRIDE))
enteredcall = MethodDefn(
- MethodDecl(p.enteredCallVar().name, virtual=1, override=1))
+ MethodDecl(p.enteredCallVar().name, methodspec=MethodSpec.OVERRIDE))
exitedcall = MethodDefn(
- MethodDecl(p.exitedCallVar().name, virtual=1, override=1))
+ MethodDecl(p.exitedCallVar().name, methodspec=MethodSpec.OVERRIDE))
self.cls.addstmts([ processingerror,
shouldcontinue,
entered, exited,
enteredcall, exitedcall,
Whitespace.NL ])
self.cls.addstmts((
@@ -2840,17 +2843,17 @@ class _GenerateProtocolActorCode(ipdl.as
]
ctor.addstmt(StmtExpr(ExprCall(ExprVar('MOZ_COUNT_CTOR'),
[ ExprVar(self.clsname) ])))
self.cls.addstmts([ ctor, Whitespace.NL ])
# ~Actor()
dtor = DestructorDefn(
- DestructorDecl(self.clsname, virtual=True))
+ DestructorDecl(self.clsname, methodspec=MethodSpec.VIRTUAL))
dtor.addstmt(StmtExpr(ExprCall(ExprVar('MOZ_COUNT_DTOR'),
[ ExprVar(self.clsname) ])))
self.cls.addstmts([ dtor, Whitespace.NL ])
if not ptype.isToplevel():
if 1 == len(p.managers):
## manager() const
@@ -2943,17 +2946,17 @@ class _GenerateProtocolActorCode(ipdl.as
self.cls.addstmts(self.implementManagerIface())
def makeHandlerMethod(name, switch, hasReply, dispatches=0):
params = [ Decl(Type('Message', const=1, ref=1), msgvar.name) ]
if hasReply:
params.append(Decl(Type('Message', ref=1, ptr=1),
replyvar.name))
- method = MethodDefn(MethodDecl(name, virtual=1, override=1,
+ method = MethodDefn(MethodDecl(name, methodspec=MethodSpec.OVERRIDE,
params=params, ret=_Result.Type()))
if not switch:
crash = StmtExpr(ExprCall(ExprVar('MOZ_ASSERT_UNREACHABLE'),
args=[ExprLiteral.String('message protocol not supported')]))
method.addstmts([crash, StmtReturn(_Result.NotKnown)])
return method
@@ -3023,34 +3026,37 @@ class _GenerateProtocolActorCode(ipdl.as
destroysubtreevar = ExprVar('DestroySubtree')
deallocsubtreevar = ExprVar('DeallocSubtree')
deallocshmemvar = ExprVar('DeallocShmems')
deallocselfvar = ExprVar('Dealloc' + _actorName(ptype.name(), self.side))
# int32_t GetProtocolTypeId() { return PFoo; }
gettypetag = MethodDefn(
- MethodDecl('GetProtocolTypeId', ret=_actorTypeTagType(), virtual=1, override=1))
+ MethodDecl('GetProtocolTypeId', ret=_actorTypeTagType(),
+ methodspec=MethodSpec.OVERRIDE))
gettypetag.addstmt(StmtReturn(_protocolId(ptype)))
self.cls.addstmts([ gettypetag, Whitespace.NL ])
if ptype.isToplevel():
# OnChannelClose()
- onclose = MethodDefn(MethodDecl('OnChannelClose', virtual=1, override=1))
+ onclose = MethodDefn(MethodDecl('OnChannelClose',
+ methodspec=MethodSpec.OVERRIDE))
onclose.addstmts([
StmtExpr(ExprCall(destroysubtreevar,
args=[ _DestroyReason.NormalShutdown ])),
StmtExpr(ExprCall(deallocsubtreevar)),
StmtExpr(ExprCall(deallocshmemvar)),
StmtExpr(ExprCall(deallocselfvar))
])
self.cls.addstmts([ onclose, Whitespace.NL ])
# OnChannelError()
- onerror = MethodDefn(MethodDecl('OnChannelError', virtual=1, override=1))
+ onerror = MethodDefn(MethodDecl('OnChannelError',
+ methodspec=MethodSpec.OVERRIDE))
onerror.addstmts([
StmtExpr(ExprCall(destroysubtreevar,
args=[ _DestroyReason.AbnormalShutdown ])),
StmtExpr(ExprCall(deallocsubtreevar)),
StmtExpr(ExprCall(deallocshmemvar)),
StmtExpr(ExprCall(deallocselfvar))
])
self.cls.addstmts([ onerror, Whitespace.NL ])
@@ -3074,17 +3080,17 @@ class _GenerateProtocolActorCode(ipdl.as
## private methods
self.cls.addstmt(Label.PRIVATE)
## ProtocolName()
actorname = _actorName(p.name, self.side)
protocolname = MethodDefn(MethodDecl(
'ProtocolName', params=[],
- const=1, virtual=1, override=1, ret=Type('char', const=1, ptr=1)))
+ const=1, methodspec=MethodSpec.OVERRIDE, ret=Type('char', const=1, ptr=1)))
protocolname.addstmts([
StmtReturn(ExprLiteral.String(actorname))
])
self.cls.addstmts([ protocolname, Whitespace.NL ])
## DestroySubtree(bool normal)
whyvar = ExprVar('why')
subtreewhyvar = ExprVar('subtreewhy')
@@ -3199,17 +3205,17 @@ class _GenerateProtocolActorCode(ipdl.as
])
deallocsubtree.addstmt(block)
# don't delete outselves: either the manager will do it, or
# we're toplevel
self.cls.addstmts([ deallocsubtree, Whitespace.NL ])
if ptype.isToplevel():
- deallocself = MethodDefn(MethodDecl(deallocselfvar.name, virtual=1))
+ deallocself = MethodDefn(MethodDecl(deallocselfvar.name, methodspec=MethodSpec.VIRTUAL))
self.cls.addstmts([ deallocself, Whitespace.NL ])
self.implementPickling()
## private members
if ptype.isToplevel():
self.cls.addstmt(StmtDecl(Decl(p.channelType(), 'mChannel')))
@@ -3237,23 +3243,23 @@ class _GenerateProtocolActorCode(ipdl.as
ithkid = ExprIndex(kidsvar, ivar)
methods = []
if p.decl.type.isToplevel():
getchannel = MethodDefn(MethodDecl(
p.getChannelMethod().name,
ret=Type('MessageChannel', ptr=1),
- virtual=1, override=1))
+ methodspec=MethodSpec.OVERRIDE))
getchannel.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
getchannelconst = MethodDefn(MethodDecl(
p.getChannelMethod().name,
ret=Type('MessageChannel', ptr=1, const=1),
- virtual=1, override=1, const=1))
+ methodspec=MethodSpec.OVERRIDE, const=1))
getchannelconst.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
methods += [ getchannel,
getchannelconst ]
if p.decl.type.isToplevel():
tmpvar = ExprVar('tmp')
@@ -3291,17 +3297,17 @@ class _GenerateProtocolActorCode(ipdl.as
# all protocols share the "same" RemoveManagee() implementation
pvar = ExprVar('aProtocolId')
listenervar = ExprVar('aListener')
removemanagee = MethodDefn(MethodDecl(
p.removeManageeMethod().name,
params=[ Decl(_protocolIdType(), pvar.name),
Decl(protocolbase, listenervar.name) ],
- virtual=1, override=1))
+ methodspec=MethodSpec.OVERRIDE))
if not len(p.managesStmts):
removemanagee.addstmts([ _fatalError('unreached'), StmtReturn() ])
else:
switchontype = StmtSwitch(pvar)
for managee in p.managesStmts:
case = StmtBlock()
actorvar = ExprVar('actor')
@@ -4750,17 +4756,17 @@ class _GenerateProtocolActorCode(ipdl.as
_protocolErrorBreakpoint('Handler returned error code!'),
Whitespace('// Error handled in mozilla::ipc::IPCResult\n', indent=1),
StmtReturn(_Result.ProcessingError)
])
return [ failif ]
def makeDtorMethodDecl(self, md):
decl = self.makeSendMethodDecl(md)
- decl.static = 1
+ decl.methodspec = MethodSpec.STATIC
return decl
def makeSendMethodDecl(self, md, promise=False):
implicit = md.decl.type.hasImplicitActorParam()
if md.decl.type.isAsync() and md.returns:
if promise:
returnsems = 'promise'
rettype = _refptr(Type(md.promiseName()))
@@ -4887,19 +4893,17 @@ methodDefns."""
cls.stmts[i] = StmtDecl(decl)
defns.addstmts([ defn, Whitespace.NL ])
return cls, defns
def _splitMethodDefn(md, clsname):
saveddecl = deepcopy(md.decl)
md.decl.name = (clsname +'::'+ md.decl.name)
- md.decl.virtual = 0
- md.decl.override = 0
- md.decl.static = 0
+ md.decl.methodspec = MethodSpec.NONE
md.decl.warn_unused = 0
md.decl.never_inline = 0
md.decl.only_for_definition = True
for param in md.decl.params:
if isinstance(param, Param):
param.default = None
return saveddecl, md
@@ -4939,20 +4943,20 @@ class _GenerateSkeletonImpl(Visitor):
]
def visitClass(self, cls):
self.cls = Class(self.name, inherits=[ Inherit(Type(cls.name)) ])
Visitor.visitClass(self, cls)
def visitMethodDecl(self, md):
- if not md.pure:
+ if md.methodspec != MethodSpec.PURE:
return
decl = deepcopy(md)
- decl.pure = 0
+ decl.methodspec = MethodSpec.OVERRIDE
impl = MethodDefn(MethodDecl(self.implname(md.name),
params=md.params,
ret=md.ret))
if md.ret.ptr:
impl.addstmt(StmtReturn(ExprLiteral.ZERO))
elif md.ret == Type.BOOL:
impl.addstmt(StmtReturn(ExprVar('false')))
@@ -4963,17 +4967,17 @@ class _GenerateSkeletonImpl(Visitor):
self.cls.addstmt(StmtDecl(ConstructorDecl(self.name)))
ctor = ConstructorDefn(ConstructorDecl(self.implname(self.name)))
ctor.addstmt(StmtExpr(ExprCall(ExprVar( 'MOZ_COUNT_CTOR'),
[ ExprVar(self.name) ])))
self.addmethodimpl(ctor)
def visitDestructorDecl(self, dd):
self.cls.addstmt(
- StmtDecl(DestructorDecl(self.name, virtual=1)))
+ StmtDecl(DestructorDecl(self.name, methodspec=MethodSpec.VIRTUAL)))
# FIXME/cjones: hack!
dtor = DestructorDefn(ConstructorDecl(self.implname('~' +self.name)))
dtor.addstmt(StmtExpr(ExprCall(ExprVar( 'MOZ_COUNT_DTOR'),
[ ExprVar(self.name) ])))
self.addmethodimpl(dtor)
def addmethodimpl(self, impl):
self.methodimpls.addstmts([ impl, Whitespace.NL ])