mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
Support @marshall to automatically marshall pointers
This commit is contained in:
parent
a24a8ff72a
commit
1be4d5d26c
@ -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
|
||||
|
||||
@ -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):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user