From 79bd3284c63db1a88c1f05ba6d867bb13ba82a03 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 14 Jun 2010 16:11:39 +0200 Subject: Add support for generating message and structure marshallers --- python_modules/marshal.py | 357 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 python_modules/marshal.py (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py new file mode 100644 index 0000000..23b029a --- /dev/null +++ b/python_modules/marshal.py @@ -0,0 +1,357 @@ +import ptypes +import codegen + +def write_includes(writer): + writer.header.writeln("#include ") + writer.header.writeln("#include ") + writer.header.newline() + writer.header.writeln("#ifndef _GENERATED_HEADERS_H") + writer.header.writeln("#define _GENERATED_HEADERS_H") + + writer.writeln("#include ") + writer.writeln("#include ") + writer.writeln("#include ") + writer.writeln("#include ") + writer.writeln("#include ") + writer.writeln("#include ") + writer.writeln("#include ") + writer.newline() + writer.writeln("#ifdef _MSC_VER") + writer.writeln("#pragma warning(disable:4101)") + writer.writeln("#endif") + writer.newline() + +class MarshallingSource: + def __init__(self): + pass + + def child_at_end(self, t): + return RootMarshallingSource(self, t.c_type(), t.sizeof()) + + def child_sub(self, member): + return SubMarshallingSource(self, member) + + def declare(self, writer): + return writer.optional_block(self.reuse_scope) + + def is_toplevel(self): + return self.parent_src == None and not self.is_helper + +class RootMarshallingSource(MarshallingSource): + def __init__(self, parent_src, c_type, sizeof, pointer = None): + self.is_helper = False + self.reuse_scope = None + self.parent_src = parent_src + if parent_src: + self.base_var = codegen.increment_identifier(parent_src.base_var) + else: + self.base_var = "src" + self.c_type = c_type + self.sizeof = sizeof + self.pointer = pointer # None == at "end" + + def get_self_ref(self): + return self.base_var + + def get_ref(self, member): + return self.base_var + "->" + member + + def declare(self, writer): + if self.reuse_scope: + scope = self.reuse_scope + else: + writer.begin_block() + scope = writer.get_subwriter() + + scope.variable_def(self.c_type + " *", self.base_var) + if not self.reuse_scope: + scope.newline() + + if self.pointer: + writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer)) + else: + writer.assign(self.base_var, "(%s *)end" % self.c_type) + writer.increment("end", "%s" % self.sizeof) + writer.newline() + + if self.reuse_scope: + return writer.no_block(self.reuse_scope) + else: + return writer.partial_block(scope) + +class SubMarshallingSource(MarshallingSource): + def __init__(self, parent_src, member): + self.reuse_scope = None + self.parent_src = parent_src + self.base_var = parent_src.base_var + self.member = member + self.is_helper = False + + def get_self_ref(self): + return "&%s" % self.parent_src.get_ref(self.member) + + def get_ref(self, member): + return self.parent_src.get_ref(self.member) + "." + member + +def write_marshal_ptr_function(writer, target_type): + if target_type.is_array(): + marshal_function = "spice_marshall_array_%s" % target_type.element_type.primitive_type() + else: + marshal_function = "spice_marshall_%s" % target_type.name + if writer.is_generated("marshaller", marshal_function): + return marshal_function + + writer.set_is_generated("marshaller", marshal_function) + + names = target_type.get_pointer_names() + names_args = "" + if len(names) > 0: + n = map(lambda name: ", SpiceMarshaller **%s" % name, names) + names_args = "".join(n) + + header = writer.header + writer = writer.function_helper() + writer.header = header + writer.out_prefix = "" + if target_type.is_array(): + scope = writer.function(marshal_function, "void *", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) + else: + 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") + + for n in names: + writer.assign("*%s" % n, "NULL") + + writer.newline() + writer.assign("end", "(uint8_t *)(ptr+1)") + + if target_type.is_struct(): + src = RootMarshallingSource(None, target_type.c_type(), target_type.sizeof(), "ptr") + src.reuse_scope = scope + write_container_marshaller(writer, target_type, src) + elif target_type.is_array() and target_type.element_type.is_primitive(): + with writer.index() as index: + with writer.for_loop(index, "count") as array_scope: + writer.statement("spice_marshaller_add_%s(m, *ptr++)" % (target_type.element_type.primitive_type())) + else: + writer.todo("Unsuppored pointer marshaller type") + + writer.statement("return end") + + writer.end_block() + + return marshal_function + +def get_array_size(array, container_src): + if array.is_constant_length(): + return array.size + elif array.is_identifier_length(): + return container_src.get_ref(array.size) + elif array.is_remaining_length(): + raise NotImplementedError("remaining size array sizes marshalling not supported") + elif array.is_image_size_length(): + bpp = array.size[1] + width = array.size[2] + rows = array.size[3] + width_v = container_src.get_ref(width) + rows_v = container_src.get_ref(rows) + # TODO: Handle multiplication overflow + if bpp == 8: + return "(%s * %s)" % (width_v, rows_v) + elif bpp == 1: + return "(((%s + 7) / 8 ) * %s)" % (width_v, rows_v) + else: + return "(((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v) + elif array.is_bytes_length(): + return container_src.get_ref(array.size[1]) + else: + raise NotImplementedError("TODO array size type not handled yet") + +def write_array_marshaller(writer, at_end, member, array, container_src, scope): + element_type = array.element_type + + if array.is_remaining_length(): + writer.comment("Remaining data must be appended manually").newline() + return + + nelements = get_array_size(array, container_src) + is_byte_size = array.is_bytes_length() + + if is_byte_size: + element = "%s__bytes" % member.name + else: + element = "%s__element" % member.name + + if not at_end: + writer.assign(element, container_src.get_ref(member.name)) + + if is_byte_size: + scope.variable_def("size_t", "array_end") + writer.assign("array_end", "spice_marshaller_get_size(m) + %s" % nelements) + + with writer.index(no_block = is_byte_size) as index: + with writer.while_loop("spice_marshaller_get_size(m) < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope: + array_scope.variable_def(element_type.c_type() + " *", element) + if at_end: + writer.assign(element, "(%s *)end" % element_type.c_type()) + writer.increment("end", element_type.sizeof()) + + if element_type.is_primitive(): + writer.statement("spice_marshaller_add_%s(m, *%s)" % (element_type.primitive_type(), element)) + elif element_type.is_struct(): + src2 = RootMarshallingSource(container_src, element_type.c_type(), element_type.sizeof(), element) + src2.reuse_scope = array_scope + write_container_marshaller(writer, element_type, src2) + else: + writer.todo("array element unhandled type").newline() + + if not at_end: + writer.statement("%s++" % element) + +def write_switch_marshaller(writer, container, switch, src, scope): + var = container.lookup_member(switch.variable) + var_type = var.member_type + + saved_out_prefix = writer.out_prefix + first = True + for c in switch.cases: + check = c.get_check(src.get_ref(switch.variable), var_type) + m = c.member + writer.out_prefix = saved_out_prefix + if m.has_attr("outvar"): + writer.out_prefix = "%s_%s" % (m.attributes["outvar"][0], writer.out_prefix) + with writer.if_block(check, not first, False) as block: + t = m.member_type + if switch.has_end_attr(): + src2 = src.child_at_end(m.member_type) + elif switch.has_attr("anon"): + src2 = src + else: + if t.is_struct(): + src2 = src.child_sub(switch.name + "." + m.name) + else: + src2 = src.child_sub(switch.name) + src2.reuse_scope = block + + 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, %s)" % ("0" if m.has_attr("ptr32") else "1")) + elif t.is_primitive(): + if m.has_attr("zero"): + writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type())) + else: + writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src2.get_ref(m.name))) + #TODO validate e.g. flags and enums + elif t.is_array(): + write_array_marshaller(writer, switch.has_end_attr(), m, t, src, scope) + else: + writer.todo("Can't handle type %s" % m.member_type) + + if switch.has_attr("fixedsize"): + remaining = switch.get_fixed_nw_size() - t.get_fixed_nw_size() + if remaining != 0: + writer.statement("spice_marshaller_reserve_space(m, %s)" % remaining) + + first = False + if switch.has_attr("fixedsize"): + with writer.block(" else"): + writer.statement("spice_marshaller_reserve_space(m, %s)" % switch.get_fixed_nw_size()) + + writer.newline() + +def write_member_marshaller(writer, container, member, src, scope): + if member.has_attr("outvar"): + writer.out_prefix = "%s_%s" % (member.attributes["outvar"][0], writer.out_prefix) + if member.has_attr("nomarshal"): + writer.comment("Don't marshall @nomarshal %s" % member.name).newline() + return + if member.is_switch(): + write_switch_marshaller(writer, container, member, src, scope) + return + + 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, %s)" % ("0" if member.has_attr("ptr32") else "1")) + elif t.is_primitive(): + if member.has_attr("zero"): + writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type())) + elif member.has_end_attr(): + writer.statement("spice_marshaller_add_%s(m, *(%s_t *)end)" % (t.primitive_type(), t.primitive_type())) + writer.increment("end", t.sizeof()) + else: + writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src.get_ref(member.name))) + elif t.is_array(): + write_array_marshaller(writer, member.has_end_attr(), member, t, src, scope) + elif t.is_struct(): + if member.has_end_attr(): + src2 = src.child_at_end(t) + else: + src2 = src.child_sub(member.name) + writer.comment(member.name) + write_container_marshaller(writer, t, src2) + else: + raise NotImplementedError("TODO can't handle parsing of %s" % t) + +def write_container_marshaller(writer, container, src): + saved_out_prefix = writer.out_prefix + with src.declare(writer) as scope: + for m in container.members: + writer.out_prefix = saved_out_prefix + write_member_marshaller(writer, container, m, src, scope) + +def write_message_marshaller(writer, message, is_server): + writer.out_prefix = "" + function_name = "spice_marshall_" + message.c_name() + if writer.is_generated("marshaller", function_name): + return function_name + writer.set_is_generated("marshaller", function_name) + + names = message.get_pointer_names() + names_args = "" + if len(names) > 0: + n = map(lambda name: ", SpiceMarshaller **%s" % name, names) + names_args = "".join(n) + + writer.header.writeln("void " + function_name + "(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");") + + scope = writer.function(function_name, + "void", + "SpiceMarshaller *m, %s *msg" % message.c_type() + names_args) + scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "end") + + for n in names: + writer.assign("*%s" % n, "NULL") + + src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg") + src.reuse_scope = scope + + writer.assign("end", "(uint8_t *)(msg+1)") + write_container_marshaller(writer, message, src) + + writer.end_block() + writer.newline() + +def write_protocol_marshaller(writer, proto, is_server): + for c in proto.channels: + channel = c.channel_type + if is_server: + for m in channel.client_messages: + message = m.message_type + write_message_marshaller(writer, message, is_server) + else: + for m in channel.server_messages: + message = m.message_type + write_message_marshaller(writer, message, is_server) + +def write_trailer(writer): + writer.header.writeln("#endif") -- cgit From b49b77d8e9bd535d88e1ad72d6bdbbddba015040 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 18 Jun 2010 21:10:25 +0200 Subject: Make generated marshallers build on win32 --- python_modules/marshal.py | 1 + 1 file changed, 1 insertion(+) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 23b029a..4cbf942 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -18,6 +18,7 @@ def write_includes(writer): writer.newline() writer.writeln("#ifdef _MSC_VER") writer.writeln("#pragma warning(disable:4101)") + writer.writeln("#pragma warning(disable:4018)") writer.writeln("#endif") writer.newline() -- cgit From 38412df9aaac82865f7251ee67623fe48d034940 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 22 Jun 2010 10:32:08 +0200 Subject: Support creating marshallers that are called indirectly This is needed if we want to switch marshallers depending on what major version the remote side has. --- python_modules/marshal.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 4cbf942..4279cf0 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -310,7 +310,7 @@ def write_container_marshaller(writer, container, src): writer.out_prefix = saved_out_prefix write_member_marshaller(writer, container, m, src, scope) -def write_message_marshaller(writer, message, is_server): +def write_message_marshaller(writer, message, is_server, private): writer.out_prefix = "" function_name = "spice_marshall_" + message.c_name() if writer.is_generated("marshaller", function_name): @@ -323,10 +323,11 @@ def write_message_marshaller(writer, message, is_server): n = map(lambda name: ", SpiceMarshaller **%s" % name, names) names_args = "".join(n) - writer.header.writeln("void " + function_name + "(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");") + if not private: + writer.header.writeln("void " + function_name + "(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");") scope = writer.function(function_name, - "void", + "static void" if private else "void", "SpiceMarshaller *m, %s *msg" % message.c_type() + names_args) scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "end") @@ -341,18 +342,36 @@ def write_message_marshaller(writer, message, is_server): writer.end_block() writer.newline() + return function_name -def write_protocol_marshaller(writer, proto, is_server): +def write_protocol_marshaller(writer, proto, is_server, private_marshallers): + functions = {} for c in proto.channels: channel = c.channel_type if is_server: for m in channel.client_messages: message = m.message_type - write_message_marshaller(writer, message, is_server) + f = write_message_marshaller(writer, message, is_server, private_marshallers) + functions[f] = True else: for m in channel.server_messages: message = m.message_type - write_message_marshaller(writer, message, is_server) + f= write_message_marshaller(writer, message, is_server, private_marshallers) + functions[f] = True + + if private_marshallers: + scope = writer.function("spice_message_marshallers_get", + "SpiceMessageMarshallers *", + "void") + writer.writeln("static SpiceMessageMarshallers marshallers = {NULL};").newline() + for f in sorted(functions.keys()): + member = f[len("spice_marshall_"):] + writer.assign("marshallers.%s" % member, f) + + writer.newline() + writer.statement("return &marshallers") + writer.end_block() + writer.newline() def write_trailer(writer): writer.header.writeln("#endif") -- cgit From 2523cec8c4890f977ee5569d9280d54108790674 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 22 Jun 2010 16:01:57 +0200 Subject: Support extra prefix in code generators This is require when we add a new spice.proto for the old (major 1) protocol description. --- python_modules/marshal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 4279cf0..76081a9 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -360,7 +360,7 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): functions[f] = True if private_marshallers: - scope = writer.function("spice_message_marshallers_get", + scope = writer.function("spice_message_marshallers_get" + writer.public_prefix, "SpiceMessageMarshallers *", "void") writer.writeln("static SpiceMessageMarshallers marshallers = {NULL};").newline() -- cgit From 9f3a36f3f939c14da4e2fa1f98f3ebfd50dcf9c7 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 22 Jun 2010 16:03:02 +0200 Subject: Make internal generated marshaller functions static --- python_modules/marshal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 76081a9..c4bb896 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -115,7 +115,7 @@ def write_marshal_ptr_function(writer, target_type): writer.header = header writer.out_prefix = "" if target_type.is_array(): - scope = writer.function(marshal_function, "void *", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) + scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void *", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) else: 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 + ");") -- cgit From ee944c8314287a1037b9ede077583b1cec31ea07 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 22 Jun 2010 16:03:34 +0200 Subject: Add support for @virtual markup in spice protocol This means the member is not sent on the network at all. Instead its initialized to the attribute argument when demarshalled. This is useful for backwards compatibility support. --- python_modules/marshal.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index c4bb896..c5afd7c 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -266,6 +266,9 @@ def write_switch_marshaller(writer, container, switch, src, scope): def write_member_marshaller(writer, container, member, src, scope): if member.has_attr("outvar"): writer.out_prefix = "%s_%s" % (member.attributes["outvar"][0], writer.out_prefix) + if member.has_attr("virtual"): + writer.comment("Don't marshall @virtual %s" % member.name).newline() + return if member.has_attr("nomarshal"): writer.comment("Don't marshall @nomarshal %s" % member.name).newline() return -- cgit From 1d5d5272e28f8d12f5b93e4d8e5f85561eafda25 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 23 Jun 2010 16:20:33 +0200 Subject: Make pointers 32bit in new protocol format --- python_modules/marshal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index c5afd7c..ef1a47c 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -239,7 +239,7 @@ def write_switch_marshaller(writer, container, switch, src, scope): 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, %s)" % ("0" if m.has_attr("ptr32") else "1")) + 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)) elif t.is_primitive(): if m.has_attr("zero"): writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type())) @@ -285,7 +285,7 @@ def write_member_marshaller(writer, container, member, src, scope): # 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, %s)" % ("0" if member.has_attr("ptr32") else "1")) + 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)) elif t.is_primitive(): if member.has_attr("zero"): writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type())) -- cgit From 144b2fbd75812b38d1c6086ca2561f47bc371898 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 28 Jun 2010 12:45:07 +0200 Subject: Fix build error due to member "SpiceMsgEmpty" same name as type --- python_modules/marshal.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index ef1a47c..1eb3675 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -369,6 +369,8 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): writer.writeln("static SpiceMessageMarshallers marshallers = {NULL};").newline() for f in sorted(functions.keys()): member = f[len("spice_marshall_"):] + if not member.startswith("msg"): + member = "msg_" + member writer.assign("marshallers.%s" % member, f) writer.newline() -- cgit From e42c910b5cb5e6de734064fb57832a6e73e34092 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 29 Jun 2010 21:42:59 +0200 Subject: Store SpicePath segment count rather than size Internally and in the network protocol (for the new version) we now store the actual number of segments rather than the size of the full segments array in bytes. This change consists of multiple changes to handle this: * Make the qxl parser calculate num_segments * Make the canvas stroke code handle the new SpicePath layout. * Fix up is_equal_path in red_worker.c for the new layout * replace multiple calls to spice_marshall_PathSegment with a single spice_marshall_Path call * Make the byte_size() array size handling do the conversion from network size to number of elements when marshalling/demarshalling. * Update the current spice protocol to send the segment count rather than the size * Update the old spice protocol to use the new byte_size functionallity to calculate the size sent and the number of elements recieved --- python_modules/marshal.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 1eb3675..250147f 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -165,7 +165,7 @@ def get_array_size(array, container_src): else: return "(((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v) elif array.is_bytes_length(): - return container_src.get_ref(array.size[1]) + return container_src.get_ref(array.size[2]) else: raise NotImplementedError("TODO array size type not handled yet") @@ -179,20 +179,18 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): nelements = get_array_size(array, container_src) is_byte_size = array.is_bytes_length() - if is_byte_size: - element = "%s__bytes" % member.name - else: - element = "%s__element" % member.name + element = "%s__element" % member.name if not at_end: writer.assign(element, container_src.get_ref(member.name)) if is_byte_size: - scope.variable_def("size_t", "array_end") - writer.assign("array_end", "spice_marshaller_get_size(m) + %s" % nelements) + size_start_var = "%s__size_start" % member.name + scope.variable_def("size_t", size_start_var) + writer.assign(size_start_var, "spice_marshaller_get_size(m)") - with writer.index(no_block = is_byte_size) as index: - with writer.while_loop("spice_marshaller_get_size(m) < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope: + with writer.index() as index: + with writer.for_loop(index, nelements) as array_scope: array_scope.variable_def(element_type.c_type() + " *", element) if at_end: writer.assign(element, "(%s *)end" % element_type.c_type()) @@ -210,6 +208,12 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): if not at_end: writer.statement("%s++" % element) + if is_byte_size: + size_var = member.container.lookup_member(array.size[1]) + size_var_type = size_var.member_type + 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_switch_marshaller(writer, container, switch, src, scope): var = container.lookup_member(switch.variable) var_type = var.member_type @@ -289,6 +293,11 @@ def write_member_marshaller(writer, container, member, src, scope): elif t.is_primitive(): if member.has_attr("zero"): writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type())) + if member.has_attr("bytes_count"): + var = "%s__ref" % member.name + scope.variable_def("void *", var) + writer.statement("%s = spice_marshaller_add_%s(m, %s)" % (var, t.primitive_type(), 0)) + elif member.has_end_attr(): writer.statement("spice_marshaller_add_%s(m, *(%s_t *)end)" % (t.primitive_type(), t.primitive_type())) writer.increment("end", t.sizeof()) -- cgit From 02a429e46e526bbdefc7c2ca44fc585f2a90826e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 30 Jun 2010 13:24:59 +0200 Subject: Support @marshall to automatically marshall pointers --- python_modules/marshal.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 250147f..da9b0d8 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -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 -- cgit From 6228ae633e58f484f0da5cc20dcfbf42ead4859b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 30 Jun 2010 22:19:12 +0200 Subject: Properly parse and marshall SpiceString --- python_modules/marshal.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index da9b0d8..95413fc 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -50,6 +50,7 @@ class RootMarshallingSource(MarshallingSource): self.c_type = c_type self.sizeof = sizeof self.pointer = pointer # None == at "end" + self.update_end = False def get_self_ref(self): return self.base_var @@ -70,6 +71,8 @@ class RootMarshallingSource(MarshallingSource): if self.pointer: writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer)) + if self.update_end: + writer.assign("end", "((uint8_t *)%s) + %s" % (self.base_var, self.sizeof)) else: writer.assign(self.base_var, "(%s *)end" % self.c_type) writer.increment("end", "%s" % self.sizeof) @@ -182,8 +185,18 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): element = "%s__element" % member.name + if not scope.variable_defined(element): + if array.ptr_array: + stars = " **" + else: + stars = " *" + scope.variable_def(element_type.c_type() + stars, element) + element_array = element + if array.ptr_array: + element = "*" + element + if not at_end: - writer.assign(element, container_src.get_ref(member.name)) + writer.assign(element_array, container_src.get_ref(member.name)) if is_byte_size: size_start_var = "%s__size_start" % member.name @@ -192,7 +205,6 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): with writer.index() as index: with writer.for_loop(index, nelements) as array_scope: - array_scope.variable_def(element_type.c_type() + " *", element) if at_end: writer.assign(element, "(%s *)end" % element_type.c_type()) writer.increment("end", element_type.sizeof()) @@ -201,13 +213,15 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): writer.statement("spice_marshaller_add_%s(m, *%s)" % (element_type.primitive_type(), element)) elif element_type.is_struct(): src2 = RootMarshallingSource(container_src, element_type.c_type(), element_type.sizeof(), element) + if array.is_extra_size(): + src2.update_end = True src2.reuse_scope = array_scope write_container_marshaller(writer, element_type, src2) else: writer.todo("array element unhandled type").newline() if not at_end: - writer.statement("%s++" % element) + writer.statement("%s++" % element_array) if is_byte_size: size_var = member.container.lookup_member(array.size[1]) -- cgit From fefc89c6c45a5371be611c83e570d9f3fbc7fe75 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 5 Jul 2010 12:03:34 +0200 Subject: marshaller: Add generic way to handle propagating attributes Also switches @ptr_array to use this --- python_modules/marshal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 95413fc..f151d94 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -186,13 +186,13 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): element = "%s__element" % member.name if not scope.variable_defined(element): - if array.ptr_array: + if array.has_attr("ptr_array"): stars = " **" else: stars = " *" scope.variable_def(element_type.c_type() + stars, element) element_array = element - if array.ptr_array: + if array.has_attr("ptr_array"): element = "*" + element if not at_end: -- cgit From 32481bf381f97cf99bee6df36afadbb213b61e3f Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 5 Jul 2010 12:13:45 +0200 Subject: marshaller: Make @nonnull a propagated attribute This cleans up some stuff --- python_modules/marshal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index f151d94..df0c3b3 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -235,7 +235,7 @@ def write_pointer_marshaller(writer, member, src): 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"): + if t.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: -- cgit From 373993f32c094296aa11ca61dec424dbed3083af Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 19 Jul 2010 10:12:41 +0200 Subject: codegen: Pass member to SubMarshallingSource rather than name This way we can check attributes on the member. --- python_modules/marshal.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index df0c3b3..6b2d428 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -29,8 +29,8 @@ class MarshallingSource: def child_at_end(self, t): return RootMarshallingSource(self, t.c_type(), t.sizeof()) - def child_sub(self, member): - return SubMarshallingSource(self, member) + def child_sub(self, containee): + return SubMarshallingSource(self, containee) def declare(self, writer): return writer.optional_block(self.reuse_scope) @@ -84,18 +84,19 @@ class RootMarshallingSource(MarshallingSource): return writer.partial_block(scope) class SubMarshallingSource(MarshallingSource): - def __init__(self, parent_src, member): + def __init__(self, parent_src, containee): self.reuse_scope = None self.parent_src = parent_src self.base_var = parent_src.base_var - self.member = member + self.containee = containee + self.name = containee.name self.is_helper = False def get_self_ref(self): - return "&%s" % self.parent_src.get_ref(self.member) + return "&%s" % self.parent_src.get_ref(self.name) def get_ref(self, member): - return self.parent_src.get_ref(self.member) + "." + member + return self.parent_src.get_ref(self.name) + "." + member def write_marshal_ptr_function(writer, target_type): if target_type.is_array(): @@ -263,9 +264,9 @@ def write_switch_marshaller(writer, container, switch, src, scope): src2 = src else: if t.is_struct(): - src2 = src.child_sub(switch.name + "." + m.name) + src2 = src.child_sub(switch).child_sub(m) else: - src2 = src.child_sub(switch.name) + src2 = src.child_sub(switch) src2.reuse_scope = block if t.is_struct(): @@ -331,7 +332,7 @@ def write_member_marshaller(writer, container, member, src, scope): if member.has_end_attr(): src2 = src.child_at_end(t) else: - src2 = src.child_sub(member.name) + src2 = src.child_sub(member) writer.comment(member.name) write_container_marshaller(writer, t, src2) else: -- cgit From d9629ca4e700cb35b77579bde4ab78ad7adbb30a Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 19 Jul 2010 14:10:16 +0200 Subject: codegen: Various cleanups Remove all uses of @end in the marshaller, instead just using the C struct array-at-end-of-struct. To make this work we also remove all use of @end for switches (making them C unions). We drop the zero member of the notify message so that we can avoid this use of @end for a primitive in the marshaller (plus its useless to send over the wire). We change the offsets and stuff in the migration messages to real pointers. --- python_modules/marshal.py | 68 ++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 45 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 6b2d428..cf6ad08 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -49,8 +49,8 @@ class RootMarshallingSource(MarshallingSource): self.base_var = "src" self.c_type = c_type self.sizeof = sizeof - self.pointer = pointer # None == at "end" - self.update_end = False + self.pointer = pointer + assert pointer != None def get_self_ref(self): return self.base_var @@ -69,13 +69,7 @@ class RootMarshallingSource(MarshallingSource): if not self.reuse_scope: scope.newline() - if self.pointer: - writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer)) - if self.update_end: - writer.assign("end", "((uint8_t *)%s) + %s" % (self.base_var, self.sizeof)) - else: - writer.assign(self.base_var, "(%s *)end" % self.c_type) - writer.increment("end", "%s" % self.sizeof) + writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer)) writer.newline() if self.reuse_scope: @@ -119,18 +113,16 @@ def write_marshal_ptr_function(writer, target_type): writer.header = header writer.out_prefix = "" if target_type.is_array(): - scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void *", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) + scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) else: - 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 = 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 SpiceMarshaller *", "m2") for n in names: writer.assign("*%s_out" % n, "NULL") writer.newline() - writer.assign("end", "(uint8_t *)(ptr+1)") if target_type.is_struct(): src = RootMarshallingSource(None, target_type.c_type(), target_type.sizeof(), "ptr") @@ -143,8 +135,6 @@ def write_marshal_ptr_function(writer, target_type): else: writer.todo("Unsuppored pointer marshaller type") - writer.statement("return end") - writer.end_block() return marshal_function @@ -172,9 +162,9 @@ def get_array_size(array, container_src): elif array.is_bytes_length(): return container_src.get_ref(array.size[2]) else: - raise NotImplementedError("TODO array size type not handled yet") + raise NotImplementedError("TODO array size type not handled yet: %s" % array) -def write_array_marshaller(writer, at_end, member, array, container_src, scope): +def write_array_marshaller(writer, member, array, container_src, scope): element_type = array.element_type if array.is_remaining_length(): @@ -196,8 +186,7 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): if array.has_attr("ptr_array"): element = "*" + element - if not at_end: - writer.assign(element_array, container_src.get_ref(member.name)) + writer.assign(element_array, container_src.get_ref(member.name)) if is_byte_size: size_start_var = "%s__size_start" % member.name @@ -206,23 +195,16 @@ def write_array_marshaller(writer, at_end, member, array, container_src, scope): with writer.index() as index: with writer.for_loop(index, nelements) as array_scope: - if at_end: - writer.assign(element, "(%s *)end" % element_type.c_type()) - writer.increment("end", element_type.sizeof()) - if element_type.is_primitive(): writer.statement("spice_marshaller_add_%s(m, *%s)" % (element_type.primitive_type(), element)) elif element_type.is_struct(): src2 = RootMarshallingSource(container_src, element_type.c_type(), element_type.sizeof(), element) - if array.is_extra_size(): - src2.update_end = True src2.reuse_scope = array_scope write_container_marshaller(writer, element_type, src2) else: writer.todo("array element unhandled type").newline() - if not at_end: - writer.statement("%s++" % element_array) + writer.statement("%s++" % element_array) if is_byte_size: size_var = member.container.lookup_member(array.size[1]) @@ -235,12 +217,15 @@ def write_pointer_marshaller(writer, member, src): 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"): + rest_args = "" + if t.target_type.is_array(): + rest_args = ", %s" % get_array_size(t.target_type, src) writer.assign("m2", submarshaller) if t.has_attr("nonnull"): - writer.statement("%s(m2, %s)" % (ptr_func, src.get_ref(member.name))) + writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args)) 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))) + writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args)) else: writer.assign("*%s_out" % (writer.out_prefix + member.name), submarshaller) @@ -258,10 +243,11 @@ def write_switch_marshaller(writer, container, switch, src, scope): writer.out_prefix = "%s_%s" % (m.attributes["outvar"][0], writer.out_prefix) with writer.if_block(check, not first, False) as block: t = m.member_type - if switch.has_end_attr(): - src2 = src.child_at_end(m.member_type) - elif switch.has_attr("anon"): - src2 = src + if switch.has_attr("anon"): + if t.is_struct(): + src2 = src.child_sub(m) + else: + src2 = src else: if t.is_struct(): src2 = src.child_sub(switch).child_sub(m) @@ -280,7 +266,7 @@ def write_switch_marshaller(writer, container, switch, src, scope): writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src2.get_ref(m.name))) #TODO validate e.g. flags and enums elif t.is_array(): - write_array_marshaller(writer, switch.has_end_attr(), m, t, src, scope) + write_array_marshaller(writer, m, t, src2, scope) else: writer.todo("Can't handle type %s" % m.member_type) @@ -321,18 +307,12 @@ def write_member_marshaller(writer, container, member, src, scope): scope.variable_def("void *", var) writer.statement("%s = spice_marshaller_add_%s(m, %s)" % (var, t.primitive_type(), 0)) - elif member.has_end_attr(): - writer.statement("spice_marshaller_add_%s(m, *(%s_t *)end)" % (t.primitive_type(), t.primitive_type())) - writer.increment("end", t.sizeof()) else: writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src.get_ref(member.name))) elif t.is_array(): - write_array_marshaller(writer, member.has_end_attr(), member, t, src, scope) + write_array_marshaller(writer, member, t, src, scope) elif t.is_struct(): - if member.has_end_attr(): - src2 = src.child_at_end(t) - else: - src2 = src.child_sub(member) + src2 = src.child_sub(member) writer.comment(member.name) write_container_marshaller(writer, t, src2) else: @@ -364,7 +344,6 @@ def write_message_marshaller(writer, message, is_server, private): scope = writer.function(function_name, "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: @@ -373,7 +352,6 @@ def write_message_marshaller(writer, message, is_server, private): src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg") src.reuse_scope = scope - writer.assign("end", "(uint8_t *)(msg+1)") write_container_marshaller(writer, message, src) writer.end_block() -- cgit From f008b7605df19ab5deb8f4f383837bef9416d7a1 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 19 Jul 2010 15:47:40 +0200 Subject: codegen: Allow @to_ptr to make inline structs demarshal as pointers --- python_modules/marshal.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index cf6ad08..6b894c1 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -87,10 +87,16 @@ class SubMarshallingSource(MarshallingSource): self.is_helper = False def get_self_ref(self): - return "&%s" % self.parent_src.get_ref(self.name) + if self.containee.has_attr("to_ptr"): + return "%s" % self.parent_src.get_ref(self.name) + else: + return "&%s" % self.parent_src.get_ref(self.name) def get_ref(self, member): - return self.parent_src.get_ref(self.name) + "." + member + if self.containee.has_attr("to_ptr"): + return self.parent_src.get_ref(self.name) + "->" + member + else: + return self.parent_src.get_ref(self.name) + "." + member def write_marshal_ptr_function(writer, target_type): if target_type.is_array(): -- cgit From aa7a086933c8b03d2f7f78874342a53719a24fa5 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Thu, 29 Jul 2010 09:03:15 -0400 Subject: support python 2.5.4+ for marshaller/demarshallers Patch adds a "from __future__" import that doesn't affect newer python's but allows python 2.5.4 to run the code (tested under scratchbox, n900 build environment) --- python_modules/marshal.py | 1 + 1 file changed, 1 insertion(+) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 6b894c1..9ee1466 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -1,3 +1,4 @@ +from __future__ import with_statement import ptypes import codegen -- cgit From 11269608a77b22df32ac1760b1df261c2b407af7 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Mon, 6 Dec 2010 18:02:34 +0200 Subject: mingw32 build: python_modules/marshal: use unsigned for for_loop index variable --- python_modules/marshal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 9ee1466..a82df98 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -120,7 +120,7 @@ def write_marshal_ptr_function(writer, target_type): writer.header = header writer.out_prefix = "" if target_type.is_array(): - scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void", "SpiceMarshaller *m, %s_t *ptr, int count" % target_type.element_type.primitive_type() + names_args) + scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void", "SpiceMarshaller *m, %s_t *ptr, unsigned count" % target_type.element_type.primitive_type() + names_args) else: 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 + ");") -- cgit From 3a6de6d6fb0362df9e78fa64942a45c02bdabe53 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Mon, 24 Jan 2011 23:32:43 +0200 Subject: demarshaller/marshaller fix gcc 4.6.0 python_modules/demarshal.py and marshal.py fixes for gcc 4.6.0 warning about set but unused variables. The fixes disable creating of variables mem_size when they are not used (demarshall) and declaring a src variable when the message doesn't use it (marshal). You need to touch *.proto after applying this (should add a Makefile dependency). --- python_modules/marshal.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index a82df98..5b4dfdd 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -356,10 +356,12 @@ def write_message_marshaller(writer, message, is_server, private): for n in names: writer.assign("*%s_out" % n, "NULL") - src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg") - src.reuse_scope = scope + # fix warnings about unused variables by not creating body if no members to parse + if any(x.is_fixed_nw_size() for x in message.members): + src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg") + src.reuse_scope = scope - write_container_marshaller(writer, message, src) + write_container_marshaller(writer, message, src) writer.end_block() writer.newline() -- cgit From 12a5ce3dc5d9b130de1eba7038c9915428fac802 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 22 Jun 2011 13:26:15 +0200 Subject: handle @ifdef on messages and channels --- python_modules/marshal.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 5b4dfdd..d93f983 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -333,6 +333,8 @@ def write_container_marshaller(writer, container, src): write_member_marshaller(writer, container, m, src, scope) def write_message_marshaller(writer, message, is_server, private): + if message.has_attr("ifdef"): + writer.ifdef(message.attributes["ifdef"][0]) writer.out_prefix = "" function_name = "spice_marshall_" + message.c_name() if writer.is_generated("marshaller", function_name): @@ -364,6 +366,8 @@ def write_message_marshaller(writer, message, is_server, private): write_container_marshaller(writer, message, src) writer.end_block() + if message.has_attr("ifdef"): + writer.endif(message.attributes["ifdef"][0]) writer.newline() return function_name @@ -371,16 +375,30 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): functions = {} for c in proto.channels: channel = c.channel_type + if channel.has_attr("ifdef"): + writer.ifdef(channel.attributes["ifdef"][0]) if is_server: for m in channel.client_messages: message = m.message_type f = write_message_marshaller(writer, message, is_server, private_marshallers) - functions[f] = True + if channel.has_attr("ifdef") and not functions.has_key(f): + functions[f] = channel.attributes["ifdef"][0] + elif message.has_attr("ifdef") and not functions.has_key(f): + functions[f] = message.attributes["ifdef"][0] + else: + functions[f] = True else: for m in channel.server_messages: message = m.message_type - f= write_message_marshaller(writer, message, is_server, private_marshallers) - functions[f] = True + f = write_message_marshaller(writer, message, is_server, private_marshallers) + if channel.has_attr("ifdef") and not functions.has_key(f): + functions[f] = channel.attributes["ifdef"][0] + elif message.has_attr("ifdef") and not functions.has_key(f): + functions[f] = message.attributes["ifdef"][0] + else: + functions[f] = True + if channel.has_attr("ifdef"): + writer.endif(channel.attributes["ifdef"][0]) if private_marshallers: scope = writer.function("spice_message_marshallers_get" + writer.public_prefix, @@ -391,7 +409,11 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): member = f[len("spice_marshall_"):] if not member.startswith("msg"): member = "msg_" + member + if functions[f] != True: + writer.ifdef(functions[f]) writer.assign("marshallers.%s" % member, f) + if functions[f] != True: + writer.endif(functions[f]) writer.newline() writer.statement("return &marshallers") -- cgit From ecce70452f5e28e111fb7acd6eac5c169ba67cff Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 21 Mar 2012 01:43:29 +0100 Subject: codegen: struct marshallers are not current function helper This solves the issue of struct_marshallers being included within the current ifdef/endif body, although they are independant functions. --- python_modules/marshal.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index d93f983..dc10a4c 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -99,7 +99,7 @@ class SubMarshallingSource(MarshallingSource): else: return self.parent_src.get_ref(self.name) + "." + member -def write_marshal_ptr_function(writer, target_type): +def write_marshal_ptr_function(writer, target_type, is_helper=True): if target_type.is_array(): marshal_function = "spice_marshall_array_%s" % target_type.element_type.primitive_type() else: @@ -116,7 +116,8 @@ def write_marshal_ptr_function(writer, target_type): names_args = "".join(n) header = writer.header - writer = writer.function_helper() + if is_helper: + writer = writer.function_helper() writer.header = header writer.out_prefix = "" if target_type.is_array(): -- cgit From 055c68ccdd33cb9d22ee34275aceb345092955f8 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 21 Mar 2012 01:45:04 +0100 Subject: codegen: include headers locally --- python_modules/marshal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index dc10a4c..8cbc426 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -4,7 +4,7 @@ import codegen def write_includes(writer): writer.header.writeln("#include ") - writer.header.writeln("#include ") + writer.header.writeln('#include "marshaller.h"') writer.header.newline() writer.header.writeln("#ifndef _GENERATED_HEADERS_H") writer.header.writeln("#define _GENERATED_HEADERS_H") @@ -15,7 +15,7 @@ def write_includes(writer): writer.writeln("#include ") writer.writeln("#include ") writer.writeln("#include ") - writer.writeln("#include ") + writer.writeln('#include "marshaller.h"') writer.newline() writer.writeln("#ifdef _MSC_VER") writer.writeln("#pragma warning(disable:4101)") -- cgit From 3215ddd6cd73adef6d0a7774ece46c3526b0b26b Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 21 Mar 2012 01:46:44 +0100 Subject: codegen: ifdef/endif function declaration too Compile out part that we are not supporting. In the future, we might want to declare a fake type and an empty function to keep API compatibility --- python_modules/marshal.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 8cbc426..4020799 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -378,6 +378,7 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): channel = c.channel_type if channel.has_attr("ifdef"): writer.ifdef(channel.attributes["ifdef"][0]) + writer.header.ifdef(channel.attributes["ifdef"][0]) if is_server: for m in channel.client_messages: message = m.message_type @@ -400,6 +401,7 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): functions[f] = True if channel.has_attr("ifdef"): writer.endif(channel.attributes["ifdef"][0]) + writer.header.endif(channel.attributes["ifdef"][0]) if private_marshallers: scope = writer.function("spice_message_marshallers_get" + writer.public_prefix, -- cgit From ef14521ac5218ca876e29173470fdb41a0cc821c Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Wed, 19 Mar 2014 15:41:07 +0100 Subject: Use #include "common/..." in (de)marshallers Now that they are created in $builddir, their includes will need to refer to files in $srcdir, which can be different. It's cleaner to add -I $(top_srcdir)/spice-common/ to modules using spice-common rather than having -I $(top_srcdir)/spice-common/common which would could create header collisions. --- python_modules/marshal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 4020799..ae5fe31 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -4,7 +4,7 @@ import codegen def write_includes(writer): writer.header.writeln("#include ") - writer.header.writeln('#include "marshaller.h"') + writer.header.writeln('#include "common/marshaller.h"') writer.header.newline() writer.header.writeln("#ifndef _GENERATED_HEADERS_H") writer.header.writeln("#define _GENERATED_HEADERS_H") @@ -15,7 +15,7 @@ def write_includes(writer): writer.writeln("#include ") writer.writeln("#include ") writer.writeln("#include ") - writer.writeln('#include "marshaller.h"') + writer.writeln('#include "common/marshaller.h"') writer.newline() writer.writeln("#ifdef _MSC_VER") writer.writeln("#pragma warning(disable:4101)") -- cgit From 744675b424a9db5e6fc26440dcfab961fd1d284e Mon Sep 17 00:00:00 2001 From: Fabiano Fidêncio Date: Wed, 3 Sep 2014 11:51:45 +0200 Subject: python: Fix -Wunused-parameter Although the most part of the parameters marked as unused are actually being used for a few functions, a bunch of warnings can be seen when the code is compiled with "-Wall -Wextra". As adding the unused attribute means that the variable/parameter is meant to be *possibly* unused, we're safe adding it in the generated code, even for used variables/parameters. --- python_modules/marshal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index ae5fe31..97d02e9 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -353,7 +353,7 @@ def write_message_marshaller(writer, message, is_server, private): scope = writer.function(function_name, "static void" if private else "void", - "SpiceMarshaller *m, %s *msg" % message.c_type() + names_args) + "SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED %s *msg" % message.c_type() + names_args) scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2") for n in names: -- cgit From cb37de352012da27268882eb24784ba39e834712 Mon Sep 17 00:00:00 2001 From: Fabiano Fidêncio Date: Wed, 3 Sep 2014 15:14:54 +0200 Subject: python: Fix -Wsign-compare The return of the get_array_size() is used as a limit in a loop, being compared with an unsigned index (indexes are always unsigned). To avoid the -Wsign-compare warning, let's cast the return of the get_array_size() to unsigned and make GCC happier. --- python_modules/marshal.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 97d02e9..1eda1ba 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -162,11 +162,11 @@ def get_array_size(array, container_src): rows_v = container_src.get_ref(rows) # TODO: Handle multiplication overflow if bpp == 8: - return "(%s * %s)" % (width_v, rows_v) + return "(unsigned) (%s * %s)" % (width_v, rows_v) elif bpp == 1: - return "(((%s + 7) / 8 ) * %s)" % (width_v, rows_v) + return "(unsigned) (((%s + 7) / 8 ) * %s)" % (width_v, rows_v) else: - return "(((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v) + return "(unsigned) (((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v) elif array.is_bytes_length(): return container_src.get_ref(array.size[2]) else: -- cgit From e919337980c45fb4bc907cf40cdd106fb8f32d92 Mon Sep 17 00:00:00 2001 From: Alexander Wauck Date: Tue, 31 Mar 2015 12:44:09 -0500 Subject: Make spice_codegen.py work on both Python 2 and 3 This is a new version of my previous patch that does not include six.py. It's still kind of big, but at least it's all spice-common changes now. There are also a few other fixes that Christophe brought to my attention. Note that six now needs to be installed on the system (python-six on Fedora and Debian, six on PyPI). This *should* be enough to make spice_codegen.py work on both Python 2 and Python 3. The major changes are as follows: * cStringIO.StringIO -> io.StringIO * str vs. unicode updates (io.StringIO doesn't like str) * integer division * foo.has_key(bar) -> bar in foo * import internal_thing -> from . import internal_thing * removed from __future__ import with_statement (might break Python 2.5?) * changed some lambdas to list comprehensions (done by 2to3) * cast some_dict.keys() to list where needed (e.g. for sorting) * use normal type names with isinstance instead of types.WhateverType Signed-off-by: Alexander Wauck --- python_modules/marshal.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index 1eda1ba..b77b910 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -1,6 +1,6 @@ -from __future__ import with_statement -import ptypes -import codegen + +from . import ptypes +from . import codegen def write_includes(writer): writer.header.writeln("#include ") @@ -112,7 +112,7 @@ def write_marshal_ptr_function(writer, target_type, is_helper=True): names = target_type.get_pointer_names(False) names_args = "" if len(names) > 0: - n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names) + n = [", SpiceMarshaller **%s_out" % name for name in names] names_args = "".join(n) header = writer.header @@ -345,7 +345,7 @@ def write_message_marshaller(writer, message, is_server, private): names = message.get_pointer_names(False) names_args = "" if len(names) > 0: - n = map(lambda name: ", SpiceMarshaller **%s_out" % name, names) + n = [", SpiceMarshaller **%s_out" % name for name in names] names_args = "".join(n) if not private: @@ -383,9 +383,9 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): for m in channel.client_messages: message = m.message_type f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and not functions.has_key(f): + if channel.has_attr("ifdef") and f not in functions: functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and not functions.has_key(f): + elif message.has_attr("ifdef") and f not in functions: functions[f] = message.attributes["ifdef"][0] else: functions[f] = True @@ -393,9 +393,9 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): for m in channel.server_messages: message = m.message_type f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and not functions.has_key(f): + if channel.has_attr("ifdef") and f not in functions: functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and not functions.has_key(f): + elif message.has_attr("ifdef") and f not in functions: functions[f] = message.attributes["ifdef"][0] else: functions[f] = True -- cgit From 5bad231e80ad6202b1860783cc29093b0457d296 Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Tue, 21 Jul 2015 17:45:32 +0100 Subject: codegen: Simplify if/else blocks Blocks were mainly the same, this reduces the amount of code. Signed-off-by: Frediano Ziglio --- python_modules/marshal.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'python_modules/marshal.py') diff --git a/python_modules/marshal.py b/python_modules/marshal.py index b77b910..1d38d3d 100644 --- a/python_modules/marshal.py +++ b/python_modules/marshal.py @@ -380,25 +380,18 @@ def write_protocol_marshaller(writer, proto, is_server, private_marshallers): writer.ifdef(channel.attributes["ifdef"][0]) writer.header.ifdef(channel.attributes["ifdef"][0]) if is_server: - for m in channel.client_messages: - message = m.message_type - f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and f not in functions: - functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and f not in functions: - functions[f] = message.attributes["ifdef"][0] - else: - functions[f] = True + messages = channel.client_messages else: - for m in channel.server_messages: - message = m.message_type - f = write_message_marshaller(writer, message, is_server, private_marshallers) - if channel.has_attr("ifdef") and f not in functions: - functions[f] = channel.attributes["ifdef"][0] - elif message.has_attr("ifdef") and f not in functions: - functions[f] = message.attributes["ifdef"][0] - else: - functions[f] = True + messages = channel.server_messages + for m in messages: + message = m.message_type + f = write_message_marshaller(writer, message, is_server, private_marshallers) + if channel.has_attr("ifdef") and f not in functions: + functions[f] = channel.attributes["ifdef"][0] + elif message.has_attr("ifdef") and f not in functions: + functions[f] = message.attributes["ifdef"][0] + else: + functions[f] = True if channel.has_attr("ifdef"): writer.endif(channel.attributes["ifdef"][0]) writer.header.endif(channel.attributes["ifdef"][0]) -- cgit