--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -333,25 +333,29 @@ def _promise(resolvetype, rejecttype, ta
inner = Type('Private') if resolver else None
return Type('MozPromise', T=[resolvetype, rejecttype, tail], inner=inner)
def _makePromise(returns, side, resolver=False):
if len(returns) > 1:
resolvetype = _tuple([d.bareType(side) for d in returns])
else:
resolvetype = returns[0].bareType(side)
+
+ needmove = not all(d.isCopyable() for d in returns)
+
return _promise(resolvetype,
_PromiseRejectReason.Type(),
- ExprLiteral.FALSE, resolver=resolver)
+ ExprLiteral.TRUE if needmove else ExprLiteral.FALSE,
+ resolver=resolver)
def _makeResolver(returns, side):
if len(returns) > 1:
- resolvetype = _tuple([d.bareType(side) for d in returns])
+ resolvetype = _tuple([d.moveType(side) for d in returns])
else:
- resolvetype = returns[0].bareType(side)
+ resolvetype = returns[0].moveType(side)
return TypeFunction([Decl(resolvetype, '')])
def _cxxArrayType(basetype, const=0, ref=0):
return Type('nsTArray', T=basetype, const=const, ref=ref, hasimplicitcopyctor=False)
def _cxxManagedContainerType(basetype, const=0, ref=0):
return Type('ManagedContainer', T=basetype,
const=const, ref=ref, hasimplicitcopyctor=False)
@@ -581,19 +585,24 @@ def _cxxConstRefType(ipdltype, side):
return t
if ipdltype.isIPDL() and ipdltype.isShmem():
t.ref = 1
return t
t.const = 1
t.ref = 1
return t
+def _cxxTypeNeedsMove(ipdltype):
+ return ipdltype.isIPDL() and (ipdltype.isArray() or
+ ipdltype.isShmem() or
+ ipdltype.isEndpoint())
+
def _cxxMoveRefType(ipdltype, side):
t = _cxxBareType(ipdltype, side)
- if ipdltype.isIPDL() and (ipdltype.isArray() or ipdltype.isShmem() or ipdltype.isEndpoint()):
+ if _cxxTypeNeedsMove(ipdltype):
t.ref = 2
return t
return _cxxConstRefType(ipdltype, side)
def _cxxPtrToType(ipdltype, side):
t = _cxxBareType(ipdltype, side)
if ipdltype.isIPDL() and ipdltype.isActor():
t.ptr = 0
@@ -626,16 +635,19 @@ def _deallocMethod(ptype, side):
class _HybridDecl:
"""A hybrid decl stores both an IPDL type and all the C++ type
info needed by later passes, along with a basic name for the decl."""
def __init__(self, ipdltype, name):
self.ipdltype = ipdltype
self.name = name
self.idnum = 0
+ def isCopyable(self):
+ return not _cxxTypeNeedsMove(self.ipdltype)
+
def var(self):
return ExprVar(self.name)
def bareType(self, side):
"""Return this decl's unqualified C++ type."""
return _cxxBareType(self.ipdltype, side)
def refType(self, side):
@@ -4079,19 +4091,19 @@ class _GenerateProtocolActorCode(ipdl.as
getpromise = [ Whitespace.NL,
StmtDecl(Decl(_refptr(promise), 'promise'),
init=ExprCall(ExprSelect(ExprCall(ExprSelect(self.protocol.callGetChannel(), '->', 'PopPromise'),
args=[ self.msgvar ]),
'.', Type('downcast', T=promise)))),
ifnotpromise ]
if len(md.returns) > 1:
resolvearg = ExprCall(ExprVar('MakeTuple'),
- args=[p.var() for p in md.returns])
+ args=[ExprMove(p.var()) for p in md.returns])
else:
- resolvearg = md.returns[0].var()
+ resolvearg = ExprMove(md.returns[0].var())
resolvepromise = [ StmtExpr(ExprCall(ExprSelect(ExprVar('promise'), '->', 'Resolve'),
args=[ resolvearg,
ExprVar('__func__')])) ]
rejectpromise = [ StmtExpr(ExprCall(ExprSelect(ExprVar('promise'), '->', 'Reject'),
args=[ reason, ExprVar('__func__') ])) ]
ifresolve = StmtIf(resolve)
ifresolve.addifstmts(desstmts)
@@ -4282,23 +4294,23 @@ class _GenerateProtocolActorCode(ipdl.as
+ [ self.logMessage(md, self.replyvar, 'Sending reply '),
StmtDecl(Decl(Type.BOOL, sendok.name),
init=ExprCall(
ExprSelect(self.protocol.callGetChannel(),
'->', 'Send'),
args=[ self.replyvar ])),
failifsendok ])
if len(md.returns) > 1:
- resolvedecl = Decl(_tuple([p.bareType(self.side) for p in md.returns],
+ resolvedecl = Decl(_tuple([p.moveType(self.side) for p in md.returns],
const=1, ref=1),
'aParam')
destructexpr = ExprCall(ExprVar('Tie'),
args=[ p.var() for p in md.returns ])
else:
- resolvedecl = Decl(md.returns[0].bareType(self.side), 'aParam')
+ resolvedecl = Decl(md.returns[0].moveType(self.side), 'aParam')
destructexpr = md.returns[0].var()
selfvar = ExprVar('self__')
ifactorisdead = StmtIf(ExprNot(selfvar))
ifactorisdead.addifstmts([_printWarningMessage("Not resolving promise because actor is dead."),
StmtReturn()])
ifactorisdestroyed = StmtIf(ExprBinary(self.protocol.stateVar(), '==',
self.protocol.deadState()))
ifactorisdestroyed.addifstmts([_printWarningMessage("Not resolving promise because actor is destroyed."),
@@ -4307,17 +4319,17 @@ class _GenerateProtocolActorCode(ipdl.as
ifactorisdestroyed ]
resolverfn = ExprLambda([ExprVar.THIS, selfvar, routingId, seqno],
[resolvedecl])
resolverfn.addstmts(returnifactorisdead
+ [ StmtDecl(Decl(Type.BOOL, resolve.name),
init=ExprLiteral.TRUE) ]
+ [ StmtDecl(Decl(p.bareType(self.side), p.var().name))
for p in md.returns ]
- + [ StmtExpr(ExprAssn(destructexpr, ExprVar('aParam'))),
+ + [ StmtExpr(ExprAssn(destructexpr, ExprMove(ExprVar('aParam')))),
StmtDecl(Decl(Type('IPC::Message', ptr=1), self.replyvar.name),
init=ExprCall(ExprVar(md.pqReplyCtorFunc()),
args=[ routingId ])) ]
+ [ self.checkedWrite(None, resolve, self.replyvar,
sentinelKey=resolve.name) ]
+ [ self.checkedWrite(r.ipdltype, r.var(), self.replyvar,
sentinelKey=r.name)
for r in md.returns ])