[Spice-commits] 6 commits - common/canvas_base.c common/gdi_canvas.c common/gl_canvas.c python_modules/demarshal.py python_modules/marshal.py python_modules/ptypes.py server/red_parse_qxl.c server/red_worker.c spice1.proto spice.proto
Alexander Larsson
alexl at kemper.freedesktop.org
Mon Jul 5 11:47:21 PDT 2010
common/canvas_base.c | 21 ++---
common/gdi_canvas.c | 13 +--
common/gl_canvas.c | 12 +--
python_modules/demarshal.py | 173 +++++++++++++++++++++++++-------------------
python_modules/marshal.py | 6 -
python_modules/ptypes.py | 15 ++-
server/red_parse_qxl.c | 9 +-
server/red_worker.c | 7 -
spice.proto | 2
spice1.proto | 4 -
10 files changed, 145 insertions(+), 117 deletions(-)
New commits:
commit f39d64f40bca094396d5002dcfcd38eaa281c9af
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 20:45:13 2010 +0200
Convert SpicePath.segments to a pointer array
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 53d13f2..a0429a6 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -3062,7 +3062,6 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
stroke_fill_spans,
stroke_fill_rects
};
- SpicePathSeg *seg;
StrokeLines lines;
unsigned int i;
int dashed;
@@ -3165,24 +3164,22 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
CANVAS_ERROR("invalid brush type");
}
- seg = (SpicePathSeg*)stroke->path->segments;
-
stroke_lines_init(&lines);
for (i = 0; i < stroke->path->num_segments; i++) {
- uint32_t flags = seg->flags;
- SpicePointFix* point = seg->points;
- SpicePointFix* end_point = point + seg->count;
- ASSERT(point < end_point);
- seg = (SpicePathSeg*)end_point;
+ SpicePathSeg *seg = stroke->path->segments[i];
+ SpicePointFix* point, *end_point;
+
+ point = seg->points;
+ end_point = point + seg->count;
- if (flags & SPICE_PATH_BEGIN) {
+ if (seg->flags & SPICE_PATH_BEGIN) {
stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
stroke_lines_append_fix(&lines, point);
point++;
}
- if (flags & SPICE_PATH_BEZIER) {
+ if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
stroke_lines_append_bezier(&lines,
@@ -3196,8 +3193,8 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
stroke_lines_append_fix(&lines, point);
}
}
- if (flags & SPICE_PATH_END) {
- if (flags & SPICE_PATH_CLOSE) {
+ if (seg->flags & SPICE_PATH_END) {
+ if (seg->flags & SPICE_PATH_CLOSE) {
stroke_lines_append(&lines,
lines.points[0].x, lines.points[0].y);
}
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
index e348994..9c52002 100644
--- a/common/gdi_canvas.c
+++ b/common/gdi_canvas.c
@@ -310,17 +310,14 @@ uint32_t raster_ops[] = {
static void set_path(GdiCanvas *canvas, SpicePath *s)
{
- SpicePathSeg* seg = (SpicePathSeg*)s->segments;
unsigned int i;
for (i = 0; i < s->num_segments; i++) {
- uint32_t flags = seg->flags;
+ SpicePathSeg* seg = s->segments[0];
SpicePointFix* point = seg->points;
SpicePointFix* end_point = point + seg->count;
- ASSERT(point < end_point);
- seg = (SpicePathSeg*)end_point;
- if (flags & SPICE_PATH_BEGIN) {
+ if (seg->flags & SPICE_PATH_BEGIN) {
BeginPath(canvas->dc);
if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y),
NULL)) {
@@ -330,7 +327,7 @@ static void set_path(GdiCanvas *canvas, SpicePath *s)
point++;
}
- if (flags & SPICE_PATH_BEZIER) {
+ if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
POINT points[3];
@@ -355,9 +352,9 @@ static void set_path(GdiCanvas *canvas, SpicePath *s)
}
}
- if (flags & SPICE_PATH_END) {
+ if (seg->flags & SPICE_PATH_END) {
- if (flags & SPICE_PATH_CLOSE) {
+ if (seg->flags & SPICE_PATH_CLOSE) {
if (!CloseFigure(canvas->dc)) {
CANVAS_ERROR("CloseFigure failed");
}
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index 3e02a25..f0e10dd 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -115,20 +115,18 @@ static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
{
GLCPath path = glc_path_create(canvas->glc);
int i;
- SpicePathSeg* seg = (SpicePathSeg*)s->segments;
for (i = 0; i < s->num_segments; i++) {
- uint32_t flags = seg->flags;
+ SpicePathSeg* seg = s->segments[i];
SpicePointFix* point = seg->points;
SpicePointFix* end_point = point + seg->count;
- seg = (SpicePathSeg*)end_point;
- if (flags & SPICE_PATH_BEGIN) {
+ if (seg->flags & SPICE_PATH_BEGIN) {
glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y));
point++;
}
- if (flags & SPICE_PATH_BEZIER) {
+ if (seg->flags & SPICE_PATH_BEZIER) {
ASSERT((point - end_point) % 3 == 0);
for (; point + 2 < end_point; point += 3) {
glc_path_curve_to(path,
@@ -141,8 +139,8 @@ static GLCPath get_path(GLCanvas *canvas, SpicePath *s)
glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y));
}
}
- if (flags & SPICE_PATH_END) {
- if (flags & SPICE_PATH_CLOSE) {
+ if (seg->flags & SPICE_PATH_END) {
+ if (seg->flags & SPICE_PATH_CLOSE) {
glc_path_close(path);
}
}
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 606b926..bd7660d 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -47,13 +47,16 @@ def write_parser_helpers(writer):
swap = "SPICE_BYTESWAP%d" % size
if size == 8:
writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
+ writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = val" % (type))
else:
writer.macro("read_%s" % type, "ptr", "((%s_t)%s(*((%s_t *)(ptr)))" % (type, swap, utype))
+ writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = %s((%s_t)val)" % (utype, swap, utype))
writer.writeln("#else")
for size in [8, 16, 32, 64]:
for sign in ["", "u"]:
type = "%sint%d" % (sign, size)
writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
+ writer.macro("write_%s" % type, "ptr, val", "(*((%s_t *)(ptr))) = val" % type)
writer.writeln("#endif")
for size in [8, 16, 32, 64]:
@@ -96,6 +99,15 @@ def write_read_primitive(writer, start, container, name, scope):
writer.assign(var, "read_%s(pos)" % (m.member_type.primitive_type()))
return var
+def write_write_primitive(writer, start, container, name, val):
+ m = container.lookup_member(name)
+ assert(m.is_primitive())
+ writer.assign("pos", start + " + " + container.get_nw_offset(m, "", "__nw_size"))
+
+ var = "%s__value" % (name)
+ writer.statement("write_%s(pos, %s)" % (m.member_type.primitive_type(), val))
+ return var
+
def write_read_primitive_item(writer, item, scope):
assert(item.type.is_primitive())
writer.assign("pos", item.get_position())
@@ -280,6 +292,9 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
element_type = array.element_type
if array.is_bytes_length():
nelements = "%s__nbytes" %(item.prefix)
+ real_nelements = "%s__nelements" %(item.prefix)
+ if not parent_scope.variable_defined(real_nelements):
+ parent_scope.variable_def("uint32_t", real_nelements)
else:
nelements = "%s__nelements" %(item.prefix)
if not parent_scope.variable_defined(nelements):
@@ -315,6 +330,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
is_byte_size = True
v = write_read_primitive(writer, start, container, array.size[1], scope)
writer.assign(nelements, v)
+ writer.assign(real_nelements, 0)
elif array.is_cstring_length():
writer.todo("cstring array size type not handled yet")
else:
@@ -389,6 +405,8 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("%s < %s" % (start2, start2_end) ) if is_byte_size else writer.for_loop(index, nelements) as scope:
+ if is_byte_size:
+ writer.increment(real_nelements, 1)
write_validate_item(writer, container, element_item, scope, parent_scope, start2,
want_element_nw_size, want_mem_size, want_extra_size)
@@ -405,6 +423,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
writer.increment(start2, start_increment)
if is_byte_size:
writer.error_check("%s != %s" % (start2, start2_end))
+ write_write_primitive(writer, start, container, array.size[1], real_nelements)
def write_validate_struct_item(writer, container, item, scope, parent_scope, start,
want_nw_size, want_mem_size, want_extra_size):
@@ -613,11 +632,9 @@ class SubDemarshallingDestination(DemarshallingDestination):
def get_ref(self, member):
return self.parent_dest.get_ref(self.member) + "." + member
-def read_array_len(writer, prefix, array, dest, scope, handles_bytes = False):
- if array.is_bytes_length():
- nelements = "%s__nbytes" % prefix
- else:
- nelements = "%s__nelements" % prefix
+# Note: during parsing, byte_size types have been converted to count during validation
+def read_array_len(writer, prefix, array, dest, scope):
+ nelements = "%s__nelements" % prefix
if dest.is_toplevel():
return nelements # Already there for toplevel, need not recalculate
element_type = array.element_type
@@ -645,9 +662,7 @@ def read_array_len(writer, prefix, array, dest, scope, handles_bytes = False):
else:
writer.assign(nelements, "((%s * %s + 7) / 8 ) * %s" % (bpp, width_v, rows_v))
elif array.is_bytes_length():
- if not handles_bytes:
- raise NotImplementedError("handling of bytes() not supported here yet")
- writer.assign(nelements, array.size[1])
+ writer.assign(nelements, dest.get_ref(array.size[2]))
else:
raise NotImplementedError("TODO array size type not handled yet")
return nelements
@@ -758,24 +773,16 @@ def write_array_parser(writer, nelements, array, dest, scope):
writer.increment("in", nelements)
writer.increment("end", nelements)
else:
- if is_byte_size:
- real_nelements = nelements[:-len("nbytes")] + "nelements"
- scope.variable_def("uint8_t *", "array_end")
- scope.variable_def("uint32_t", real_nelements)
- writer.assign("array_end", "end + %s" % nelements)
- writer.assign(real_nelements, 0)
if array.has_attr("ptr_array"):
scope.variable_def("void **", "ptr_array")
scope.variable_def("int", "ptr_array_index")
writer.assign("ptr_array_index", 0)
writer.assign("ptr_array", "(void **)end")
writer.increment("end", "sizeof(void *) * %s" % nelements)
- with writer.index(no_block = is_byte_size) as index:
- with writer.while_loop("end < 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:
if array.has_attr("ptr_array"):
writer.statement("ptr_array[ptr_array_index++] = end")
- if is_byte_size:
- writer.increment(real_nelements, 1)
if element_type.is_primitive():
writer.statement("*(%s *)end = consume_%s(&in)" % (element_type.c_type(), element_type.primitive_type()))
writer.increment("end", element_type.sizeof())
@@ -786,8 +793,6 @@ def write_array_parser(writer, nelements, array, dest, scope):
if array.has_attr("ptr_array"):
writer.comment("Align ptr_array element to 4 bytes").newline()
writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
- if is_byte_size:
- writer.assign(dest.get_ref(array.size[2]), real_nelements)
def write_parse_pointer(writer, t, at_end, dest, member_name, scope):
as_c_ptr = t.has_attr("c_ptr")
@@ -831,14 +836,14 @@ def write_member_parser(writer, container, member, dest, scope):
writer.increment("end", t.sizeof())
else:
if member.has_attr("bytes_count"):
- scope.variable_def("uint32_t", member.name);
- dest_var = member.name
+ print member.attributes["bytes_count"]
+ dest_var = dest.get_ref(member.attributes["bytes_count"][0])
else:
dest_var = dest.get_ref(member.name)
writer.assign(dest_var, "consume_%s(&in)" % (t.primitive_type()))
#TODO validate e.g. flags and enums
elif t.is_array():
- nelements = read_array_len(writer, member.name, t, dest, scope, handles_bytes = True)
+ nelements = read_array_len(writer, member.name, t, dest, scope)
if member.has_attr("as_ptr") and t.element_type.is_fixed_nw_size():
writer.comment("use array as pointer").newline()
writer.assign(dest.get_ref(member.name), "(%s *)in" % t.element_type.c_type())
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
index d38cad7..56f17dc 100644
--- a/server/red_parse_qxl.c
+++ b/server/red_parse_qxl.c
@@ -153,7 +153,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
bool free_data;
QXLPath *qxl;
SpicePath *red;
- size_t size, mem_size, mem_size2, dsize;
+ size_t size, mem_size, mem_size2, dsize, segment_size;
int n_segments;
int i;
uint32_t count;
@@ -173,7 +173,8 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
while (start < end) {
n_segments++;
count = start->count;
- mem_size += sizeof(SpicePathSeg) + count * sizeof(SpicePointFix);
+ segment_size = sizeof(SpicePathSeg) + count * sizeof(SpicePointFix);
+ mem_size += sizeof(SpicePathSeg *) + SPICE_ALIGN(segment_size, 4);
start = (QXLPathSeg*)(&start->points[count]);
}
@@ -182,11 +183,11 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
start = (QXLPathSeg*)data;
end = (QXLPathSeg*)(data + size);
- seg = (SpicePathSeg*)red->segments;
+ seg = (SpicePathSeg*)&red->segments[n_segments];
n_segments = 0;
mem_size2 = sizeof(*red);
while (start < end) {
- n_segments++;
+ red->segments[n_segments++] = seg;
count = start->count;
/* Protect against overflow in size calculations before
diff --git a/server/red_worker.c b/server/red_worker.c
index ff0a049..255a46e 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -2296,9 +2296,10 @@ static int is_equal_path(RedWorker *worker, SpicePath *path1, SpicePath *path2)
if (path1->num_segments != path2->num_segments)
return FALSE;
- seg1 = (SpicePathSeg*)&path1->segments[0];
- seg2 = (SpicePathSeg*)&path2->segments[0];
for (i = 0; i < path1->num_segments; i++) {
+ seg1 = path1->segments[i];
+ seg2 = path2->segments[i];
+
if (seg1->flags != seg2->flags ||
seg1->count != seg2->count) {
return FALSE;
@@ -2309,8 +2310,6 @@ static int is_equal_path(RedWorker *worker, SpicePath *path1, SpicePath *path2)
return FALSE;
}
}
- seg1 = (SpicePathSeg*)(&seg1->points[seg1->count]);
- seg2 = (SpicePathSeg*)(&seg2->points[seg2->count]);
}
return TRUE;
diff --git a/spice.proto b/spice.proto
index 8df1238..e437630 100644
--- a/spice.proto
+++ b/spice.proto
@@ -393,7 +393,7 @@ struct PathSegment {
struct Path {
uint32 num_segments;
- PathSegment segments[num_segments] @end;
+ PathSegment segments[num_segments] @ptr_array;
};
struct Clip {
diff --git a/spice1.proto b/spice1.proto
index 982f666..b49371a 100644
--- a/spice1.proto
+++ b/spice1.proto
@@ -374,8 +374,8 @@ struct PathSegment {
} @ctype(SpicePathSeg);
struct Path {
- uint32 segments_size @bytes_count;
- PathSegment segments[bytes(segments_size, num_segments)] @end;
+ uint32 segments_size @bytes_count(num_segments);
+ PathSegment segments[bytes(segments_size, num_segments)] @ptr_array;
};
struct Clip {
commit 6dcf43912e752b8c61199017718ccfb067b45576
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 13:13:39 2010 +0200
Handle extra size for switch and array the right way
Even for is_extra_size() we should calculate the mem_size for
arrays, its just that the parent type (in this case switch) should
request mem_size if the type is_extra_size.
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index cf6fefd..606b926 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -150,13 +150,19 @@ def write_validate_switch_member(writer, container, switch_member, scope, parent
with writer.if_block(check, not first, False) as if_scope:
item.type = c.member.member_type
item.subprefix = item.prefix + "_" + m.name
- sub_want_extra_size = want_extra_size
- if sub_want_extra_size and not m.contains_extra_size() and not m.is_extra_size():
- writer.assign(item.extra_size(), 0)
- sub_want_extra_size = False
+
+ all_as_extra_size = m.is_extra_size() and want_extra_size
+ if not want_mem_size and all_as_extra_size and not scope.variable_defined(item.mem_size()):
+ scope.variable_def("uint32_t", item.mem_size())
+
+ sub_want_mem_size = want_mem_size or all_as_extra_size
+ sub_want_extra_size = want_extra_size and not all_as_extra_size
write_validate_item(writer, container, item, if_scope, scope, start,
- want_nw_size, want_mem_size, sub_want_extra_size)
+ want_nw_size, sub_want_mem_size, sub_want_extra_size)
+
+ if all_as_extra_size:
+ writer.assign(item.extra_size(), item.mem_size())
first = False
@@ -341,7 +347,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
writer.assign(mem_size, "%s * %s" % (element_type.sizeof(), nelements))
want_mem_size = False
- if not element_type.contains_extra_size() and not array.is_extra_size() and want_extra_size:
+ if not element_type.contains_extra_size() and want_extra_size:
writer.assign(extra_size, 0)
want_extra_size = False
@@ -361,21 +367,14 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
element_extra_size = element_item.extra_size()
scope.variable_def("uint32_t", element_nw_size)
scope.variable_def("uint32_t", element_mem_size)
- want_is_extra_size = False
- want_element_mem_size = want_mem_size
if want_extra_size:
- if array.is_extra_size():
- want_is_extra_size = True
- want_extra_size = False
- want_element_mem_size = True
- else:
- scope.variable_def("uint32_t", element_extra_size)
+ scope.variable_def("uint32_t", element_extra_size)
if want_nw_size:
writer.assign(nw_size, 0)
if want_mem_size:
writer.assign(mem_size, 0)
- if want_extra_size or want_is_extra_size:
+ if want_extra_size:
writer.assign(extra_size, 0)
want_element_nw_size = want_nw_size
@@ -391,19 +390,16 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("%s < %s" % (start2, start2_end) ) if is_byte_size else writer.for_loop(index, nelements) as scope:
write_validate_item(writer, container, element_item, scope, parent_scope, start2,
- want_element_nw_size, want_element_mem_size, want_extra_size)
+ want_element_nw_size, want_mem_size, want_extra_size)
if want_nw_size:
writer.increment(nw_size, element_nw_size)
if want_mem_size:
- if not array.is_extra_size():
- writer.increment(mem_size, element_mem_size)
- if want_is_extra_size:
if array.has_attr("ptr_array"):
- writer.increment(extra_size, "sizeof(void *) + SPICE_ALIGN(%s, 4)" % element_mem_size)
+ writer.increment(mem_size, "sizeof(void *) + SPICE_ALIGN(%s, 4)" % element_mem_size)
else:
- writer.increment(extra_size, "%s + %s" % (element_mem_size, element_extra_size))
- elif want_extra_size:
+ writer.increment(mem_size, element_mem_size)
+ if want_extra_size:
writer.increment(extra_size, element_extra_size)
writer.increment(start2, start_increment)
@@ -426,7 +422,8 @@ def write_validate_primitive_item(writer, container, item, scope, parent_scope,
if want_mem_size:
mem_size = item.mem_size()
writer.assign(mem_size, item.type.sizeof())
- assert not want_extra_size
+ if want_extra_size:
+ writer.assign(item.extra_size(), 0)
def write_validate_item(writer, container, item, scope, parent_scope, start,
want_nw_size, want_mem_size, want_extra_size):
commit b8524fc33861cbb7000631ccc647af109b0399ef
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 13:13:09 2010 +0200
marshaller: Add some docs describing the types of sizes
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 5709567..cf6fefd 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -1,6 +1,35 @@
import ptypes
import codegen
+# The handling of sizes is somewhat complex, as there are several types of size:
+# * nw_size
+# This is the network size, i.e. the number of bytes on the network
+#
+# * mem_size
+# The total amount of memory used for the representation of something inside
+# spice. This is generally sizeof(C struct), but can be larger if for instance
+# the type has a variable size array at the end or has a pointer in it that
+# points to another data chunk (which will be allocated after the main
+# data chunk). This is essentially how much memory you need to allocate to
+# contain the data type.
+#
+# * extra_size
+# This is the size of anything that is not part of the containing structure.
+# For instance, a primitive (say uint32_t) member has no extra size, because
+# when allocating its part of the sizeof(MessageStructType) struct. However
+# a variable array can be places at the end of a structure (@end) and its
+# size is then extra_size. Note that this extra_size is included in the
+# mem_size of the enclosing struct, and even if you request the mem_size
+# of the array itself. However, extra_size is typically not requested
+# when the full mem_size is also requested.
+#
+# extra sizes come in two flavours. contains_extra_size means that the item
+# has a normal presence in the parent container, but has some additional
+# extra_size it references. For instance via a pointer somewhere in it.
+# There is also is_extra_size(). This indicates that the whole elements
+# "normal" mem size should be considered extra size for the container, so
+# when computing the parent mem_size you should add the mem_size of this
+# part as extra_size
def write_parser_helpers(writer):
if writer.is_generated("helper", "demarshaller"):
commit d161994f46af7c77e428f11fea84eb34fc097449
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 12:13:45 2010 +0200
marshaller: Make @nonnull a propagated attribute
This cleans up some stuff
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 5a8f8ff..5709567 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -82,7 +82,6 @@ class ItemInfo:
self.prefix = prefix
self.subprefix = prefix
self.position = position
- self.non_null = False
self.member = None
def nw_size(self):
@@ -103,7 +102,6 @@ class MemberItemInfo(ItemInfo):
self.type = member.member_type
self.prefix = member.name
self.subprefix = member.name
- self.non_null = member.has_attr("nonnull")
self.position = "(%s + %s)" % (start, container.get_nw_offset(member, "", "__nw_size"))
self.member = member
@@ -123,7 +121,6 @@ def write_validate_switch_member(writer, container, switch_member, scope, parent
with writer.if_block(check, not first, False) as if_scope:
item.type = c.member.member_type
item.subprefix = item.prefix + "_" + m.name
- item.non_null = c.member.has_attr("nonnull")
sub_want_extra_size = want_extra_size
if sub_want_extra_size and not m.contains_extra_size() and not m.is_extra_size():
writer.assign(item.extra_size(), 0)
@@ -192,7 +189,7 @@ def write_validate_pointer_item(writer, container, item, scope, parent_scope, st
target_type = item.type.target_type
v = write_read_primitive_item(writer, item, scope)
- if item.non_null:
+ if item.type.has_attr("nonnull"):
writer.error_check("%s == 0" % v)
# pointer target is struct, or array of primitives
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:
diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index 2c0dd88..31ae79d 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -60,7 +60,7 @@ class FixedSize:
# only to attributes that affect pointer or array attributes, as these
# are member local types, unlike e.g. a Struct that may be used by
# other members
-propagated_attributes=["ptr_array", "c_ptr"]
+propagated_attributes=["ptr_array", "c_ptr", "nonnull"]
class Type:
def __init__(self):
commit d7164a0669b0f8c6531b1728f4fbda32647942ba
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 12:09:08 2010 +0200
marshaller: Make @c_ptr a propagated attribute
This simplifies some code
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 5391e53..5a8f8ff 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -657,7 +657,7 @@ def write_switch_parser(writer, container, switch, dest, scope):
if t.is_struct():
write_container_parser(writer, t, dest2)
elif t.is_pointer():
- write_parse_pointer(writer, t, False, m.has_attr("c_ptr"), dest2, m.name, block)
+ write_parse_pointer(writer, t, False, dest2, m.name, block)
elif t.is_primitive():
if m.has_attr("zero"):
writer.statement("consume_%s(&in)" % (t.primitive_type()))
@@ -766,21 +766,22 @@ def write_array_parser(writer, nelements, array, dest, scope):
if is_byte_size:
writer.assign(dest.get_ref(array.size[2]), real_nelements)
-def write_parse_pointer(writer, t, at_end, as_c_ptr, dest, member_name, scope):
- target_type = t.target_type
- writer.assign("ptr_info[n_ptr].offset", "consume_%s(&in)" % t.primitive_type())
- writer.assign("ptr_info[n_ptr].parse", write_parse_ptr_function(writer, target_type))
- if at_end:
- writer.assign("ptr_info[n_ptr].dest", "end")
- writer.increment("end", "sizeof(void *)" if as_c_ptr else "sizeof(SPICE_ADDRESS)");
- else:
- writer.assign("ptr_info[n_ptr].dest", "&%s" % dest.get_ref(member_name))
- writer.assign("ptr_info[n_ptr].is_ptr", "1" if as_c_ptr else "0")
- if target_type.is_array():
- nelements = read_array_len(writer, member_name, target_type, dest, scope)
- writer.assign("ptr_info[n_ptr].nelements", nelements)
+def write_parse_pointer(writer, t, at_end, dest, member_name, scope):
+ as_c_ptr = t.has_attr("c_ptr")
+ target_type = t.target_type
+ writer.assign("ptr_info[n_ptr].offset", "consume_%s(&in)" % t.primitive_type())
+ writer.assign("ptr_info[n_ptr].parse", write_parse_ptr_function(writer, target_type))
+ if at_end:
+ writer.assign("ptr_info[n_ptr].dest", "end")
+ writer.increment("end", "sizeof(void *)" if as_c_ptr else "sizeof(SPICE_ADDRESS)");
+ else:
+ writer.assign("ptr_info[n_ptr].dest", "&%s" % dest.get_ref(member_name))
+ writer.assign("ptr_info[n_ptr].is_ptr", "1" if as_c_ptr else "0")
+ if target_type.is_array():
+ nelements = read_array_len(writer, member_name, target_type, dest, scope)
+ writer.assign("ptr_info[n_ptr].nelements", nelements)
- writer.statement("n_ptr++")
+ writer.statement("n_ptr++")
def write_member_parser(writer, container, member, dest, scope):
if member.has_attr("virtual"):
@@ -798,7 +799,7 @@ def write_member_parser(writer, container, member, dest, scope):
writer.comment("Reuse data from network message").newline()
writer.assign(dest.get_ref(member.name), "(size_t)(message_start + consume_%s(&in))" % t.primitive_type())
else:
- write_parse_pointer(writer, t, member.has_end_attr(), member.has_attr("c_ptr"), dest, member.name, scope)
+ write_parse_pointer(writer, t, member.has_end_attr(), dest, member.name, scope)
elif t.is_primitive():
if member.has_attr("zero"):
writer.statement("consume_%s(&in)" % t.primitive_type())
diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index cc74b72..2c0dd88 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -60,7 +60,7 @@ class FixedSize:
# only to attributes that affect pointer or array attributes, as these
# are member local types, unlike e.g. a Struct that may be used by
# other members
-propagated_attributes=["ptr_array"]
+propagated_attributes=["ptr_array", "c_ptr"]
class Type:
def __init__(self):
commit 4a60f1822a356e4e1e2d7ecd2d18f4e3fce48f85
Author: Alexander Larsson <alexl at redhat.com>
Date: Mon Jul 5 12:03:34 2010 +0200
marshaller: Add generic way to handle propagating attributes
Also switches @ptr_array to use this
diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
index 4d3e79b..5391e53 100644
--- a/python_modules/demarshal.py
+++ b/python_modules/demarshal.py
@@ -309,7 +309,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
if element_type.is_fixed_sizeof() and want_mem_size and not is_byte_size:
# TODO: Overflow check the multiplication
- if array.ptr_array:
+ if array.has_attr("ptr_array"):
writer.assign(mem_size, "sizeof(void *) + SPICE_ALIGN(%s * %s, 4)" % (element_type.sizeof(), nelements))
else:
writer.assign(mem_size, "%s * %s" % (element_type.sizeof(), nelements))
@@ -373,7 +373,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
if not array.is_extra_size():
writer.increment(mem_size, element_mem_size)
if want_is_extra_size:
- if array.ptr_array:
+ if array.has_attr("ptr_array"):
writer.increment(extra_size, "sizeof(void *) + SPICE_ALIGN(%s, 4)" % element_mem_size)
else:
writer.increment(extra_size, "%s + %s" % (element_mem_size, element_extra_size))
@@ -741,7 +741,7 @@ def write_array_parser(writer, nelements, array, dest, scope):
scope.variable_def("uint32_t", real_nelements)
writer.assign("array_end", "end + %s" % nelements)
writer.assign(real_nelements, 0)
- if array.ptr_array:
+ if array.has_attr("ptr_array"):
scope.variable_def("void **", "ptr_array")
scope.variable_def("int", "ptr_array_index")
writer.assign("ptr_array_index", 0)
@@ -749,7 +749,7 @@ def write_array_parser(writer, nelements, array, dest, scope):
writer.increment("end", "sizeof(void *) * %s" % nelements)
with writer.index(no_block = is_byte_size) as index:
with writer.while_loop("end < array_end") if is_byte_size else writer.for_loop(index, nelements) as array_scope:
- if array.ptr_array:
+ if array.has_attr("ptr_array"):
writer.statement("ptr_array[ptr_array_index++] = end")
if is_byte_size:
writer.increment(real_nelements, 1)
@@ -760,7 +760,7 @@ def write_array_parser(writer, nelements, array, dest, scope):
dest2 = dest.child_at_end(writer, element_type)
dest2.reuse_scope = array_scope
write_container_parser(writer, element_type, dest2)
- if array.ptr_array:
+ if array.has_attr("ptr_array"):
writer.comment("Align ptr_array element to 4 bytes").newline()
writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
if is_byte_size:
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:
diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index 055034e..cc74b72 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -55,6 +55,13 @@ class FixedSize:
s = s + " + ((minor >= %d)?%d:0)" % (i, self.vals[i])
return s
+# Some attribute are propagated from member to the type as they really
+# are part of the type definition, rather than the member. This applies
+# only to attributes that affect pointer or array attributes, as these
+# are member local types, unlike e.g. a Struct that may be used by
+# other members
+propagated_attributes=["ptr_array"]
+
class Type:
def __init__(self):
self.attributes = {}
@@ -353,7 +360,6 @@ class ArrayType(Type):
self.element_type = element_type
self.size = size
- self.ptr_array = False
def __str__(self):
if self.size == None:
@@ -416,7 +422,7 @@ class ArrayType(Type):
raise Exception, "Pointer names in arrays not supported"
def is_extra_size(self):
- return self.ptr_array
+ return self.has_attr("ptr_array")
def contains_extra_size(self):
return self.element_type.contains_extra_size()
@@ -516,8 +522,9 @@ class Member(Containee):
self.member_type.register()
if self.has_attr("ptr32") and self.member_type.is_pointer():
self.member_type.set_ptr_size(4)
- if self.has_attr("ptr_array") and self.member_type.is_array():
- self.member_type.ptr_array = True
+ for i in propagated_attributes:
+ if self.has_attr(i):
+ self.member_type.attributes[i] = self.attributes[i]
return self
def is_primitive(self):
More information about the Spice-commits
mailing list