зеркало из https://github.com/mozilla/pjs.git
bug 506171: rewrite lower.py and add native IPDL arrays.
This commit is contained in:
Родитель
c0129fa14f
Коммит
36a356411a
|
@ -672,7 +672,7 @@ PBrowserStreamChild*
|
|||
PluginInstanceChild::AllocPBrowserStream(const nsCString& url,
|
||||
const uint32_t& length,
|
||||
const uint32_t& lastmodified,
|
||||
const PStreamNotifyChild* notifyData,
|
||||
PStreamNotifyChild* notifyData,
|
||||
const nsCString& headers,
|
||||
const nsCString& mimeType,
|
||||
const bool& seekable,
|
||||
|
|
|
@ -97,7 +97,7 @@ protected:
|
|||
AllocPBrowserStream(const nsCString& url,
|
||||
const uint32_t& length,
|
||||
const uint32_t& lastmodified,
|
||||
const PStreamNotifyChild* notifyData,
|
||||
PStreamNotifyChild* notifyData,
|
||||
const nsCString& headers,
|
||||
const nsCString& mimeType,
|
||||
const bool& seekable,
|
||||
|
|
|
@ -84,7 +84,7 @@ PBrowserStreamParent*
|
|||
PluginInstanceParent::AllocPBrowserStream(const nsCString& url,
|
||||
const uint32_t& length,
|
||||
const uint32_t& lastmodified,
|
||||
const PStreamNotifyParent* notifyData,
|
||||
PStreamNotifyParent* notifyData,
|
||||
const nsCString& headers,
|
||||
const nsCString& mimeType,
|
||||
const bool& seekable,
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
AllocPBrowserStream(const nsCString& url,
|
||||
const uint32_t& length,
|
||||
const uint32_t& lastmodified,
|
||||
const PStreamNotifyParent* notifyData,
|
||||
PStreamNotifyParent* notifyData,
|
||||
const nsCString& headers,
|
||||
const nsCString& mimeType,
|
||||
const bool& seekable,
|
||||
|
|
|
@ -54,8 +54,9 @@ def typecheck(ast, errout=sys.stderr):
|
|||
|
||||
def gencxx(ast, outdir):
|
||||
for hdr in LowerToCxx().lower(ast):
|
||||
file = os.path.join(outdir,
|
||||
*([ns.namespace for ns in ast.protocol.namespaces] + [hdr.filename]))
|
||||
file = os.path.join(
|
||||
outdir,
|
||||
*([ns.name for ns in ast.protocol.namespaces] + [hdr.name]))
|
||||
|
||||
tempfile = StringIO()
|
||||
CxxCodeGen(tempfile).cgen(hdr)
|
||||
|
|
|
@ -151,7 +151,7 @@ class NamespacedNode(Node):
|
|||
|
||||
def qname(self):
|
||||
return QualifiedId(self.loc, self.name,
|
||||
[ ns.namespace for ns in self.namespaces ])
|
||||
[ ns.name for ns in self.namespaces ])
|
||||
|
||||
class TranslationUnit(Node):
|
||||
def __init__(self):
|
||||
|
@ -242,7 +242,7 @@ _prettyTable = {
|
|||
class Namespace(Node):
|
||||
def __init__(self, loc, namespace):
|
||||
Node.__init__(self, loc)
|
||||
self.namespace = namespace
|
||||
self.name = namespace
|
||||
|
||||
class Protocol(NamespacedNode):
|
||||
def __init__(self, loc):
|
||||
|
@ -363,10 +363,11 @@ class Param(Node):
|
|||
self.typespec = typespec
|
||||
|
||||
class TypeSpec(Node):
|
||||
def __init__(self, loc, spec, state=None):
|
||||
def __init__(self, loc, spec, state=None, array=0):
|
||||
Node.__init__(self, loc)
|
||||
self.spec = spec
|
||||
self.state = state
|
||||
self.array = array
|
||||
|
||||
def basename(self):
|
||||
return self.spec.baseid
|
||||
|
|
|
@ -68,5 +68,6 @@ Includes = (
|
|||
'nscore.h',
|
||||
'IPC/IPCMessageUtils.h',
|
||||
'nsStringGlue.h',
|
||||
'nsTArray.h',
|
||||
'mozilla/ipc/ProtocolUtils.h',
|
||||
)
|
||||
|
|
|
@ -138,9 +138,16 @@ class Visitor:
|
|||
def visitExprDeref(self, ed):
|
||||
self.visitExprPrefixUnop(ed)
|
||||
|
||||
def visitExprNot(self, en):
|
||||
self.visitExprPrefixUnop(en)
|
||||
|
||||
def visitExprCast(self, ec):
|
||||
ec.expr.accept(self)
|
||||
|
||||
def visitExprIndex(self, ei):
|
||||
ei.arr.accept(self)
|
||||
ei.idx.accept(self)
|
||||
|
||||
def visitExprSelect(self, es):
|
||||
es.obj.accept(self)
|
||||
|
||||
|
@ -154,7 +161,13 @@ class Visitor:
|
|||
arg.accept(self)
|
||||
|
||||
def visitExprNew(self, en):
|
||||
self.visitExprCall(en)
|
||||
en.ctype.accept(self)
|
||||
if en.newargs is not None:
|
||||
for arg in en.newargs:
|
||||
arg.accept(self)
|
||||
if en.args is not None:
|
||||
for arg in en.args:
|
||||
arg.accept(self)
|
||||
|
||||
def visitExprDelete(self, ed):
|
||||
ed.obj.accept(self)
|
||||
|
@ -188,6 +201,14 @@ class Visitor:
|
|||
if si.elseb is not None:
|
||||
si.elseb.accept(self)
|
||||
|
||||
def visitStmtFor(self, sf):
|
||||
if sf.init is not None:
|
||||
sf.init.accept(self)
|
||||
if sf.cond is not None:
|
||||
sf.cond.accept(self)
|
||||
if sf.update is not None:
|
||||
sf.update.accept(self)
|
||||
|
||||
def visitStmtSwitch(self, ss):
|
||||
ss.expr.accept(self)
|
||||
self.visitBlock(ss)
|
||||
|
@ -216,26 +237,37 @@ class Node:
|
|||
class Whitespace(Node):
|
||||
# yes, this is silly. but we need to stick comments in the
|
||||
# generated code without resorting to more serious hacks
|
||||
def __init__(self, ws):
|
||||
def __init__(self, ws, indent=0):
|
||||
Node.__init__(self)
|
||||
self.ws = ws
|
||||
self.indent = indent
|
||||
Whitespace.NL = Whitespace('\n')
|
||||
|
||||
class File(Node):
|
||||
def __init__(self, filename):
|
||||
Node.__init__(self)
|
||||
self.filename = filename
|
||||
self.name = filename
|
||||
# array of stuff in the file --- stmts and preprocessor thingies
|
||||
self.stuff = [ ]
|
||||
|
||||
def addthing(self, thing):
|
||||
assert thing is not None
|
||||
assert not isinstance(thing, list)
|
||||
self.stuff.append(thing)
|
||||
|
||||
def addthings(self, things):
|
||||
for t in things: self.addthing(t)
|
||||
|
||||
# "look like" a Block so code doesn't have to care whether they're
|
||||
# in global scope or not
|
||||
def addstmt(self, stmt):
|
||||
assert stmt is not None
|
||||
assert not isinstance(stmt, list)
|
||||
self.stuff.append(stmt)
|
||||
|
||||
def addstmts(self, stmts):
|
||||
for s in stmts: self.addstmt(s)
|
||||
|
||||
class CppDirective(Node):
|
||||
'''represents |#[directive] [rest]|, where |rest| is any string'''
|
||||
def __init__(self, directive, rest):
|
||||
|
@ -249,11 +281,12 @@ class Block(Node):
|
|||
self.stmts = [ ]
|
||||
|
||||
def addstmt(self, stmt):
|
||||
assert stmt is not None
|
||||
assert not isinstance(stmt, list)
|
||||
self.stmts.append(stmt)
|
||||
|
||||
def addstmts(self, stmts):
|
||||
for stmt in stmts:
|
||||
self.addstmt(stmt)
|
||||
for s in stmts: self.addstmt(s)
|
||||
|
||||
##------------------------------
|
||||
# type and decl thingies
|
||||
|
@ -268,7 +301,7 @@ class Type(Node):
|
|||
def __init__(self, name, const=0,
|
||||
ptr=0, ptrconst=0, ptrptr=0, ptrconstptr=0,
|
||||
ref=0,
|
||||
actor=0):
|
||||
T=None):
|
||||
"""
|
||||
To avoid getting fancy with recursive types, we limit the kinds
|
||||
of pointer types that can be be constructed.
|
||||
|
@ -279,10 +312,10 @@ of pointer types that can be be constructed.
|
|||
ptrconstptr => T* const*
|
||||
|
||||
Any type, naked or pointer, can be const (const T) or ref (T&).
|
||||
|
||||
The "actor" flag is used internally when we need to know if the C++
|
||||
type actually represents an IPDL actor type.
|
||||
"""
|
||||
assert isinstance(name, str)
|
||||
assert not isinstance(const, str)
|
||||
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.const = const
|
||||
|
@ -291,7 +324,7 @@ type actually represents an IPDL actor type.
|
|||
self.ptrptr = ptrptr
|
||||
self.ptrconstptr = ptrconstptr
|
||||
self.ref = ref
|
||||
self.actor = actor
|
||||
self.T = T
|
||||
# XXX could get serious here with recursive types, but shouldn't
|
||||
# need that for this codegen
|
||||
def __deepcopy__(self, memo):
|
||||
|
@ -299,7 +332,12 @@ type actually represents an IPDL actor type.
|
|||
const=self.const,
|
||||
ptr=self.ptr, ptrconst=self.ptrconst,
|
||||
ptrptr=self.ptrptr, ptrconstptr=self.ptrconstptr,
|
||||
ref=self.ref, actor=self.actor)
|
||||
ref=self.ref,
|
||||
T=copy.deepcopy(self.T, memo))
|
||||
Type.BOOL = Type('bool')
|
||||
Type.INT = Type('int')
|
||||
Type.INTPTR = Type('intptr_t')
|
||||
Type.UINT32 = Type('uint32_t')
|
||||
|
||||
class TypeArray(Node):
|
||||
def __init__(self, basetype, nmemb):
|
||||
|
@ -323,12 +361,10 @@ class TypeUnion(Node):
|
|||
def __init__(self, name=None):
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.components = [ ] # pairs of (Type, name)
|
||||
self.componentDecls = [ ] # [ Decl ]
|
||||
self.components = [ ] # [ Decl ]
|
||||
|
||||
def addComponent(self, type, name):
|
||||
self.components.append((type, name))
|
||||
self.componentDecls.append(Decl(type, name))
|
||||
self.components.append(Decl(type, name))
|
||||
|
||||
class Typedef(Node):
|
||||
def __init__(self, fromtype, totypename):
|
||||
|
@ -349,6 +385,10 @@ class ForwardDecl(Node):
|
|||
class Decl(Node):
|
||||
'''represents |Foo bar|, e.g. in a function signature'''
|
||||
def __init__(self, type, name):
|
||||
assert type is not None
|
||||
assert not isinstance(type, str)
|
||||
assert isinstance(name, str)
|
||||
|
||||
Node.__init__(self)
|
||||
self.type = type
|
||||
self.name = name
|
||||
|
@ -376,9 +416,10 @@ class Class(Block):
|
|||
self.struct = struct # bool
|
||||
|
||||
class Inherit(Node):
|
||||
def __init__(self, name, viz='public'):
|
||||
def __init__(self, type, viz='public'):
|
||||
assert isinstance(viz, str)
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.viz = viz
|
||||
|
||||
class FriendClassDecl(Node):
|
||||
|
@ -388,12 +429,15 @@ class FriendClassDecl(Node):
|
|||
|
||||
class MethodDecl(Node):
|
||||
def __init__(self, name, params=[ ], ret=Type('void'),
|
||||
virtual=0, const=0, pure=0, static=0, typeop=0):
|
||||
virtual=0, const=0, pure=0, static=0,
|
||||
typeop=None):
|
||||
assert not (virtual and static)
|
||||
assert not pure or virtual # pure => virtual
|
||||
assert not (static and typeop)
|
||||
assert not (name and typeop)
|
||||
assert name is None or isinstance(name, str)
|
||||
|
||||
if typeop:
|
||||
if typeop is not None:
|
||||
ret = None
|
||||
|
||||
Node.__init__(self)
|
||||
|
@ -404,8 +448,8 @@ class MethodDecl(Node):
|
|||
self.const = const # bool
|
||||
self.pure = pure # bool
|
||||
self.static = static # bool
|
||||
self.typeop = typeop # bool
|
||||
|
||||
self.typeop = typeop # Type or None
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return MethodDecl(self.name,
|
||||
copy.deepcopy(self.params, memo),
|
||||
|
@ -443,6 +487,14 @@ class DestructorDefn(MethodDefn):
|
|||
|
||||
##------------------------------
|
||||
# expressions
|
||||
class ExprVar(Node):
|
||||
def __init__(self, name):
|
||||
assert isinstance(name, str)
|
||||
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
ExprVar.THIS = ExprVar('this')
|
||||
|
||||
class ExprLiteral(Node):
|
||||
def __init__(self, value, type):
|
||||
'''|type| is a Python format specifier; 'd' for example'''
|
||||
|
@ -464,17 +516,18 @@ class ExprLiteral(Node):
|
|||
ExprLiteral.ZERO = ExprLiteral.Int(0)
|
||||
ExprLiteral.ONE = ExprLiteral.Int(1)
|
||||
ExprLiteral.NULL = ExprLiteral.ZERO
|
||||
|
||||
class ExprVar(Node):
|
||||
def __init__(self, name):
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
ExprLiteral.TRUE = ExprVar('true')
|
||||
ExprLiteral.FALSE = ExprVar('false')
|
||||
|
||||
class ExprPrefixUnop(Node):
|
||||
def __init__(self, expr, op):
|
||||
self.expr = expr
|
||||
self.op = op
|
||||
|
||||
class ExprNot(ExprPrefixUnop):
|
||||
def __init__(self, expr):
|
||||
ExprPrefixUnop.__init__(self, expr, '!')
|
||||
|
||||
class ExprAddrOf(ExprPrefixUnop):
|
||||
def __init__(self, expr):
|
||||
ExprPrefixUnop.__init__(self, expr, '&')
|
||||
|
@ -510,9 +563,19 @@ class ExprConditional(Node):
|
|||
self.cond = cond
|
||||
self.ife = ife
|
||||
self.elsee = elsee
|
||||
|
||||
|
||||
class ExprIndex(Node):
|
||||
def __init__(self, arr, idx):
|
||||
Node.__init__(self)
|
||||
self.arr = arr
|
||||
self.idx = idx
|
||||
|
||||
class ExprSelect(Node):
|
||||
def __init__(self, obj, op, field):
|
||||
assert obj and op and field
|
||||
assert not isinstance(obj, str)
|
||||
assert isinstance(field, str)
|
||||
|
||||
Node.__init__(self)
|
||||
self.obj = obj
|
||||
self.op = op
|
||||
|
@ -527,20 +590,21 @@ class ExprAssn(Node):
|
|||
|
||||
class ExprCall(Node):
|
||||
def __init__(self, func, args=[ ]):
|
||||
assert hasattr(func, 'accept')
|
||||
assert isinstance(args, list)
|
||||
|
||||
Node.__init__(self)
|
||||
self.func = func
|
||||
self.args = args
|
||||
|
||||
class ExprNew(ExprCall):
|
||||
class ExprNew(Node):
|
||||
# XXX taking some poetic license ...
|
||||
def __init__(self, type, args=[ ], newargs=None):
|
||||
assert not (type.const or type.ref)
|
||||
|
||||
ctorname = type.name
|
||||
if type.ptr: ctorname += '*'
|
||||
elif type.ptrptr: ctorname += '**'
|
||||
|
||||
ExprCall.__init__(self, ExprVar(ctorname), args)
|
||||
def __init__(self, ctype, args=[ ], newargs=None):
|
||||
assert not (ctype.const or ctype.ref)
|
||||
|
||||
Node.__init__(self)
|
||||
self.ctype = ctype
|
||||
self.args = args
|
||||
self.newargs = newargs
|
||||
|
||||
class ExprDelete(Node):
|
||||
|
@ -559,14 +623,20 @@ class ExprSizeof(ExprCall):
|
|||
##------------------------------
|
||||
# statements etc.
|
||||
class StmtBlock(Block):
|
||||
def __init__(self):
|
||||
def __init__(self, stmts=[ ]):
|
||||
Block.__init__(self)
|
||||
self.addstmts(stmts)
|
||||
|
||||
class StmtDecl(Node):
|
||||
def __init__(self, decl, init=None):
|
||||
def __init__(self, decl, init=None, initargs=None):
|
||||
assert not (init and initargs)
|
||||
assert not isinstance(init, str) # easy to confuse with Decl
|
||||
assert not isinstance(decl, tuple)
|
||||
|
||||
Node.__init__(self)
|
||||
self.decl = decl
|
||||
self.init = init
|
||||
self.initargs = initargs
|
||||
|
||||
class Label(Node):
|
||||
def __init__(self, name):
|
||||
|
@ -591,12 +661,28 @@ class StmtIf(Node):
|
|||
self.cond = cond
|
||||
self.ifb = Block()
|
||||
self.elseb = None
|
||||
|
||||
def addifstmt(self, stmt):
|
||||
self.ifb.addstmt(stmt)
|
||||
|
||||
def addifstmts(self, stmts):
|
||||
self.ifb.addstmts(stmts)
|
||||
|
||||
def addelsestmt(self, stmt):
|
||||
if self.elseb is None: self.elseb = Block()
|
||||
self.elseb.addstmt(stmt)
|
||||
|
||||
def addelsestmts(self, stmts):
|
||||
if self.elseb is None: self.elseb = Block()
|
||||
self.elseb.addstmts(stmts)
|
||||
|
||||
class StmtFor(Block):
|
||||
def __init__(self, init=None, cond=None, update=None):
|
||||
Block.__init__(self)
|
||||
self.init = init
|
||||
self.cond = cond
|
||||
self.update = update
|
||||
|
||||
class StmtSwitch(Block):
|
||||
def __init__(self, expr):
|
||||
Block.__init__(self)
|
||||
|
@ -605,6 +691,11 @@ class StmtSwitch(Block):
|
|||
|
||||
def addcase(self, case, block):
|
||||
'''NOTE: |case| is not checked for uniqueness'''
|
||||
assert (isinstance(block, StmtBreak)
|
||||
or isinstance(block, StmtReturn)
|
||||
or (hasattr(block, 'stmts')
|
||||
and (isinstance(block.stmts[-1], StmtBreak)
|
||||
or isinstance(block.stmts[-1], StmtReturn))))
|
||||
self.addstmt(case)
|
||||
self.addstmt(block)
|
||||
self.nr_cases += 1
|
||||
|
|
|
@ -43,6 +43,8 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
cxxfile.accept(self)
|
||||
|
||||
def visitWhitespace(self, ws):
|
||||
if ws.indent:
|
||||
self.printdent('')
|
||||
self.write(ws.ws)
|
||||
|
||||
def visitCppDirective(self, cd):
|
||||
|
@ -54,11 +56,17 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.println('} // namespace '+ ns.name)
|
||||
|
||||
def visitType(self, t):
|
||||
if t.const:
|
||||
self.write('const ')
|
||||
|
||||
self.write(t.name)
|
||||
|
||||
if t.T is not None:
|
||||
self.write('<')
|
||||
t.T.accept(self)
|
||||
self.write('>')
|
||||
|
||||
ts = ''
|
||||
|
||||
if t.const: ts += 'const '
|
||||
ts += t.name
|
||||
|
||||
if t.ptr: ts += '*'
|
||||
elif t.ptrconst: ts += '* const'
|
||||
elif t.ptrptr: ts += '**'
|
||||
|
@ -85,7 +93,6 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.println()
|
||||
self.dedent()
|
||||
self.printdent('}')
|
||||
|
||||
|
||||
def visitTypeUnion(self, u):
|
||||
self.write('union')
|
||||
|
@ -94,7 +101,7 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.println(' {')
|
||||
|
||||
self.indent()
|
||||
for decl in u.componentDecls:
|
||||
for decl in u.components:
|
||||
self.printdent()
|
||||
decl.accept(self)
|
||||
self.println(';')
|
||||
|
@ -173,7 +180,8 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.printdentln('};')
|
||||
|
||||
def visitInherit(self, inh):
|
||||
self.write(inh.viz +' '+ inh.name)
|
||||
self.write(inh.viz +' ')
|
||||
inh.type.accept(self)
|
||||
|
||||
def visitFriendClassDecl(self, fcd):
|
||||
self.printdentln('friend class '+ fcd.friend +';')
|
||||
|
@ -189,9 +197,16 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
if md.ret:
|
||||
md.ret.accept(self)
|
||||
self.write(' ')
|
||||
self.write(md.name +'(')
|
||||
if md.typeop is not None:
|
||||
self.write('operator ')
|
||||
md.typeop.accept(self)
|
||||
else:
|
||||
self.write(md.name)
|
||||
|
||||
self.write('(')
|
||||
self.writeDeclList(md.params)
|
||||
self.write(')')
|
||||
|
||||
if md.const:
|
||||
self.write(' const')
|
||||
if md.pure:
|
||||
|
@ -265,10 +280,12 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.write(ev.name)
|
||||
|
||||
def visitExprPrefixUnop(self, e):
|
||||
self.write('(')
|
||||
self.write(e.op)
|
||||
self.write('(')
|
||||
e.expr.accept(self)
|
||||
self.write(')')
|
||||
self.write(')')
|
||||
|
||||
def visitExprCast(self, c):
|
||||
pfx, sfx = '', ''
|
||||
|
@ -299,8 +316,16 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
c.elsee.accept(self)
|
||||
self.write(')')
|
||||
|
||||
def visitExprIndex(self, ei):
|
||||
ei.arr.accept(self)
|
||||
self.write('[')
|
||||
ei.idx.accept(self)
|
||||
self.write(']')
|
||||
|
||||
def visitExprSelect(self, es):
|
||||
self.write('(')
|
||||
es.obj.accept(self)
|
||||
self.write(')')
|
||||
self.write(es.op + es.field)
|
||||
|
||||
def visitExprAssn(self, ea):
|
||||
|
@ -320,11 +345,15 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.write('(')
|
||||
self.writeExprList(en.newargs)
|
||||
self.write(') ')
|
||||
self.visitExprCall(en)
|
||||
en.ctype.accept(self)
|
||||
if en.args is not None:
|
||||
self.write('(')
|
||||
self.writeExprList(en.args)
|
||||
self.write(')')
|
||||
|
||||
def visitExprDelete(self, ed):
|
||||
self.write('delete ')
|
||||
ed.accept(self)
|
||||
ed.obj.accept(self)
|
||||
|
||||
|
||||
def visitStmtBlock(self, b):
|
||||
|
@ -367,6 +396,24 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.printdentln('}')
|
||||
|
||||
|
||||
def visitStmtFor(self, sf):
|
||||
self.printdent('for (')
|
||||
if sf.init is not None:
|
||||
sf.init.accept(self)
|
||||
self.write('; ')
|
||||
if sf.cond is not None:
|
||||
sf.cond.accept(self)
|
||||
self.write('; ')
|
||||
if sf.update is not None:
|
||||
sf.update.accept(self)
|
||||
self.println(') {')
|
||||
|
||||
self.indent()
|
||||
self.visitBlock(sf)
|
||||
self.dedent()
|
||||
self.printdentln('}')
|
||||
|
||||
|
||||
def visitStmtSwitch(self, sw):
|
||||
self.printdent('switch (')
|
||||
sw.expr.accept(self)
|
||||
|
@ -383,6 +430,10 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
def visitStmtDecl(self, sd):
|
||||
self.printdent()
|
||||
sd.decl.accept(self)
|
||||
if sd.initargs is not None:
|
||||
self.write('(')
|
||||
self.writeDeclList(sd.initargs)
|
||||
self.write(')')
|
||||
if sd.init is not None:
|
||||
self.write(' = ')
|
||||
sd.init.accept(self)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -519,8 +519,15 @@ def p_Param(p):
|
|||
p[0] = Param(locFromTok(p, 1), p[1], p[2])
|
||||
|
||||
def p_Type(p):
|
||||
"""Type : ActorType
|
||||
| CxxID""" # ID == CxxType; we forbid qnames here,
|
||||
"""Type : ScalarType
|
||||
| ScalarType '[' ']'"""
|
||||
if 4 == len(p):
|
||||
p[1].array = 1
|
||||
p[0] = p[1]
|
||||
|
||||
def p_ScalarType(p):
|
||||
"""ScalarType : ActorType
|
||||
| CxxID""" # ID == CxxType; we forbid qnames here,
|
||||
# in favor of the |using| declaration
|
||||
if isinstance(p[1], TypeSpec):
|
||||
p[0] = p[1]
|
||||
|
|
|
@ -35,7 +35,58 @@ import os, sys
|
|||
from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, TypeSpec, UsingStmt, Visitor, ASYNC, SYNC, RPC, IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
|
||||
import ipdl.builtin as builtin
|
||||
|
||||
|
||||
class TypeVisitor:
|
||||
def defaultVisit(self, node, *args):
|
||||
raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% (
|
||||
node.__class__.__name__)
|
||||
|
||||
def visitVoidType(self, v, *args):
|
||||
pass
|
||||
|
||||
def visitBuiltinCxxType(self, t, *args):
|
||||
pass
|
||||
|
||||
def visitImportedCxxType(self, t, *args):
|
||||
pass
|
||||
|
||||
def visitStateType(self, s, *args):
|
||||
pass
|
||||
|
||||
def visitMessageType(self, m, *args):
|
||||
for param in m.params:
|
||||
param.accept(self, *args)
|
||||
for ret in m.returns:
|
||||
ret.accept(self, *args)
|
||||
if m.cdtype is not None:
|
||||
m.cdtype.accept(self, *args)
|
||||
|
||||
def visitProtocolType(self, p, *args):
|
||||
# NB: don't visit manager and manages. a naive default impl
|
||||
# could result in an infinite loop
|
||||
pass
|
||||
|
||||
def visitActorType(self, a, *args):
|
||||
a.protocol.accept(self, *args)
|
||||
a.state.accept(self, *args)
|
||||
|
||||
def visitUnionType(self, u, *args):
|
||||
for component in u.components:
|
||||
component.accept(self, *args)
|
||||
|
||||
def visitArrayType(self, a, *args):
|
||||
a.basetype.accept(self, *args)
|
||||
|
||||
|
||||
class Type:
|
||||
def __cmp__(self, o):
|
||||
return cmp(self.fullname(), o.fullname())
|
||||
def __eq__(self, o):
|
||||
return (self.__class__ == o.__class__
|
||||
and self.fullname() == o.fullname())
|
||||
def __hash__(self):
|
||||
return hash(self.fullname())
|
||||
|
||||
# Is this a C++ type?
|
||||
def isCxx(self):
|
||||
return False
|
||||
|
@ -53,8 +104,14 @@ class Type:
|
|||
def name(self): raise Exception, 'NYI'
|
||||
def fullname(self): raise Exception, 'NYI'
|
||||
|
||||
def accept(self, visitor, *args):
|
||||
visit = getattr(visitor, 'visit'+ self.__class__.__name__, None)
|
||||
if visit is None:
|
||||
return getattr(visitor, 'defaultVisit')(self, *args)
|
||||
return visit(self, *args)
|
||||
|
||||
class VoidType(Type):
|
||||
# the following are not a type-o's (hah): void is both a Cxx and IPDL type
|
||||
# the following are not type-o's (hah): void is both a Cxx and IPDL type
|
||||
def isCxx():
|
||||
return True
|
||||
def isIPDL():
|
||||
|
@ -106,10 +163,6 @@ class ImportedCxxType(CxxType):
|
|||
def fullname(self):
|
||||
return str(self.qname)
|
||||
|
||||
class GeneratedCxxType(CxxType):
|
||||
def isGenerated(self): return True
|
||||
def isVisible(self): return False
|
||||
|
||||
##--------------------
|
||||
class IPDLType(Type):
|
||||
def isIPDL(self): return True
|
||||
|
@ -119,6 +172,7 @@ class IPDLType(Type):
|
|||
def isProtocol(self): return False
|
||||
def isActor(self): return False
|
||||
def isUnion(self): return False
|
||||
def isArray(self): return False
|
||||
|
||||
def isAsync(self): return self.sendSemantics is ASYNC
|
||||
def isSync(self): return self.sendSemantics is SYNC
|
||||
|
@ -219,6 +273,35 @@ class UnionType(IPDLType):
|
|||
def name(self): return self.qname.baseid
|
||||
def fullname(self): return str(self.qname)
|
||||
|
||||
class ArrayType(IPDLType):
|
||||
def __init__(self, basetype):
|
||||
self.basetype = basetype
|
||||
|
||||
def isArray(self): return True
|
||||
def name(self): return self.basetype.name() +'[]'
|
||||
def fullname(self): return self.basetype.fullname() +'[]'
|
||||
|
||||
|
||||
def iteractortypes(type):
|
||||
"""Iterate over any actor(s) buried in |type|."""
|
||||
# XXX |yield| semantics makes it hard to use TypeVisitor
|
||||
if not type or not type.isIPDL():
|
||||
return
|
||||
elif type.isActor():
|
||||
yield type
|
||||
elif type.isArray():
|
||||
for actor in iteractortypes(type.basetype):
|
||||
yield actor
|
||||
elif type.isUnion():
|
||||
for c in type.components:
|
||||
for actor in iteractortypes(c):
|
||||
yield actor
|
||||
|
||||
def hasactor(type):
|
||||
"""Return true iff |type| is an actor or has one buried within."""
|
||||
for _ in iteractortypes(type): return True
|
||||
return False
|
||||
|
||||
##--------------------
|
||||
_builtinloc = Loc('<builtin>', 0)
|
||||
def makeBuiltinUsing(tname):
|
||||
|
@ -448,18 +531,19 @@ class GatherDecls(TcheckVisitor):
|
|||
fullname = str(qname)
|
||||
components = [ ]
|
||||
|
||||
nactors = 0 # FIXME
|
||||
|
||||
for c in ud.components:
|
||||
ctype = self.symtab.lookup(str(c)).type
|
||||
cdecl = self.symtab.lookup(str(c))
|
||||
if cdecl is None:
|
||||
self.error(c.loc, "unknown component type `%s' of union `%s'",
|
||||
str(c), ud.name)
|
||||
continue
|
||||
ctype = cdecl.type
|
||||
if ctype.isIPDL() and ctype.isProtocol():
|
||||
ctype = ActorType(ctype)
|
||||
nactors += 1
|
||||
if c.array:
|
||||
ctype = ArrayType(ctype)
|
||||
components.append(ctype)
|
||||
|
||||
if nactors > 1:
|
||||
self.error(ud.loc, 'sorry, IPDL currently limits you to one actor type per union. file a bug against :cjones')
|
||||
|
||||
ud.decl = self.declare(
|
||||
loc=ud.loc,
|
||||
type=UnionType(qname, components),
|
||||
|
@ -537,22 +621,30 @@ class GatherDecls(TcheckVisitor):
|
|||
|
||||
# visit the message decls once more and resolve the state names
|
||||
# attached to actor params and returns
|
||||
def resolvestate(param):
|
||||
if param.type.state is None:
|
||||
def resolvestate(loc, actortype):
|
||||
assert actortype.isIPDL() and actortype.isActor()
|
||||
|
||||
# already resolved this guy's state
|
||||
if isinstance(actortype.state, Decl):
|
||||
return
|
||||
|
||||
if actortype.state is None:
|
||||
# we thought this was a C++ type until type checking,
|
||||
# when we realized it was an IPDL actor type. But
|
||||
# that means that the actor wasn't specified to be in
|
||||
# any particular state
|
||||
param.type.state = State.ANY
|
||||
actortype.state = State.ANY
|
||||
|
||||
loc = param.loc
|
||||
statename = param.type.state.name
|
||||
statename = actortype.state.name
|
||||
# FIXME/cjones: this is just wrong. we need the symbol table
|
||||
# of the protocol this actor refers to. low priority bug
|
||||
# since nobody's using this feature yet
|
||||
statedecl = self.symtab.lookup(statename)
|
||||
if statedecl is None:
|
||||
self.error(
|
||||
loc,
|
||||
"protocol `%s' does not have the state `%s'",
|
||||
param.type.protocol.name(),
|
||||
actortype.protocol.name(),
|
||||
statename)
|
||||
elif not statedecl.type.isState():
|
||||
self.error(
|
||||
|
@ -561,15 +653,17 @@ class GatherDecls(TcheckVisitor):
|
|||
statename,
|
||||
statedecl.type.typename())
|
||||
else:
|
||||
param.type.state = statedecl
|
||||
actortype.state = statedecl
|
||||
|
||||
for msg in p.messageDecls:
|
||||
for iparam in msg.inParams:
|
||||
if iparam.type and iparam.type.isIPDL() and iparam.type.isActor():
|
||||
resolvestate(iparam)
|
||||
loc = iparam.loc
|
||||
for actortype in iteractortypes(iparam.type):
|
||||
resolvestate(loc, actortype)
|
||||
for oparam in msg.outParams:
|
||||
if oparam.type and oparam.type.isIPDL() and oparam.type.isActor():
|
||||
resolvestate(oparam)
|
||||
loc = oparam.loc
|
||||
for actortype in iteractortypes(oparam.type):
|
||||
resolvestate(loc, actortype)
|
||||
|
||||
# FIXME/cjones declare all the little C++ thingies that will
|
||||
# be generated. they're not relevant to IPDL itself, but
|
||||
|
@ -687,6 +781,10 @@ class GatherDecls(TcheckVisitor):
|
|||
param.typespec.state)
|
||||
else:
|
||||
ptype = ptdecl.type
|
||||
|
||||
if param.typespec.array:
|
||||
ptype = ArrayType(ptype)
|
||||
|
||||
return self.declare(
|
||||
loc=ploc,
|
||||
type=ptype,
|
||||
|
|
|
@ -56,11 +56,12 @@ LIBXUL_LIBRARY = 1
|
|||
FORCE_STATIC_LIB = 1
|
||||
EXPORT_LIBRARY = 1
|
||||
|
||||
|
||||
IPDLTESTS = \
|
||||
# Please keep these organized in the order "easy"-to-"hard"
|
||||
IPDLTESTS = \
|
||||
TestSanity \
|
||||
TestLatency \
|
||||
TestManyChildAllocs \
|
||||
TestSanity \
|
||||
TestArrays \
|
||||
$(NULL)
|
||||
|
||||
IPDLTESTSRCS = $(addsuffix .cpp,$(IPDLTESTS))
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
include protocol "PTestArraysSub.ipdl";
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
union IntDouble {
|
||||
int;
|
||||
double;
|
||||
};
|
||||
|
||||
union IntDoubleArrays {
|
||||
int;
|
||||
int[];
|
||||
double[];
|
||||
};
|
||||
|
||||
union Actors {
|
||||
int;
|
||||
int[];
|
||||
PTestArraysSub[];
|
||||
};
|
||||
|
||||
union Unions {
|
||||
int;
|
||||
int[];
|
||||
PTestArraysSub[];
|
||||
Actors[];
|
||||
};
|
||||
|
||||
|
||||
sync protocol PTestArrays {
|
||||
manages PTestArraysSub;
|
||||
|
||||
child:
|
||||
PTestArraysSub(int i);
|
||||
|
||||
Start();
|
||||
|
||||
parent:
|
||||
~PTestArraysSub();
|
||||
|
||||
sync Test1(int[] i1)
|
||||
returns (int[] o1);
|
||||
|
||||
sync Test2(PTestArraysSub[] i1)
|
||||
returns (PTestArraysSub[] o1);
|
||||
|
||||
sync Test3(IntDouble i1,
|
||||
IntDouble i2)
|
||||
returns (IntDouble o1,
|
||||
IntDouble o2);
|
||||
|
||||
sync Test4(IntDouble[] i1)
|
||||
returns (IntDouble[] o1);
|
||||
|
||||
sync Test5(IntDoubleArrays i1,
|
||||
IntDoubleArrays i2,
|
||||
IntDoubleArrays i3)
|
||||
returns (IntDoubleArrays o1,
|
||||
IntDoubleArrays o2,
|
||||
IntDoubleArrays o3);
|
||||
|
||||
sync Test6(IntDoubleArrays[] i1)
|
||||
returns (IntDoubleArrays[] o1);
|
||||
|
||||
sync Test7(Actors i1,
|
||||
Actors i2,
|
||||
Actors i3)
|
||||
returns (Actors o1,
|
||||
Actors o2,
|
||||
Actors o3);
|
||||
|
||||
sync Test8(Actors[] i1)
|
||||
returns (Actors[] o1);
|
||||
|
||||
sync Test9(Unions i1,
|
||||
Unions i2,
|
||||
Unions i3,
|
||||
Unions i4)
|
||||
returns (Unions o1,
|
||||
Unions o2,
|
||||
Unions o3,
|
||||
Unions o4);
|
||||
|
||||
sync Test10(Unions[] i1)
|
||||
returns (Unions[] o1);
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
include protocol "PTestArrays.ipdl";
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
protocol PTestArraysSub {
|
||||
manager PTestArrays;
|
||||
// empty
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,555 @@
|
|||
#include "TestArrays.h"
|
||||
|
||||
#include "nsIAppShell.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsServiceManagerUtils.h" // do_GetService()
|
||||
#include "nsWidgetsCID.h" // NS_APPSHELL_CID
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
static const uint32_t nactors = 10;
|
||||
|
||||
#define test_assert(_cond, _msg) \
|
||||
if (!(_cond)) fail(_msg)
|
||||
|
||||
template<typename T>
|
||||
static void
|
||||
assert_arrays_equal(nsTArray<T> a, nsTArray<T> b)
|
||||
{
|
||||
test_assert(a.Length() == b.Length(), "Length()s different");
|
||||
for (uint32_t i = 0; i < a.Length(); ++i)
|
||||
test_assert(a[i] == b[i], "values different");
|
||||
}
|
||||
|
||||
inline static TestArraysSub&
|
||||
Cast(PTestArraysSubParent* a)
|
||||
{
|
||||
return *static_cast<TestArraysSub*>(a);
|
||||
}
|
||||
|
||||
inline static TestArraysSub&
|
||||
Cast(PTestArraysSubChild* a)
|
||||
{
|
||||
return *static_cast<TestArraysSub*>(a);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parent
|
||||
|
||||
TestArraysParent::TestArraysParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestArraysParent);
|
||||
}
|
||||
|
||||
TestArraysParent::~TestArraysParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestArraysParent);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysParent::Main()
|
||||
{
|
||||
for (uint32_t i = 0; i < nactors; ++i)
|
||||
if (!SendPTestArraysSubConstructor(i))
|
||||
fail("can't alloc actor");
|
||||
|
||||
if (!SendStart())
|
||||
fail("can't send Start()");
|
||||
}
|
||||
|
||||
bool
|
||||
TestArraysParent::RecvPTestArraysSubDestructor(PTestArraysSubParent* actor)
|
||||
{
|
||||
test_assert(Cast(actor).mI == Cast(mKids[0]).mI,
|
||||
"dtor sent to wrong actor");
|
||||
mKids.RemoveElementAt(0);
|
||||
if (mKids.Length() > 0)
|
||||
return true;
|
||||
|
||||
passed("with flying colors");
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
nsCOMPtr<nsIAppShell> appShell (do_GetService(kAppShellCID));
|
||||
appShell->Exit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest1(
|
||||
const nsTArray<int>& ia,
|
||||
nsTArray<int>* oa)
|
||||
{
|
||||
test_assert(5 == ia.Length(), "wrong length");
|
||||
for (int i = 0; i < 5; ++i)
|
||||
test_assert(i == ia[i], "wrong value");
|
||||
|
||||
*oa = ia;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest2(
|
||||
const nsTArray<PTestArraysSubParent*>& i1,
|
||||
nsTArray<PTestArraysSubParent*>* o1)
|
||||
{
|
||||
test_assert(nactors == i1.Length(), "wrong #actors");
|
||||
for (uint32_t i = 0; i < i1.Length(); ++i)
|
||||
test_assert(i == Cast(i1[i]).mI, "wrong mI value");
|
||||
*o1 = i1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest3(
|
||||
const IntDouble& i1,
|
||||
const IntDouble& i2,
|
||||
IntDouble* o1,
|
||||
IntDouble* o2)
|
||||
{
|
||||
test_assert(42 == i1.get_int(), "wrong value");
|
||||
test_assert(4.0 == i2.get_double(), "wrong value");
|
||||
|
||||
*o1 = i1;
|
||||
*o2 = i2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest4(
|
||||
const nsTArray<IntDouble>& i1,
|
||||
nsTArray<IntDouble>* o1)
|
||||
{
|
||||
test_assert(4 == i1.Length(), "wrong length");
|
||||
test_assert(1 == i1[0].get_int(), "wrong value");
|
||||
test_assert(2.0 == i1[1].get_double(), "wrong value");
|
||||
test_assert(3 == i1[2].get_int(), "wrong value");
|
||||
test_assert(4.0 == i1[3].get_double(), "wrong value");
|
||||
|
||||
*o1 = i1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest5(
|
||||
const IntDoubleArrays& i1,
|
||||
const IntDoubleArrays& i2,
|
||||
const IntDoubleArrays& i3,
|
||||
IntDoubleArrays* o1,
|
||||
IntDoubleArrays* o2,
|
||||
IntDoubleArrays* o3)
|
||||
{
|
||||
test_assert(42 == i1.get_int(), "wrong value");
|
||||
|
||||
const nsTArray<int>& i2a = i2.get_ArrayOfint();
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
const nsTArray<double>& i3a = i3.get_ArrayOfdouble();
|
||||
test_assert(3 == i3a.Length(), "wrong length");
|
||||
test_assert(1.0 == i3a[0], "wrong value");
|
||||
test_assert(2.0 == i3a[1], "wrong value");
|
||||
test_assert(3.0 == i3a[2], "wrong value");
|
||||
|
||||
*o1 = i1;
|
||||
*o2 = i2a;
|
||||
*o3 = i3a;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest6(
|
||||
const nsTArray<IntDoubleArrays>& i1,
|
||||
nsTArray<IntDoubleArrays>* o1)
|
||||
{
|
||||
test_assert(3 == i1.Length(), "wrong length");
|
||||
|
||||
IntDoubleArrays id1(i1[0]);
|
||||
test_assert(42 == id1.get_int(), "wrong value");
|
||||
|
||||
nsTArray<int> i2a = i1[1].get_ArrayOfint();
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
nsTArray<double> i3a = i1[2].get_ArrayOfdouble();
|
||||
test_assert(3 == i3a.Length(), "wrong length");
|
||||
test_assert(1.0 == i3a[0], "wrong value");
|
||||
test_assert(2.0 == i3a[1], "wrong value");
|
||||
test_assert(3.0 == i3a[2], "wrong value");
|
||||
|
||||
o1->AppendElement(id1);
|
||||
o1->AppendElement(IntDoubleArrays(i2a));
|
||||
o1->AppendElement(IntDoubleArrays(i3a));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest7(
|
||||
const Actors& i1,
|
||||
const Actors& i2,
|
||||
const Actors& i3,
|
||||
Actors* o1,
|
||||
Actors* o2,
|
||||
Actors* o3)
|
||||
{
|
||||
test_assert(42 == i1.get_int(), "wrong value");
|
||||
|
||||
nsTArray<int> i2a(i2.get_ArrayOfint());
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
assert_arrays_equal(mKids, i3.get_ArrayOfPTestArraysSubParent());
|
||||
|
||||
*o1 = 42;
|
||||
*o2 = i2a;
|
||||
*o3 = mKids;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest8(
|
||||
const nsTArray<Actors>& i1,
|
||||
nsTArray<Actors>* o1)
|
||||
{
|
||||
test_assert(3 == i1.Length(), "wrong length");
|
||||
test_assert(42 == i1[0].get_int(), "wrong value");
|
||||
|
||||
const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
assert_arrays_equal(mKids, i1[2].get_ArrayOfPTestArraysSubParent());
|
||||
|
||||
*o1 = i1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest9(
|
||||
const Unions& i1,
|
||||
const Unions& i2,
|
||||
const Unions& i3,
|
||||
const Unions& i4,
|
||||
Unions* o1,
|
||||
Unions* o2,
|
||||
Unions* o3,
|
||||
Unions* o4)
|
||||
{
|
||||
test_assert(42 == i1.get_int(), "wrong value");
|
||||
|
||||
const nsTArray<int>& i2a = i2.get_ArrayOfint();
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
assert_arrays_equal(mKids, i3.get_ArrayOfPTestArraysSubParent());
|
||||
|
||||
const nsTArray<PTestArraysSubParent*>& i4a =
|
||||
i4.get_ArrayOfActors()[0].get_ArrayOfPTestArraysSubParent();
|
||||
assert_arrays_equal(mKids, i4a);
|
||||
|
||||
*o1 = i1;
|
||||
*o2 = i2;
|
||||
*o3 = i3;
|
||||
*o4 = i4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestArraysParent::RecvTest10(
|
||||
const nsTArray<Unions>& i1,
|
||||
nsTArray<Unions>* o1)
|
||||
{
|
||||
test_assert(42 == i1[0].get_int(), "wrong value");
|
||||
|
||||
const nsTArray<int>& i2a = i1[1].get_ArrayOfint();
|
||||
test_assert(3 == i2a.Length(), "wrong length");
|
||||
test_assert(1 == i2a[0], "wrong value");
|
||||
test_assert(2 == i2a[1], "wrong value");
|
||||
test_assert(3 == i2a[2], "wrong value");
|
||||
|
||||
assert_arrays_equal(mKids, i1[2].get_ArrayOfPTestArraysSubParent());
|
||||
|
||||
const nsTArray<PTestArraysSubParent*>& i4a =
|
||||
i1[3].get_ArrayOfActors()[0].get_ArrayOfPTestArraysSubParent();
|
||||
assert_arrays_equal(mKids, i4a);
|
||||
|
||||
*o1 = i1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
TestArraysChild::TestArraysChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(TestArraysChild);
|
||||
}
|
||||
|
||||
TestArraysChild::~TestArraysChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TestArraysChild);
|
||||
}
|
||||
|
||||
bool
|
||||
TestArraysChild::RecvStart()
|
||||
{
|
||||
puts("[TestArraysChild] starting");
|
||||
|
||||
Test1();
|
||||
Test2();
|
||||
Test3();
|
||||
Test4();
|
||||
Test5();
|
||||
Test6();
|
||||
Test7();
|
||||
Test8();
|
||||
Test9();
|
||||
Test10();
|
||||
|
||||
for (uint32_t i = 0; i < nactors; ++i)
|
||||
if (!SendPTestArraysSubDestructor(mKids[i]))
|
||||
fail("can't send dtor");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test1()
|
||||
{
|
||||
nsTArray<int> ia;
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
ia.AppendElement(i);
|
||||
|
||||
nsTArray<int> oa;
|
||||
if (!SendTest1(ia, &oa))
|
||||
fail("can't send Test1");
|
||||
|
||||
assert_arrays_equal(ia, oa);
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test2()
|
||||
{
|
||||
nsTArray<PTestArraysSubChild*> oa;
|
||||
if (!SendTest2(mKids, &oa))
|
||||
fail("can't send Test2");
|
||||
assert_arrays_equal(mKids, oa);
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test3()
|
||||
{
|
||||
int i1i = 42;
|
||||
double i2d = 4.0;
|
||||
IntDouble i1(i1i);
|
||||
IntDouble i2(i2d);
|
||||
IntDouble o1, o2;
|
||||
|
||||
SendTest3(i1, i2, &o1, &o2);
|
||||
|
||||
test_assert(i1i == o1.get_int(), "wrong value");
|
||||
test_assert(i2d == o2.get_double(), "wrong value");
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test4()
|
||||
{
|
||||
nsTArray<IntDouble> i1;
|
||||
i1.AppendElement(IntDouble(int(1)));
|
||||
i1.AppendElement(IntDouble(2.0));
|
||||
i1.AppendElement(IntDouble(int(3)));
|
||||
i1.AppendElement(IntDouble(4.0));
|
||||
|
||||
nsTArray<IntDouble> o1;
|
||||
if (!SendTest4(i1, &o1))
|
||||
fail("can't send Test4");
|
||||
|
||||
// TODO Union::operator==()
|
||||
test_assert(i1.Length() == o1.Length(), "wrong length");
|
||||
test_assert(1 == o1[0].get_int(), "wrong value");
|
||||
test_assert(2.0 == o1[1].get_double(), "wrong value");
|
||||
test_assert(3 == o1[2].get_int(), "wrong value");
|
||||
test_assert(4.0 == o1[3].get_double(), "wrong value");
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test5()
|
||||
{
|
||||
IntDoubleArrays i1(int(42));
|
||||
nsTArray<int> i2;
|
||||
i2.AppendElement(1); i2.AppendElement(2); i2.AppendElement(3);
|
||||
nsTArray<double> i3;
|
||||
i3.AppendElement(1.0); i3.AppendElement(2.0); i3.AppendElement(3.0);
|
||||
|
||||
IntDoubleArrays o1, o2, o3;
|
||||
if (!SendTest5(i1, IntDoubleArrays(i2), IntDoubleArrays(i3),
|
||||
&o1, &o2, &o3))
|
||||
fail("can't send Test5");
|
||||
|
||||
test_assert(42 == o1.get_int(), "wrong value");
|
||||
assert_arrays_equal(i2, o2.get_ArrayOfint());
|
||||
assert_arrays_equal(i3, o3.get_ArrayOfdouble());
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test6()
|
||||
{
|
||||
IntDoubleArrays id1(int(42));
|
||||
nsTArray<int> id2;
|
||||
id2.AppendElement(1); id2.AppendElement(2); id2.AppendElement(3);
|
||||
nsTArray<double> id3;
|
||||
id3.AppendElement(1.0); id3.AppendElement(2.0); id3.AppendElement(3.0);
|
||||
|
||||
nsTArray<IntDoubleArrays> i1;
|
||||
i1.AppendElement(id1);
|
||||
i1.AppendElement(IntDoubleArrays(id2));
|
||||
i1.AppendElement(IntDoubleArrays(id3));
|
||||
|
||||
nsTArray<IntDoubleArrays> o1;
|
||||
if (!SendTest6(i1, &o1))
|
||||
fail("can't send Test6");
|
||||
|
||||
test_assert(3 == o1.Length(), "wrong length");
|
||||
IntDoubleArrays od1(o1[0]);
|
||||
nsTArray<int> od2 = o1[1].get_ArrayOfint();
|
||||
nsTArray<double> od3 = o1[2].get_ArrayOfdouble();
|
||||
|
||||
test_assert(42 == od1.get_int(), "wrong value");
|
||||
assert_arrays_equal(id2, od2);
|
||||
assert_arrays_equal(id3, od3);
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test7()
|
||||
{
|
||||
Actors i1(42);
|
||||
nsTArray<int> i2a;
|
||||
i2a.AppendElement(1); i2a.AppendElement(2); i2a.AppendElement(3);
|
||||
|
||||
Actors o1, o2, o3;
|
||||
if (!SendTest7(i1, Actors(i2a), Actors(mKids), &o1, &o2, &o3))
|
||||
fail("can't send Test7");
|
||||
|
||||
test_assert(42 == o1.get_int(), "wrong value");
|
||||
assert_arrays_equal(i2a, o2.get_ArrayOfint());
|
||||
assert_arrays_equal(mKids, o3.get_ArrayOfPTestArraysSubChild());
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test8()
|
||||
{
|
||||
Actors i1e(42);
|
||||
nsTArray<int> i2a;
|
||||
i2a.AppendElement(1); i2a.AppendElement(2); i2a.AppendElement(3);
|
||||
|
||||
nsTArray<Actors> i1;
|
||||
i1.AppendElement(i1e);
|
||||
i1.AppendElement(i2a);
|
||||
i1.AppendElement(mKids);
|
||||
|
||||
nsTArray<Actors> o1;
|
||||
if (!SendTest8(i1, &o1))
|
||||
fail("can't send Test8");
|
||||
|
||||
test_assert(3 == o1.Length(), "wrong length");
|
||||
test_assert(42 == o1[0].get_int(), "wrong value");
|
||||
assert_arrays_equal(i2a, o1[1].get_ArrayOfint());
|
||||
assert_arrays_equal(mKids, o1[2].get_ArrayOfPTestArraysSubChild());
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test9()
|
||||
{
|
||||
Unions i1(int(42));
|
||||
|
||||
nsTArray<int> i2a;
|
||||
i2a.AppendElement(1);
|
||||
i2a.AppendElement(2);
|
||||
i2a.AppendElement(3);
|
||||
|
||||
nsTArray<Actors> i4a;
|
||||
i4a.AppendElement(mKids);
|
||||
|
||||
Unions o1, o2, o3, o4;
|
||||
if (!SendTest9(i1, Unions(i2a), Unions(mKids), Unions(i4a),
|
||||
&o1, &o2, &o3, &o4))
|
||||
fail("can't send Test9");
|
||||
|
||||
test_assert(42 == o1.get_int(), "wrong value");
|
||||
assert_arrays_equal(i2a, o2.get_ArrayOfint());
|
||||
assert_arrays_equal(mKids, o3.get_ArrayOfPTestArraysSubChild());
|
||||
assert_arrays_equal(
|
||||
mKids,
|
||||
o4.get_ArrayOfActors()[0].get_ArrayOfPTestArraysSubChild());
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
TestArraysChild::Test10()
|
||||
{
|
||||
Unions i1a(int(42));
|
||||
|
||||
nsTArray<int> i2a;
|
||||
i2a.AppendElement(1);
|
||||
i2a.AppendElement(2);
|
||||
i2a.AppendElement(3);
|
||||
|
||||
nsTArray<Actors> i4a;
|
||||
i4a.AppendElement(mKids);
|
||||
|
||||
nsTArray<Unions> i1;
|
||||
i1.AppendElement(i1a);
|
||||
i1.AppendElement(Unions(i2a));
|
||||
i1.AppendElement(Unions(mKids));
|
||||
i1.AppendElement(Unions(i4a));
|
||||
|
||||
nsTArray<Unions> o1;
|
||||
if (!SendTest10(i1, &o1))
|
||||
fail("can't send Test10");
|
||||
|
||||
test_assert(4 == o1.Length(), "wrong length");
|
||||
test_assert(42 == o1[0].get_int(), "wrong value");
|
||||
assert_arrays_equal(i2a, o1[1].get_ArrayOfint());
|
||||
assert_arrays_equal(mKids, o1[2].get_ArrayOfPTestArraysSubChild());
|
||||
assert_arrays_equal(
|
||||
mKids,
|
||||
o1[3].get_ArrayOfActors()[0].get_ArrayOfPTestArraysSubChild());
|
||||
|
||||
printf(" passed %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,159 @@
|
|||
#ifndef mozilla__ipdltest_TestArrays_h
|
||||
#define mozilla__ipdltest_TestArrays_h 1
|
||||
|
||||
|
||||
#include "mozilla/_ipdltest/PTestArraysParent.h"
|
||||
#include "mozilla/_ipdltest/PTestArraysChild.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestArraysSubParent.h"
|
||||
#include "mozilla/_ipdltest/PTestArraysSubChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Subprotocol actors
|
||||
|
||||
class TestArraysSub :
|
||||
public PTestArraysSubParent,
|
||||
public PTestArraysSubChild
|
||||
{
|
||||
public:
|
||||
TestArraysSub(uint32_t i) : mI(i)
|
||||
{ }
|
||||
virtual ~TestArraysSub()
|
||||
{ }
|
||||
uint32_t mI;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main actors
|
||||
|
||||
class TestArraysParent :
|
||||
public PTestArraysParent
|
||||
{
|
||||
public:
|
||||
TestArraysParent();
|
||||
virtual ~TestArraysParent();
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
virtual PTestArraysSubParent* AllocPTestArraysSub(const int& i)
|
||||
{
|
||||
PTestArraysSubParent* actor = new TestArraysSub(i);
|
||||
mKids.AppendElement(actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
virtual bool DeallocPTestArraysSub(PTestArraysSubParent* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RecvPTestArraysSubDestructor(PTestArraysSubParent* actor);
|
||||
|
||||
virtual bool RecvTest1(
|
||||
const nsTArray<int>& i1,
|
||||
nsTArray<int>* o1);
|
||||
|
||||
virtual bool RecvTest2(
|
||||
const nsTArray<PTestArraysSubParent*>& i1,
|
||||
nsTArray<PTestArraysSubParent*>* o1);
|
||||
|
||||
virtual bool RecvTest3(
|
||||
const IntDouble& i1,
|
||||
const IntDouble& i2,
|
||||
IntDouble* o1,
|
||||
IntDouble* o2);
|
||||
|
||||
virtual bool RecvTest4(
|
||||
const nsTArray<IntDouble>& i1,
|
||||
nsTArray<IntDouble>* o1);
|
||||
|
||||
virtual bool RecvTest5(
|
||||
const IntDoubleArrays& i1,
|
||||
const IntDoubleArrays& i2,
|
||||
const IntDoubleArrays& i3,
|
||||
IntDoubleArrays* o1,
|
||||
IntDoubleArrays* o2,
|
||||
IntDoubleArrays* o3);
|
||||
|
||||
virtual bool RecvTest6(
|
||||
const nsTArray<IntDoubleArrays>& i1,
|
||||
nsTArray<IntDoubleArrays>* o1);
|
||||
|
||||
virtual bool RecvTest7(
|
||||
const Actors& i1,
|
||||
const Actors& i2,
|
||||
const Actors& i3,
|
||||
Actors* o1,
|
||||
Actors* o2,
|
||||
Actors* o3);
|
||||
|
||||
virtual bool RecvTest8(
|
||||
const nsTArray<Actors>& i1,
|
||||
nsTArray<Actors>* o1);
|
||||
virtual bool RecvTest9(
|
||||
const Unions& i1,
|
||||
const Unions& i2,
|
||||
const Unions& i3,
|
||||
const Unions& i4,
|
||||
Unions* o1,
|
||||
Unions* o2,
|
||||
Unions* o3,
|
||||
Unions* o4);
|
||||
virtual bool RecvTest10(
|
||||
const nsTArray<Unions>& i1,
|
||||
nsTArray<Unions>* o1);
|
||||
|
||||
private:
|
||||
nsTArray<PTestArraysSubParent*> mKids;
|
||||
};
|
||||
|
||||
|
||||
class TestArraysChild :
|
||||
public PTestArraysChild
|
||||
{
|
||||
public:
|
||||
TestArraysChild();
|
||||
virtual ~TestArraysChild();
|
||||
|
||||
protected:
|
||||
virtual PTestArraysSubChild* AllocPTestArraysSub(const int& i)
|
||||
{
|
||||
PTestArraysSubChild* actor = new TestArraysSub(i);
|
||||
mKids.AppendElement(actor);
|
||||
return actor;
|
||||
}
|
||||
virtual bool DeallocPTestArraysSub(PTestArraysSubChild* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool RecvStart();
|
||||
|
||||
private:
|
||||
void Test1();
|
||||
void Test2();
|
||||
void Test3();
|
||||
void Test4();
|
||||
void Test5();
|
||||
void Test6();
|
||||
void Test7();
|
||||
void Test8();
|
||||
void Test9();
|
||||
void Test10();
|
||||
|
||||
nsTArray<PTestArraysSubChild*> mKids;
|
||||
};
|
||||
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestArrays_h
|
|
@ -1,4 +1,6 @@
|
|||
IPDLSRCS = \
|
||||
PTestArrays.ipdl \
|
||||
PTestArraysSub.ipdl \
|
||||
PTestLatency.ipdl \
|
||||
PTestManyChildAllocs.ipdl \
|
||||
PTestManyChildAllocsSub.ipdl \
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
protocol array_Recursive {
|
||||
child: Msg(int[][] aa);
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
protocol array_Basic {
|
||||
child:
|
||||
Msg(int[] array);
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
include protocol "array_OfActorsSub.ipdl";
|
||||
|
||||
protocol array_OfActors {
|
||||
manages array_OfActorsSub;
|
||||
|
||||
child:
|
||||
Msg(array_OfActorsSub[] p);
|
||||
|
||||
array_OfActorsSub();
|
||||
~array_OfActorsSub();
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
include protocol "array_OfActors.ipdl";
|
||||
|
||||
protocol array_OfActorsSub {
|
||||
manager array_OfActors;
|
||||
|
||||
// empty
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
union Union {
|
||||
int[];
|
||||
int;
|
||||
double;
|
||||
};
|
||||
|
||||
sync protocol array_Union {
|
||||
parent:
|
||||
sync Msg(Union u, Union[] au) returns (Union r);
|
||||
};
|
Загрузка…
Ссылка в новой задаче