@@ -15,25 +15,53 @@ def CStruct.entity_class
15
15
16
16
def self . offsetof ( name , members , types ) # :nodoc:
17
17
offset = 0
18
- index = 0
19
- member_index = members . index ( name )
20
-
21
- types . each { |type , count = 1 |
22
- orig_offset = offset
23
- if type . respond_to? ( :entity_class )
24
- align = type . alignment
25
- type_size = type . size
26
- else
27
- align = PackInfo ::ALIGN_MAP [ type ]
28
- type_size = PackInfo ::SIZE_MAP [ type ]
18
+ worklist = name . split ( '.' )
19
+ this_type = self
20
+ while search_name = worklist . shift
21
+ index = 0
22
+ member_index = members . index ( search_name )
23
+
24
+ unless member_index
25
+ # Possibly a sub-structure
26
+ member_index = members . index { |member_name , _ |
27
+ member_name == search_name
28
+ }
29
+ return unless member_index
29
30
end
30
- offset = PackInfo . align ( orig_offset , align )
31
31
32
- return offset if index == member_index
32
+ types . each { |type , count = 1 |
33
+ orig_offset = offset
34
+ if type . respond_to? ( :entity_class )
35
+ align = type . alignment
36
+ type_size = type . size
37
+ else
38
+ align = PackInfo ::ALIGN_MAP [ type ]
39
+ type_size = PackInfo ::SIZE_MAP [ type ]
40
+ end
41
+
42
+ # Unions shouldn't advance the offset
43
+ if this_type . entity_class == CUnionEntity
44
+ type_size = 0
45
+ end
33
46
34
- offset += ( type_size * count )
35
- index += 1
36
- }
47
+ offset = PackInfo . align ( orig_offset , align )
48
+
49
+ if worklist . empty?
50
+ return offset if index == member_index
51
+ else
52
+ if index == member_index
53
+ subtype = types [ member_index ]
54
+ members = subtype . members
55
+ types = subtype . types
56
+ this_type = subtype
57
+ break
58
+ end
59
+ end
60
+
61
+ offset += ( type_size * count )
62
+ index += 1
63
+ }
64
+ end
37
65
nil
38
66
end
39
67
0 commit comments