Support @marshall to automatically marshall pointers

This commit is contained in:
Alexander Larsson 2010-06-30 13:24:59 +02:00 committed by Gerd Hoffmann
parent a24a8ff72a
commit 1be4d5d26c
2 changed files with 40 additions and 28 deletions

View File

@ -104,10 +104,10 @@ def write_marshal_ptr_function(writer, target_type):
writer.set_is_generated("marshaller", marshal_function)
names = target_type.get_pointer_names()
names = target_type.get_pointer_names(False)
names_args = ""
if len(names) > 0:
n = map(lambda name: ", SpiceMarshaller **%s" % name, names)
n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names)
names_args = "".join(n)
header = writer.header
@ -120,9 +120,10 @@ def write_marshal_ptr_function(writer, target_type):
scope = writer.function(marshal_function, "void *", "SpiceMarshaller *m, %s *ptr" % target_type.c_type() + names_args)
header.writeln("void *" + marshal_function + "(SpiceMarshaller *m, %s *msg" % target_type.c_type() + names_args + ");")
scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "end")
scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
for n in names:
writer.assign("*%s" % n, "NULL")
writer.assign("*%s_out" % n, "NULL")
writer.newline()
writer.assign("end", "(uint8_t *)(ptr+1)")
@ -214,6 +215,20 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope):
var = "%s__ref" % array.size[1]
writer.statement("spice_marshaller_set_%s(m, %s, spice_marshaller_get_size(m) - %s)" % (size_var_type.primitive_type(), var, size_start_var))
def write_pointer_marshaller(writer, member, src):
t = member.member_type
ptr_func = write_marshal_ptr_function(writer, t.target_type)
submarshaller = "spice_marshaller_get_ptr_submarshaller(m, %d)" % (1 if member.get_fixed_nw_size() == 8 else 0)
if member.has_attr("marshall"):
writer.assign("m2", submarshaller)
if member.has_attr("nonnull"):
writer.statement("%s(m2, %s)" % (ptr_func, src.get_ref(member.name)))
else:
with writer.if_block("%s != NULL" % src.get_ref(member.name)) as block:
writer.statement("%s(m2, %s)" % (ptr_func, src.get_ref(member.name)))
else:
writer.assign("*%s_out" % (writer.out_prefix + member.name), submarshaller)
def write_switch_marshaller(writer, container, switch, src, scope):
var = container.lookup_member(switch.variable)
var_type = var.member_type
@ -242,8 +257,7 @@ def write_switch_marshaller(writer, container, switch, src, scope):
if t.is_struct():
write_container_marshaller(writer, t, src2)
elif t.is_pointer():
ptr_func = write_marshal_ptr_function(writer, t.target_type)
writer.assign("*%s_out" % (writer.out_prefix + m.name), "spice_marshaller_get_ptr_submarshaller(m, %d)" % (1 if m.get_fixed_nw_size() == 8 else 0))
write_pointer_marshaller(writer, m, src2)
elif t.is_primitive():
if m.has_attr("zero"):
writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
@ -283,13 +297,7 @@ def write_member_marshaller(writer, container, member, src, scope):
t = member.member_type
if t.is_pointer():
# if member.has_attr("nocopy"):
# writer.comment("Reuse data from network message").newline()
# writer.assign(src.get_ref(member.name), "(size_t)(message_start + consume_uint64(&in))")
# else:
# write_parse_pointer(writer, t, member.has_end_attr(), src, member.name, scope)
ptr_func = write_marshal_ptr_function(writer, t.target_type)
writer.assign("*%s_out" % (writer.out_prefix + member.name), "spice_marshaller_get_ptr_submarshaller(m, %d)" % (1 if member.get_fixed_nw_size() == 8 else 0))
write_pointer_marshaller(writer, member, src)
elif t.is_primitive():
if member.has_attr("zero"):
writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
@ -329,10 +337,10 @@ def write_message_marshaller(writer, message, is_server, private):
return function_name
writer.set_is_generated("marshaller", function_name)
names = message.get_pointer_names()
names = message.get_pointer_names(False)
names_args = ""
if len(names) > 0:
n = map(lambda name: ", SpiceMarshaller **%s" % name, names)
n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names)
names_args = "".join(n)
if not private:
@ -342,9 +350,10 @@ def write_message_marshaller(writer, message, is_server, private):
"static void" if private else "void",
"SpiceMarshaller *m, %s *msg" % message.c_type() + names_args)
scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "end")
scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
for n in names:
writer.assign("*%s" % n, "NULL")
writer.assign("*%s_out" % n, "NULL")
src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg")
src.reuse_scope = scope

View File

@ -94,7 +94,7 @@ class Type:
def get_num_pointers(self):
return 0
def get_pointer_names(self):
def get_pointer_names(self, marshalled):
return []
def sizeof(self):
@ -205,8 +205,8 @@ class TypeAlias(Type):
def get_num_pointers(self):
return self.the_type.get_num_pointers()
def get_pointer_names(self):
return self.the_type.get_pointer_names()
def get_pointer_names(self, marshalled):
return self.the_type.get_pointer_names(marshalled)
def c_type(self):
if self.has_attr("ctype"):
@ -408,7 +408,7 @@ class ArrayType(Type):
return element_count * self.size
raise Exception, "Pointers in dynamic arrays not supported"
def get_pointer_names(self):
def get_pointer_names(self, marshalled):
element_count = self.element_type.get_num_pointers()
if element_count == 0:
return []
@ -554,11 +554,14 @@ class Member(Containee):
def get_num_pointers(self):
return self.member_type.get_num_pointers()
def get_pointer_names(self):
def get_pointer_names(self, marshalled):
if self.member_type.is_pointer():
names = [self.name + "_out"]
if self.has_attr("marshall") == marshalled:
names = [self.name]
else:
names = []
else:
names = self.member_type.get_pointer_names()
names = self.member_type.get_pointer_names(marshalled)
if self.has_attr("outvar"):
prefix = self.attributes["outvar"][0]
names = map(lambda name: prefix + "_" + name, names)
@ -592,8 +595,8 @@ class SwitchCase:
def get_num_pointers(self):
return self.member.get_num_pointers()
def get_pointer_names(self):
return self.member.get_pointer_names()
def get_pointer_names(self, marshalled):
return self.member.get_pointer_names(marshalled)
class Switch(Containee):
def __init__(self, variable, cases, name, attribute_list):
@ -684,10 +687,10 @@ class Switch(Containee):
count = max(count, c.get_num_pointers())
return count
def get_pointer_names(self):
def get_pointer_names(self, marshalled):
names = []
for c in self.cases:
names = names + c.get_pointer_names()
names = names + c.get_pointer_names(marshalled)
return names
class ContainerType(Type):
@ -736,10 +739,10 @@ class ContainerType(Type):
count = count + m.get_num_pointers()
return count
def get_pointer_names(self):
def get_pointer_names(self, marshalled):
names = []
for m in self.members:
names = names + m.get_pointer_names()
names = names + m.get_pointer_names(marshalled)
return names
def has_pointer(self):