OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import module as mojom | 5 import module as mojom |
6 | 6 |
7 # This module provides a mechanism for determining the packed order and offsets | 7 # This module provides a mechanism for determining the packed order and offsets |
8 # of a mojom.Struct. | 8 # of a mojom.Struct. |
9 # | 9 # |
10 # ps = pack.PackedStruct(struct) | 10 # ps = pack.PackedStruct(struct) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 if not kind in cls.kind_to_size: | 44 if not kind in cls.kind_to_size: |
45 raise Exception("Invalid kind: %s" % kind.spec) | 45 raise Exception("Invalid kind: %s" % kind.spec) |
46 return cls.kind_to_size[kind] | 46 return cls.kind_to_size[kind] |
47 | 47 |
48 def __init__(self, field, ordinal): | 48 def __init__(self, field, ordinal): |
49 self.field = field | 49 self.field = field |
50 self.ordinal = ordinal | 50 self.ordinal = ordinal |
51 self.size = self.GetSizeForKind(field.kind) | 51 self.size = self.GetSizeForKind(field.kind) |
52 self.offset = None | 52 self.offset = None |
53 self.bit = None | 53 self.bit = None |
| 54 self.in_hole = False |
54 | 55 |
55 | 56 |
56 # Returns the pad necessary to reserve space for alignment of |size|. | 57 # Returns the pad necessary to reserve space for alignment of |size|. |
57 def GetPad(offset, size): | 58 def GetPad(offset, size): |
58 return (size - (offset % size)) % size | 59 return (size - (offset % size)) % size |
59 | 60 |
60 | 61 |
61 # Returns a 2-tuple of the field offset and bit (for BOOLs) | 62 # Returns a 2-tuple of the field offset and bit (for BOOLs) |
62 def GetFieldOffset(field, last_field): | 63 def GetFieldOffset(field, last_field): |
63 if field.field.kind == mojom.BOOL and \ | 64 if field.field.kind == mojom.BOOL and \ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 # Then find first slot that each field will fit. | 100 # Then find first slot that each field will fit. |
100 for src_field in src_fields[1:]: | 101 for src_field in src_fields[1:]: |
101 last_field = dst_fields[0] | 102 last_field = dst_fields[0] |
102 for i in xrange(1, len(dst_fields)): | 103 for i in xrange(1, len(dst_fields)): |
103 next_field = dst_fields[i] | 104 next_field = dst_fields[i] |
104 offset, bit = GetFieldOffset(src_field, last_field) | 105 offset, bit = GetFieldOffset(src_field, last_field) |
105 if offset + src_field.size <= next_field.offset: | 106 if offset + src_field.size <= next_field.offset: |
106 # Found hole. | 107 # Found hole. |
107 src_field.offset = offset | 108 src_field.offset = offset |
108 src_field.bit = bit | 109 src_field.bit = bit |
| 110 src_field.in_hole = True |
109 dst_fields.insert(i, src_field) | 111 dst_fields.insert(i, src_field) |
110 break | 112 break |
111 last_field = next_field | 113 last_field = next_field |
112 if src_field.offset is None: | 114 if src_field.offset is None: |
113 # Add to end | 115 # Add to end |
114 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field) | 116 src_field.offset, src_field.bit = GetFieldOffset(src_field, last_field) |
115 dst_fields.append(src_field) | 117 dst_fields.append(src_field) |
116 | 118 |
117 def GetTotalSize(self): | 119 def GetTotalSize(self): |
118 if not self.packed_fields: | 120 if not self.packed_fields: |
(...skipping 21 matching lines...) Expand all Loading... |
140 limit_of_previous_field = packed_field.offset + packed_field.size | 142 limit_of_previous_field = packed_field.offset + packed_field.size |
141 | 143 |
142 for i in xrange(limit_of_previous_field, len(bytes)): | 144 for i in xrange(limit_of_previous_field, len(bytes)): |
143 bytes[i].is_padding = True | 145 bytes[i].is_padding = True |
144 | 146 |
145 for byte in bytes: | 147 for byte in bytes: |
146 # A given byte cannot both be padding and have a fields packed into it. | 148 # A given byte cannot both be padding and have a fields packed into it. |
147 assert not (byte.is_padding and byte.packed_fields) | 149 assert not (byte.is_padding and byte.packed_fields) |
148 | 150 |
149 return bytes | 151 return bytes |
OLD | NEW |