fix the internal C++ union of generated IPDL unions so that they can contain non-POD types

This commit is contained in:
Chris Jones 2009-09-12 15:40:26 -05:00
Родитель 532ab88f33
Коммит 1ba0bbfbd2
3 изменённых файлов: 55 добавлений и 14 удалений

Просмотреть файл

@ -57,6 +57,10 @@ class Visitor:
def visitType(self, type):
pass
def visitTypeArray(self, ta):
ta.basetype.accept(self)
ta.nmemb.accept(self)
def visitTypeEnum(self, enum):
pass
@ -158,6 +162,9 @@ class Visitor:
def visitExprMemberInit(self, minit):
self.visitExprCall(minit)
def visitExprSizeof(self, es):
self.visitExprCall(es)
def visitStmtBlock(self, sb):
self.visitBlock(sb)
@ -292,6 +299,14 @@ type actually represents an IPDL actor type.
ptrptr=self.ptrptr, ptrconstptr=self.ptrconstptr,
ref=self.ref, actor=self.actor)
class TypeArray(Node):
def __init__(self, basetype, nmemb):
'''the type |basetype DECLNAME[nmemb]|. |nmemb| is an Expr'''
self.basetype = basetype
self.nmemb = nmemb
def __deepcopy__(self, memo):
return TypeArray(deepcopy(self.basetype, memo), nmemb)
class TypeEnum(Node):
def __init__(self, name=None):
'''name can be None'''
@ -307,9 +322,11 @@ class TypeUnion(Node):
Node.__init__(self)
self.name = name
self.components = [ ] # pairs of (Type, name)
self.componentDecls = [ ] # [ Decl ]
def addComponent(self, type, name):
self.components.append((type, name))
self.componentDecls.append(Decl(type, name))
class Typedef(Node):
def __init__(self, fromtype, totypename):
@ -526,6 +543,10 @@ class ExprMemberInit(ExprCall):
def __init__(self, member, args=[ ]):
ExprCall.__init__(self, member, args)
class ExprSizeof(ExprCall):
def __init__(self, t):
ExprCall.__init__(self, ExprVar('sizeof'), [ t ])
##------------------------------
# statements etc.
class StmtBlock(Block):

Просмотреть файл

@ -33,7 +33,7 @@
import sys
from ipdl.cgen import CodePrinter
from ipdl.cxx.ast import Visitor
from ipdl.cxx.ast import TypeArray, Visitor
class CxxCodeGen(CodePrinter, Visitor):
def __init__(self, outf=sys.stdout, indentCols=4):
@ -94,10 +94,10 @@ class CxxCodeGen(CodePrinter, Visitor):
self.println(' {')
self.indent()
for t, name in u.components:
for decl in u.componentDecls:
self.printdent()
t.accept(self)
self.println(' '+ name +';')
decl.accept(self)
self.println(';')
self.dedent()
self.printdent('}')
@ -115,10 +115,20 @@ class CxxCodeGen(CodePrinter, Visitor):
self.println(';')
def visitDecl(self, d):
d.type.accept(self)
# C-syntax arrays make code generation much more annoying
if isinstance(d.type, TypeArray):
d.type.basetype.accept(self)
else:
d.type.accept(self)
if d.name:
self.write(' '+ d.name)
if isinstance(d.type, TypeArray):
self.write('[')
d.type.nmemb.accept(self)
self.write(']')
def visitClass(self, c):
if c.specializes is not None:
self.printdentln('template<>')

Просмотреть файл

@ -266,6 +266,7 @@ class GenerateProtocolHeader(Visitor):
else:
ct = cxx.Type(t.name())
ct._ipdl = None
ct._side = None
cxxtypes.append(ct)
if t.name() != t.fullname():
usingTypedefs.append(cxx.Typedef(cxx.Type(t.fullname()),
@ -273,7 +274,7 @@ class GenerateProtocolHeader(Visitor):
# special, opaque handle used to pack away actor types when unions
# are sent across the wire
t = cxx.Type('ActorHandle'); t._ipdl = None
t = cxx.Type('ActorHandle'); t._ipdl = None; t._side = None
cxxtypes.append(t)
for cxxt in cxxtypes:
@ -313,8 +314,14 @@ class GenerateProtocolHeader(Visitor):
enumvs.append(enumv)
cxxt._tag = enumv
union.addComponent(cxxt, unionname)
cxxtstorage = cxx.TypeArray(cxx.Type('char'),
cxx.ExprSizeof(cxxt))
cxxtstorage._realtype = cxxt
cxxtstorage._tag = cxxt._tag
cxxtstorage._ipdl = cxxt._ipdl
cxxtstorage._side = cxxt._side
union.addComponent(cxxtstorage, unionname)
ptrmethdecl = cxx.MethodDecl(name='ptr'+ cxxt.name,
ret=cxxtptr)
@ -1704,7 +1711,7 @@ class GenerateProtocolActorHeader(Visitor):
continue
switch.addstmt(cxx.CaseLabel(p.type.name +'::'+ t._tag))
repack = cxx.StmtBlock()
repack.addstmt(cxx.StmtDecl(cxx.Decl(t, '__ua')))
repack.addstmt(cxx.StmtDecl(cxx.Decl(t._realtype, '__ua')))
uavar = cxx.ExprVar('__ua')
# take the actor out of the union and convert it
@ -1878,12 +1885,13 @@ class GenerateProtocolActorHeader(Visitor):
ifhandle.addifstmt(cxx.StmtExpr(cxx.ExprAssn(uahvar,
rvar)))
# look up and verify the actor handle we got
ifhandle.addifstmt(cxx.StmtDecl(cxx.Decl(t, '__ua')))
ifhandle.addifstmt(cxx.StmtDecl(cxx.Decl(t._realtype,
'__ua')))
uavar = cxx.ExprVar('__ua')
actorid = cxx.ExprSelect(uahvar, '.', 'mId')
cast = cxx.ExprCast(
cxx.ExprCall(cxx.ExprVar('Lookup'), [ actorid ]),
t,
t._realtype,
static=1)
ifhandle.addifstmt(cxx.StmtExpr(
cxx.ExprAssn(uavar, cast)))
@ -2039,14 +2047,15 @@ class GenerateProtocolActorHeader(Visitor):
ifhandle.addifstmt(cxx.StmtExpr(cxx.ExprAssn(uahvar,
pvar)))
# look up and verify the actor handle we got
ifhandle.addifstmt(cxx.StmtDecl(cxx.Decl(t, '__ua')))
ifhandle.addifstmt(cxx.StmtDecl(cxx.Decl(t._realtype,
'__ua')))
uavar = cxx.ExprVar('__ua')
ifhandle.ifb.addstmts(
_actorHandleToActor(
handle=uahvar,
actor=uavar,
actortype=t,
actortype=t._realtype,
failcode=cxx.ExprVar('MsgValueError')))
# finally, slam the actor back into the union
@ -2198,7 +2207,8 @@ class GenerateProtocolActorHeader(Visitor):
continue
switch.addstmt(cxx.Label(t._tag))
repack = cxx.StmtBlock()
repack.addstmt(cxx.StmtDecl(cxx.Decl(t, '__ua')))
repack.addstmt(cxx.StmtDecl(cxx.Decl(t._realtype,
'__ua')))
uavar = cxx.ExprVar('__ua')
repack.addstmt(cxx.StmtExpr(cxx.ExprAssn(uavar, rvar)))
repack.addstmt(cxx.StmtExpr(