зеркало из https://github.com/mozilla/gecko-dev.git
add discriminated union types to IPDL
This commit is contained in:
Родитель
7d52f509f1
Коммит
11c6e75c70
|
@ -46,9 +46,29 @@ include "mozilla/plugins/PluginMessageUtils.h";
|
|||
using NPError;
|
||||
using NPWindow;
|
||||
|
||||
|
||||
// FIXME/bent: demo purposes only
|
||||
using mozilla::void_t;
|
||||
using mozilla::null_t;
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
|
||||
|
||||
// FIXME/bent: demo purposes only
|
||||
union Variant {
|
||||
int;
|
||||
double;
|
||||
void_t;
|
||||
null_t;
|
||||
PPluginInstance;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
rpc protocol PPluginInstance
|
||||
{
|
||||
manager PPluginModule;
|
||||
|
@ -56,6 +76,15 @@ rpc protocol PPluginInstance
|
|||
manages PPluginScriptableObject;
|
||||
manages PBrowserStream;
|
||||
|
||||
|
||||
|
||||
// FIXME/bent: demo purposes only
|
||||
child:
|
||||
Test(Variant v1, Variant v2);
|
||||
|
||||
|
||||
|
||||
|
||||
child:
|
||||
/* NPP_NewStream */
|
||||
rpc PBrowserStream(nsCString url,
|
||||
|
|
|
@ -57,7 +57,6 @@ rpc protocol PPluginScriptableObject
|
|||
manager PPluginInstance;
|
||||
|
||||
child:
|
||||
|
||||
// NPClass methods
|
||||
rpc Invalidate();
|
||||
|
||||
|
|
|
@ -65,6 +65,62 @@ class PluginInstanceChild : public PPluginInstanceChild
|
|||
protected:
|
||||
friend class BrowserStreamChild;
|
||||
|
||||
|
||||
|
||||
// FIXME/bent: demo purposes only
|
||||
virtual nsresult
|
||||
RecvTest(const Variant& v1, const Variant& v2)
|
||||
{
|
||||
printf("\n[PluginInstanceChild] v1: ");
|
||||
|
||||
switch (v1.type()) {
|
||||
case Variant::Tint: {
|
||||
int i = v1;
|
||||
printf("variant-int %d", i);
|
||||
break;
|
||||
}
|
||||
case Variant::Tdouble: {
|
||||
double d = v1;
|
||||
printf("variant-double %e", d);
|
||||
break;
|
||||
}
|
||||
case Variant::TPPluginInstanceChild: {
|
||||
const PPluginInstanceChild* p = v1;
|
||||
printf("plugin instance %p", p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_RUNTIMEABORT("unexpected Variant value");
|
||||
}
|
||||
|
||||
printf(", v2: ");
|
||||
|
||||
switch (v2.type()) {
|
||||
case Variant::Tint: {
|
||||
int i = v2;
|
||||
printf("variant-int %d", i);
|
||||
break;
|
||||
}
|
||||
case Variant::Tdouble: {
|
||||
double d = v2;
|
||||
printf("variant-double %e", d);
|
||||
break;
|
||||
}
|
||||
case Variant::TPPluginInstanceChild: {
|
||||
const PPluginInstanceChild* p = v2;
|
||||
printf("plugin instance %p", p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_RUNTIMEABORT("unexpected Variant value");
|
||||
}
|
||||
|
||||
puts("\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual nsresult AnswerNPP_SetWindow(const NPWindow& window, NPError* rv);
|
||||
|
||||
virtual nsresult AnswerNPP_GetValue(const nsString& key, nsString* value);
|
||||
|
|
|
@ -47,6 +47,14 @@
|
|||
#include "nsStringGlue.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
||||
// XXX might want to move these to nscore.h or something, they can be
|
||||
// generally useful
|
||||
struct void_t { };
|
||||
struct null_t { };
|
||||
|
||||
|
||||
namespace ipc {
|
||||
|
||||
typedef intptr_t NPRemoteIdentifier;
|
||||
|
@ -364,6 +372,32 @@ struct ParamTraits<NPVariant>
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::void_t>
|
||||
{
|
||||
typedef mozilla::void_t paramType;
|
||||
static void Write(Message* aMsg, const paramType& aParam) { }
|
||||
static bool
|
||||
Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
*aResult = paramType();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::null_t>
|
||||
{
|
||||
typedef mozilla::null_t paramType;
|
||||
static void Write(Message* aMsg, const paramType& aParam) { }
|
||||
static bool
|
||||
Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
*aResult = paramType();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::plugins::IPCByteRange>
|
||||
{
|
||||
|
|
|
@ -188,6 +188,15 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType,
|
|||
printf ("[PluginModuleParent] %s: got return value %hd\n", __FUNCTION__,
|
||||
prv);
|
||||
|
||||
|
||||
// FIXME/bent: demo purposes only
|
||||
Variant v1(0);
|
||||
Variant v2(parentInstance);
|
||||
printf("\n[PluginModuleParent] sending Test msg\n\n");
|
||||
parentInstance->SendTest(v1, v2);
|
||||
|
||||
|
||||
|
||||
if (NPERR_NO_ERROR != prv)
|
||||
return prv;
|
||||
NS_ASSERTION(parentInstance,
|
||||
|
|
|
@ -42,6 +42,8 @@ class Visitor:
|
|||
cxxInc.accept(self)
|
||||
for protoInc in tu.protocolIncludes:
|
||||
protoInc.accept(self)
|
||||
for union in tu.unions:
|
||||
union.accept(self)
|
||||
for using in tu.using:
|
||||
using.accept(self)
|
||||
tu.protocol.accept(self)
|
||||
|
@ -54,6 +56,10 @@ class Visitor:
|
|||
# and pass-specific handling
|
||||
pass
|
||||
|
||||
def visitUnionDecl(self, union):
|
||||
for t in union.components:
|
||||
t.accept(self)
|
||||
|
||||
def visitUsingStmt(self, using):
|
||||
pass
|
||||
|
||||
|
@ -133,6 +139,20 @@ class Node:
|
|||
if not hasattr(self, attrsName):
|
||||
setattr(self, attrsName, _struct())
|
||||
|
||||
|
||||
class NamespacedNode(Node):
|
||||
def __init__(self, loc=Loc.NONE, name=None):
|
||||
Node.__init__(self, loc)
|
||||
self.name = name
|
||||
self.namespaces = [ ]
|
||||
|
||||
def addOuterNamespace(self, namespace):
|
||||
self.namespaces.insert(0, namespace)
|
||||
|
||||
def qname(self):
|
||||
return QualifiedId(self.loc, self.name,
|
||||
[ ns.namespace for ns in self.namespaces ])
|
||||
|
||||
class TranslationUnit(Node):
|
||||
def __init__(self):
|
||||
Node.__init__(self)
|
||||
|
@ -140,10 +160,12 @@ class TranslationUnit(Node):
|
|||
self.cxxIncludes = [ ]
|
||||
self.protocolIncludes = [ ]
|
||||
self.using = [ ]
|
||||
self.unions = [ ]
|
||||
self.protocol = None
|
||||
|
||||
def addCxxInclude(self, cxxInclude): self.cxxIncludes.append(cxxInclude)
|
||||
def addProtocolInclude(self, pInc): self.protocolIncludes.append(pInc)
|
||||
def addUnionDecl(self, union): self.unions.append(union)
|
||||
def addUsingStmt(self, using): self.using.append(using)
|
||||
|
||||
def setProtocol(self, protocol): self.protocol = protocol
|
||||
|
@ -217,20 +239,20 @@ _prettyTable = {
|
|||
}
|
||||
|
||||
|
||||
class Protocol(Node):
|
||||
def __init__(self, loc):
|
||||
class Namespace(Node):
|
||||
def __init__(self, loc, namespace):
|
||||
Node.__init__(self, loc)
|
||||
self.name = None
|
||||
self.namespaces = [ ]
|
||||
self.namespace = namespace
|
||||
|
||||
class Protocol(NamespacedNode):
|
||||
def __init__(self, loc):
|
||||
NamespacedNode.__init__(self, loc)
|
||||
self.sendSemantics = ASYNC
|
||||
self.managesStmts = [ ]
|
||||
self.messageDecls = [ ]
|
||||
self.transitionStmts = [ ]
|
||||
self.startStates = [ ]
|
||||
|
||||
def addOuterNamespace(self, namespace):
|
||||
self.namespaces.insert(0, namespace)
|
||||
|
||||
def addManagesStmts(self, managesStmts):
|
||||
self.managesStmts += managesStmts
|
||||
|
||||
|
@ -240,10 +262,10 @@ class Protocol(Node):
|
|||
def addTransitionStmts(self, transStmts):
|
||||
self.transitionStmts += transStmts
|
||||
|
||||
class Namespace(Node):
|
||||
def __init__(self, loc, namespace):
|
||||
Node.__init__(self, loc)
|
||||
self.namespace = namespace
|
||||
class UnionDecl(NamespacedNode):
|
||||
def __init__(self, loc, name, components):
|
||||
NamespacedNode.__init__(self, loc, name)
|
||||
self.components = components
|
||||
|
||||
class ManagerStmt(Node):
|
||||
def __init__(self, loc, managerName):
|
||||
|
|
|
@ -60,9 +60,12 @@ class Visitor:
|
|||
def visitTypeEnum(self, enum):
|
||||
pass
|
||||
|
||||
def visitTypeUnion(self, union):
|
||||
for t, name in union.components:
|
||||
t.accept(self)
|
||||
|
||||
def visitTypedef(self, tdef):
|
||||
tdef.fromtype.accept(self)
|
||||
tdef.totype.accept(self)
|
||||
|
||||
def visitForwardDecl(self, fd):
|
||||
pass
|
||||
|
@ -120,6 +123,11 @@ class Visitor:
|
|||
e.left.accept(self)
|
||||
e.right.accept(self)
|
||||
|
||||
def visitExprConditional(self, c):
|
||||
c.cond.accept(self)
|
||||
c.ife.accept(self)
|
||||
c.elsee.accept(self)
|
||||
|
||||
def visitExprAddrOf(self, eao):
|
||||
self.visitExprPrefixUnop(eao)
|
||||
|
||||
|
@ -175,6 +183,9 @@ class Visitor:
|
|||
ss.expr.accept(self)
|
||||
self.visitBlock(ss)
|
||||
|
||||
def visitStmtBreak(self, sb):
|
||||
pass
|
||||
|
||||
def visitStmtExpr(self, se):
|
||||
se.expr.accept(self)
|
||||
|
||||
|
@ -239,21 +250,47 @@ class Block(Node):
|
|||
# type and decl thingies
|
||||
class Namespace(Block):
|
||||
def __init__(self, name):
|
||||
assert isinstance(name, str)
|
||||
|
||||
Block.__init__(self)
|
||||
self.name = name
|
||||
|
||||
class Type(Node):
|
||||
def __init__(self, name, const=0, ptr=0, ref=0, actor=0):
|
||||
def __init__(self, name, const=0,
|
||||
ptr=0, ptrconst=0, ptrptr=0, ptrconstptr=0,
|
||||
ref=0,
|
||||
actor=0):
|
||||
"""
|
||||
To avoid getting fancy with recursive types, we limit the kinds
|
||||
of pointer types that can be be constructed.
|
||||
|
||||
ptr => T*
|
||||
ptrconst => T* const
|
||||
ptrptr => T**
|
||||
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.
|
||||
"""
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.const = const
|
||||
self.ptr = ptr
|
||||
self.ptrconst = ptrconst
|
||||
self.ptrptr = ptrptr
|
||||
self.ptrconstptr = ptrconstptr
|
||||
self.ref = ref
|
||||
self.actor = actor
|
||||
# XXX could get serious here with recursive types, but shouldn't
|
||||
# need that for this codegen
|
||||
def __deepcopy__(self, memo):
|
||||
return Type(self.name, self.const, self.ptr, self.ref, self.actor)
|
||||
return Type(self.name,
|
||||
const=self.const,
|
||||
ptr=self.ptr, ptrconst=self.ptrconst,
|
||||
ptrptr=self.ptrptr, ptrconstptr=self.ptrconstptr,
|
||||
ref=self.ref, actor=self.actor)
|
||||
|
||||
class TypeEnum(Node):
|
||||
def __init__(self, name=None):
|
||||
|
@ -265,11 +302,22 @@ class TypeEnum(Node):
|
|||
def addId(self, id, num=None):
|
||||
self.idnums.append((id, num))
|
||||
|
||||
class TypeUnion(Node):
|
||||
def __init__(self, name=None):
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.components = [ ] # pairs of (Type, name)
|
||||
|
||||
def addComponent(self, type, name):
|
||||
self.components.append((type, name))
|
||||
|
||||
class Typedef(Node):
|
||||
def __init__(self, fromtype, totype):
|
||||
def __init__(self, fromtype, totypename):
|
||||
assert isinstance(totypename, str)
|
||||
|
||||
Node.__init__(self)
|
||||
self.fromtype = fromtype
|
||||
self.totype = totype
|
||||
self.totypename = totypename
|
||||
|
||||
class ForwardDecl(Node):
|
||||
def __init__(self, pqname, cls=0, struct=0):
|
||||
|
@ -292,17 +340,21 @@ class Decl(Node):
|
|||
# class stuff
|
||||
class Class(Block):
|
||||
def __init__(self, name, inherits=[ ],
|
||||
interface=False, abstract=False, final=False):
|
||||
interface=0, abstract=0, final=0,
|
||||
specializes=None, struct=0):
|
||||
assert not (interface and abstract)
|
||||
assert not (abstract and final)
|
||||
assert not (interface and final)
|
||||
assert not (inherits and specializes)
|
||||
|
||||
Block.__init__(self)
|
||||
self.name = name
|
||||
self.inherits = inherits
|
||||
self.interface = interface
|
||||
self.abstract = abstract
|
||||
self.final = final
|
||||
self.inherits = inherits # [ Type ]
|
||||
self.interface = interface # bool
|
||||
self.abstract = abstract # bool
|
||||
self.final = final # bool
|
||||
self.specializes = specializes # Type or None
|
||||
self.struct = struct # bool
|
||||
|
||||
class Inherit(Node):
|
||||
def __init__(self, name, viz='public'):
|
||||
|
@ -317,18 +369,24 @@ class FriendClassDecl(Node):
|
|||
|
||||
class MethodDecl(Node):
|
||||
def __init__(self, name, params=[ ], ret=Type('void'),
|
||||
virtual=False, const=False, pure=False, static=False):
|
||||
virtual=0, const=0, pure=0, static=0, typeop=0):
|
||||
assert not (virtual and static)
|
||||
assert not pure or virtual # pure => virtual
|
||||
assert not pure or virtual # pure => virtual
|
||||
assert not (static and typeop)
|
||||
|
||||
if typeop:
|
||||
ret = None
|
||||
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
self.params = params
|
||||
self.ret = ret
|
||||
self.virtual = virtual
|
||||
self.const = const
|
||||
self.pure = pure
|
||||
self.static = static
|
||||
self.params = params # [ Param ]
|
||||
self.ret = ret # Type or None
|
||||
self.virtual = virtual # bool
|
||||
self.const = const # bool
|
||||
self.pure = pure # bool
|
||||
self.static = static # bool
|
||||
self.typeop = typeop # bool
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return MethodDecl(self.name,
|
||||
copy.deepcopy(self.params, memo),
|
||||
|
@ -343,8 +401,9 @@ class MethodDefn(Block):
|
|||
self.decl = decl
|
||||
|
||||
class ConstructorDecl(MethodDecl):
|
||||
def __init__(self, name, params=[ ]):
|
||||
def __init__(self, name, params=[ ], explicit=0):
|
||||
MethodDecl.__init__(self, name, params=params, ret=None)
|
||||
self.explicit = explicit
|
||||
|
||||
class ConstructorDefn(MethodDefn):
|
||||
def __init__(self, decl, memberinits=[ ]):
|
||||
|
@ -352,7 +411,7 @@ class ConstructorDefn(MethodDefn):
|
|||
self.memberinits = memberinits
|
||||
|
||||
class DestructorDecl(MethodDecl):
|
||||
def __init__(self, name, virtual=False):
|
||||
def __init__(self, name, virtual=0):
|
||||
MethodDecl.__init__(self, name, params=[ ], ret=None,
|
||||
virtual=virtual)
|
||||
class DestructorDefn(MethodDefn):
|
||||
|
@ -414,10 +473,18 @@ class ExprCast(Node):
|
|||
|
||||
class ExprBinary(Node):
|
||||
def __init__(self, left, op, right):
|
||||
Node.__init__(self)
|
||||
self.left = left
|
||||
self.op = op
|
||||
self.right = right
|
||||
|
||||
class ExprConditional(Node):
|
||||
def __init__(self, cond, ife, elsee):
|
||||
Node.__init__(self)
|
||||
self.cond = cond
|
||||
self.ife = ife
|
||||
self.elsee = elsee
|
||||
|
||||
class ExprSelect(Node):
|
||||
def __init__(self, obj, op, field):
|
||||
Node.__init__(self)
|
||||
|
@ -440,8 +507,15 @@ class ExprCall(Node):
|
|||
|
||||
class ExprNew(ExprCall):
|
||||
# XXX taking some poetic license ...
|
||||
def __init__(self, type, args=[ ]):
|
||||
ExprCall.__init__(self, ExprVar(type.name), args)
|
||||
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)
|
||||
self.newargs = newargs
|
||||
|
||||
class ExprDelete(Node):
|
||||
def __init__(self, obj):
|
||||
|
@ -467,6 +541,9 @@ class Label(Node):
|
|||
def __init__(self, name):
|
||||
Node.__init__(self)
|
||||
self.name = name
|
||||
Label.PUBLIC = Label('public')
|
||||
Label.PROTECTED = Label('protected')
|
||||
Label.PRIVATE = Label('private')
|
||||
|
||||
class CaseLabel(Node):
|
||||
def __init__(self, name):
|
||||
|
@ -501,6 +578,10 @@ class StmtSwitch(Block):
|
|||
self.addstmt(block)
|
||||
self.nr_cases += 1
|
||||
|
||||
class StmtBreak(Node):
|
||||
def __init__(self):
|
||||
Node.__init__(self)
|
||||
|
||||
class StmtExpr(Node):
|
||||
def __init__(self, expr):
|
||||
Node.__init__(self)
|
||||
|
|
|
@ -55,10 +55,17 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
|
||||
def visitType(self, t):
|
||||
ts = ''
|
||||
|
||||
if t.const: ts += 'const '
|
||||
ts += t.name
|
||||
if t.ptr: ts += '*'
|
||||
|
||||
if t.ptr: ts += '*'
|
||||
elif t.ptrconst: ts += '* const'
|
||||
elif t.ptrptr: ts += '**'
|
||||
elif t.ptrconstptr: ts += '* const*'
|
||||
|
||||
if t.ref: ts += '&'
|
||||
|
||||
self.write(ts)
|
||||
|
||||
def visitTypeEnum(self, te):
|
||||
|
@ -80,12 +87,26 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.printdent('}')
|
||||
|
||||
|
||||
def visitTypeUnion(self, u):
|
||||
self.write('union')
|
||||
if u.name:
|
||||
self.write(' '+ u.name)
|
||||
self.println(' {')
|
||||
|
||||
self.indent()
|
||||
for t, name in u.components:
|
||||
self.printdent()
|
||||
t.accept(self)
|
||||
self.println(' '+ name +';')
|
||||
self.dedent()
|
||||
|
||||
self.printdent('}')
|
||||
|
||||
|
||||
def visitTypedef(self, td):
|
||||
self.printdent('typedef ')
|
||||
td.fromtype.accept(self)
|
||||
self.write(' ')
|
||||
td.totype.accept(self)
|
||||
self.println(';')
|
||||
self.println(' '+ td.totypename +';')
|
||||
|
||||
def visitForwardDecl(self, fd):
|
||||
if fd.cls: self.printdent('class ')
|
||||
|
@ -99,7 +120,13 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.write(' '+ d.name)
|
||||
|
||||
def visitClass(self, c):
|
||||
self.printdent('class')
|
||||
if c.specializes is not None:
|
||||
self.printdentln('template<>')
|
||||
|
||||
if c.struct:
|
||||
self.printdent('struct')
|
||||
else:
|
||||
self.printdent('class')
|
||||
if c.interface:
|
||||
# FIXME/cjones: turn this "on" when we get the analysis
|
||||
self.write(' /*NS_INTERFACE_CLASS*/')
|
||||
|
@ -110,6 +137,11 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.write(' NS_FINAL_CLASS')
|
||||
self.write(' '+ c.name)
|
||||
|
||||
if c.specializes is not None:
|
||||
self.write(' <')
|
||||
c.specializes.accept(self)
|
||||
self.write('>')
|
||||
|
||||
ninh = len(c.inherits)
|
||||
if 0 < ninh:
|
||||
self.println(' :')
|
||||
|
@ -136,8 +168,10 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
def visitFriendClassDecl(self, fcd):
|
||||
self.printdentln('friend class '+ fcd.friend +';')
|
||||
|
||||
|
||||
def visitMethodDecl(self, md):
|
||||
assert not (md.static and md.virtual)
|
||||
|
||||
if md.static:
|
||||
self.write('static ')
|
||||
if md.virtual:
|
||||
|
@ -153,6 +187,7 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
if md.pure:
|
||||
self.write(' = 0')
|
||||
|
||||
|
||||
def visitMethodDefn(self, md):
|
||||
self.printdent()
|
||||
md.decl.accept(self)
|
||||
|
@ -166,7 +201,8 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
|
||||
|
||||
def visitConstructorDecl(self, cd):
|
||||
# FIXME/cjones: explicit when possible
|
||||
if cd.explicit:
|
||||
self.write('explicit ')
|
||||
self.visitMethodDecl(cd)
|
||||
|
||||
def visitConstructorDefn(self, cd):
|
||||
|
@ -244,6 +280,15 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
e.right.accept(self)
|
||||
self.write(')')
|
||||
|
||||
def visitExprConditional(self, c):
|
||||
self.write('(')
|
||||
c.cond.accept(self)
|
||||
self.write(' ? ')
|
||||
c.ife.accept(self)
|
||||
self.write(' : ')
|
||||
c.elsee.accept(self)
|
||||
self.write(')')
|
||||
|
||||
def visitExprSelect(self, es):
|
||||
es.obj.accept(self)
|
||||
self.write(es.op + es.field)
|
||||
|
@ -261,6 +306,10 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
|
||||
def visitExprNew(self, en):
|
||||
self.write('new ')
|
||||
if en.newargs is not None:
|
||||
self.write('(')
|
||||
self.writeExprList(en.newargs)
|
||||
self.write(') ')
|
||||
self.visitExprCall(en)
|
||||
|
||||
def visitExprDelete(self, ed):
|
||||
|
@ -317,6 +366,9 @@ class CxxCodeGen(CodePrinter, Visitor):
|
|||
self.dedent()
|
||||
self.printdentln('}')
|
||||
|
||||
def visitStmtBreak(self, sb):
|
||||
self.printdentln('break;')
|
||||
|
||||
|
||||
def visitStmtDecl(self, sd):
|
||||
self.printdent()
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -168,6 +168,7 @@ reserved = set((
|
|||
'state',
|
||||
'sync',
|
||||
'transfer',
|
||||
'union',
|
||||
'using'))
|
||||
tokens = [
|
||||
'COLONCOLON', 'ID', 'STRING'
|
||||
|
@ -207,15 +208,28 @@ def t_error(t):
|
|||
##-----------------------------------------------------------------------------
|
||||
|
||||
def p_TranslationUnit(p):
|
||||
"""TranslationUnit : Preamble NamespacedProtocolDefn"""
|
||||
"""TranslationUnit : Preamble NamespacedStuff"""
|
||||
tu = Parser.current.tu
|
||||
for stmt in p[1]:
|
||||
if isinstance(stmt, CxxInclude): tu.addCxxInclude(stmt)
|
||||
elif isinstance(stmt, ProtocolInclude): tu.addProtocolInclude(stmt)
|
||||
elif isinstance(stmt, UsingStmt): tu.addUsingStmt(stmt)
|
||||
if isinstance(stmt, CxxInclude):
|
||||
tu.addCxxInclude(stmt)
|
||||
elif isinstance(stmt, ProtocolInclude):
|
||||
tu.addProtocolInclude(stmt)
|
||||
elif isinstance(stmt, UsingStmt):
|
||||
tu.addUsingStmt(stmt)
|
||||
else:
|
||||
assert 0
|
||||
tu.protocol = p[2]
|
||||
|
||||
for thing in p[2]:
|
||||
if isinstance(thing, UnionDecl):
|
||||
tu.addUnionDecl(thing)
|
||||
elif isinstance(thing, Protocol):
|
||||
if tu.protocol is not None:
|
||||
_error(thing.loc, "only one protocol definition per file")
|
||||
tu.protocol = thing
|
||||
else:
|
||||
assert(0)
|
||||
|
||||
p[0] = tu
|
||||
|
||||
##--------------------
|
||||
|
@ -258,16 +272,39 @@ def p_UsingStmt(p):
|
|||
p[0] = UsingStmt(locFromTok(p, 1), p[2])
|
||||
|
||||
##--------------------
|
||||
## Protocol definition
|
||||
def p_NamespacedProtocolDefn(p):
|
||||
"""NamespacedProtocolDefn : NAMESPACE ID '{' NamespacedProtocolDefn '}'
|
||||
| ProtocolDefn"""
|
||||
## Namespaced stuff
|
||||
def p_NamespacedStuff(p):
|
||||
"""NamespacedStuff : NamespacedStuff NamespaceThing
|
||||
| NamespaceThing"""
|
||||
if 2 == len(p):
|
||||
p[0] = p[1]
|
||||
else:
|
||||
protocol = p[4]
|
||||
protocol.addOuterNamespace(Namespace(locFromTok(p, 1), p[2]))
|
||||
p[0] = protocol
|
||||
p[1].extend(p[2])
|
||||
p[0] = p[1]
|
||||
|
||||
def p_NamespaceThing(p):
|
||||
"""NamespaceThing : NAMESPACE ID '{' NamespacedStuff '}'
|
||||
| UnionDecl
|
||||
| ProtocolDefn"""
|
||||
if 2 == len(p):
|
||||
p[0] = [ p[1] ]
|
||||
else:
|
||||
for thing in p[4]:
|
||||
thing.addOuterNamespace(Namespace(locFromTok(p, 1), p[2]))
|
||||
p[0] = p[4]
|
||||
|
||||
def p_UnionDecl(p):
|
||||
"""UnionDecl : UNION ID '{' ComponentTypes '}' ';'"""
|
||||
p[0] = UnionDecl(locFromTok(p, 1), p[2], p[4])
|
||||
|
||||
def p_ComponentTypes(p):
|
||||
"""ComponentTypes : ComponentTypes Type ';'
|
||||
| Type ';'"""
|
||||
if 3 == len(p):
|
||||
p[0] = [ p[1] ]
|
||||
else:
|
||||
p[1].append(p[2])
|
||||
p[0] = p[1]
|
||||
|
||||
def p_ProtocolDefn(p):
|
||||
"""ProtocolDefn : OptionalSendSemanticsQual PROTOCOL ID '{' ManagerStmtOpt ManagesStmts OptionalMessageDecls TransitionStmts '}' ';'"""
|
||||
|
|
|
@ -118,6 +118,7 @@ class IPDLType(Type):
|
|||
def isMessage(self): return False
|
||||
def isProtocol(self): return False
|
||||
def isActor(self): return False
|
||||
def isUnion(self): return False
|
||||
|
||||
def isAsync(self): return self.sendSemantics is ASYNC
|
||||
def isSync(self): return self.sendSemantics is SYNC
|
||||
|
@ -199,7 +200,7 @@ class ProtocolType(IPDLType):
|
|||
return not self.isManaged()
|
||||
|
||||
class ActorType(IPDLType):
|
||||
def __init__(self, protocol, state):
|
||||
def __init__(self, protocol, state=None):
|
||||
self.protocol = protocol
|
||||
self.state = state
|
||||
def isActor(self): return True
|
||||
|
@ -209,6 +210,15 @@ class ActorType(IPDLType):
|
|||
def fullname(self):
|
||||
return self.protocol.fullname()
|
||||
|
||||
class UnionType(IPDLType):
|
||||
def __init__(self, qname, components):
|
||||
self.qname = qname
|
||||
self.components = components
|
||||
|
||||
def isUnionType(self): return True
|
||||
def name(self): return self.qname.baseid
|
||||
def fullname(self): return str(self.qname)
|
||||
|
||||
##--------------------
|
||||
_builtinloc = Loc('<builtin>', 0)
|
||||
def makeBuiltinUsing(tname):
|
||||
|
@ -395,8 +405,7 @@ class GatherDecls(TcheckVisitor):
|
|||
# both the namespace and non-namespaced name in the global scope.
|
||||
# try to figure out something better; maybe a type-neutral |using|
|
||||
# that works for C++ and protocol types?
|
||||
qname = QualifiedId(p.loc, p.name,
|
||||
[ ns.namespace for ns in p.namespaces ])
|
||||
qname = p.qname()
|
||||
if 0 == len(qname.quals):
|
||||
fullname = None
|
||||
else:
|
||||
|
@ -415,6 +424,10 @@ class GatherDecls(TcheckVisitor):
|
|||
for using in tu.using:
|
||||
using.accept(self)
|
||||
|
||||
# declare unions
|
||||
for union in tu.unions:
|
||||
union.accept(self)
|
||||
|
||||
# grab symbols in the protocol itself
|
||||
p.accept(self)
|
||||
|
||||
|
@ -427,6 +440,32 @@ class GatherDecls(TcheckVisitor):
|
|||
pi.tu.accept(self)
|
||||
self.symtab.declare(pi.tu.protocol.decl)
|
||||
|
||||
def visitUnionDecl(self, ud):
|
||||
qname = ud.qname()
|
||||
if 0 == len(qname.quals):
|
||||
fullname = None
|
||||
else:
|
||||
fullname = str(qname)
|
||||
components = [ ]
|
||||
|
||||
nactors = 0 # FIXME
|
||||
|
||||
for c in ud.components:
|
||||
ctype = self.symtab.lookup(str(c)).type
|
||||
if ctype.isIPDL() and ctype.isProtocol():
|
||||
ctype = ActorType(ctype)
|
||||
nactors += 1
|
||||
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),
|
||||
shortname=ud.name,
|
||||
fullname=fullname)
|
||||
|
||||
def visitUsingStmt(self, using):
|
||||
fullname = str(using.type)
|
||||
if using.type.basename() == fullname:
|
||||
|
|
Загрузка…
Ссылка в новой задаче