@@ -59,10 +59,13 @@ public final class StructLayout extends Type {
5959 static final String CLASS_NAME = "StructLayout" ;
6060
6161 /** The name:offset map for this struct */
62- private final Map <IRubyObject , Member > fields ;
62+ private final Map <IRubyObject , Member > fieldMap ;
6363
6464 /** The ordered list of field names (as symbols) */
6565 private final List <RubySymbol > fieldNames ;
66+
67+ /** The ordered list of field names (as symbols) */
68+ private final List <Member > fields ;
6669
6770 private final int cacheableFieldCount ;
6871 private final int [] cacheIndexMap ;
@@ -95,17 +98,21 @@ public static RubyClass createStructLayoutClass(Ruby runtime, RubyModule module)
9598 * @param size the total size of the struct.
9699 * @param minAlign The minimum alignment required when allocating memory.
97100 */
98- StructLayout (Ruby runtime , Map <IRubyObject , Member > fields , int size , int minAlign ) {
101+ StructLayout (Ruby runtime , Collection < RubySymbol > fieldNames , Map <IRubyObject , Member > fields , int size , int minAlign ) {
99102 super (runtime , runtime .fastGetModule ("FFI" ).fastGetClass (CLASS_NAME ), NativeType .STRUCT , size , minAlign );
100103 //
101104 // fields should really be an immutable map as it is never modified after construction
102105 //
103- this .fields = immutableMap (fields );
104- this .cacheIndexMap = new int [fields .size ()];
105- this .referenceIndexMap = new int [fields .size ()];
106+ this .fieldMap = immutableMap (fields );
107+ this .cacheIndexMap = new int [fieldNames .size ()];
108+ this .referenceIndexMap = new int [fieldNames .size ()];
106109
107110 int cfCount = 0 , refCount = 0 ;
108- for (Member m : fields .values ()) {
111+ List <Member > fieldList = new ArrayList <Member >(fieldNames .size ());
112+
113+ for (RubySymbol fieldName : fieldNames ) {
114+ Member m = fields .get (fieldName );
115+ fieldList .add (m );
109116 if (m .isCacheable ()) {
110117 cacheIndexMap [m .index ] = cfCount ++;
111118 } else {
@@ -121,13 +128,8 @@ public static RubyClass createStructLayoutClass(Ruby runtime, RubyModule module)
121128 this .referenceFieldCount = refCount ;
122129
123130 // Create the ordered list of field names from the map
124- List <RubySymbol > names = new ArrayList <RubySymbol >(fields .size ());
125- for (Map .Entry <IRubyObject , Member > e : fields .entrySet ()) {
126- if (e .getKey () instanceof RubySymbol ) {
127- names .add ((RubySymbol ) e .getKey ());
128- }
129- }
130- this .fieldNames = Collections .unmodifiableList (names );
131+ this .fieldNames = Collections .unmodifiableList (new ArrayList <RubySymbol >(fieldNames ));
132+ this .fields = Collections .unmodifiableList (fieldList );
131133 }
132134
133135 /**
@@ -192,15 +194,15 @@ public IRubyObject members(ThreadContext context) {
192194 public IRubyObject offsets (ThreadContext context ) {
193195 Ruby runtime = context .getRuntime ();
194196 RubyArray offsets = RubyArray .newArray (runtime );
195- for (Map .Entry <IRubyObject , Member > e : fields .entrySet ()) {
196- if (e .getKey () instanceof RubySymbol ) {
197- RubyArray offset = RubyArray .newArray (runtime );
198- // Assemble a [ :name, offset ] array
199- offset .append (e .getKey ());
200- offset .append (runtime .newFixnum (e .getValue ().offset ));
201- offsets .append (offset );
202- }
197+
198+ for (RubySymbol name : fieldNames ) {
199+ RubyArray offset = RubyArray .newArray (runtime );
200+ // Assemble a [ :name, offset ] array
201+ offset .append (name );
202+ offset .append (runtime .newFixnum (fieldMap .get (name ).offset ));
203+ offsets .append (offset );
203204 }
205+
204206 return offsets ;
205207 }
206208
@@ -242,7 +244,7 @@ public IRubyObject offset_of(ThreadContext context, IRubyObject fieldName) {
242244 * @return A <tt>Member</tt> descriptor.
243245 */
244246 final Member getMember (Ruby runtime , IRubyObject name ) {
245- Member f = fields .get (name );
247+ Member f = fieldMap .get (name );
246248 if (f != null ) {
247249 return f ;
248250 }
@@ -278,7 +280,7 @@ public final int getFieldCount() {
278280 }
279281
280282 public final java .util .Collection <Member > getFields () {
281- return Collections . unmodifiableCollection ( fields . values ()) ;
283+ return fields ;
282284 }
283285
284286 /**
0 commit comments