فهرست منبع

reverse field order and create both list and PMap at the same time

Simon Krajewski 1 سال پیش
والد
کامیت
979660de49
2فایلهای تغییر یافته به همراه43 افزوده شده و 6 حذف شده
  1. 19 4
      src/compiler/hxb/hxbReader.ml
  2. 24 2
      src/compiler/hxb/hxbWriter.ml

+ 19 - 4
src/compiler/hxb/hxbReader.ml

@@ -1685,10 +1685,25 @@ class hxb_reader
 				in
 				in
 
 
 				c.cl_constructor <- self#read_option read_field;
 				c.cl_constructor <- self#read_option read_field;
-				c.cl_ordered_fields <- self#read_list read_field;
-				c.cl_ordered_statics <- self#read_list read_field;
-				List.iter (fun cf -> c.cl_fields <- PMap.add cf.cf_name cf c.cl_fields) c.cl_ordered_fields;
-				List.iter (fun cf -> c.cl_statics <- PMap.add cf.cf_name cf c.cl_statics) c.cl_ordered_statics;
+				let read_fields i =
+					let rec loop acc_l acc_pm i =
+						if i = 0 then
+							acc_l,acc_pm
+						else begin
+							let cf = self#read_class_field_forward in
+							loop (cf :: acc_l) (PMap.add cf.cf_name cf acc_pm) (i - 1)
+						end
+					in
+					loop [] PMap.empty i
+				in
+				let num_fields = read_uleb128 ch in
+				let num_statics = read_uleb128 ch in
+				let l,pm = read_fields num_fields in
+				c.cl_ordered_fields <- l;
+				c.cl_fields <- pm;
+				let l,pm = read_fields num_statics in
+				c.cl_ordered_statics <- l;
+				c.cl_statics <- pm;
 
 
 				TClassDecl c
 				TClassDecl c
 			| 1 ->
 			| 1 ->

+ 24 - 2
src/compiler/hxb/hxbWriter.ml

@@ -1974,8 +1974,30 @@ module HxbWriter = struct
 		| TClassDecl c ->
 		| TClassDecl c ->
 			Chunk.write_uleb128 writer.chunk c.cl_flags;
 			Chunk.write_uleb128 writer.chunk c.cl_flags;
 			Chunk.write_option writer.chunk c.cl_constructor (write_class_field_forward writer);
 			Chunk.write_option writer.chunk c.cl_constructor (write_class_field_forward writer);
-			Chunk.write_list writer.chunk c.cl_ordered_fields (write_class_field_forward writer);
-			Chunk.write_list writer.chunk c.cl_ordered_statics (write_class_field_forward writer);
+
+			(* Write in reverse order so reader can read tail-recursively without List.rev *)
+			let write_fields cfl =
+				let i = ref 0 in
+				let rec loop cfl = match cfl with
+					| [] ->
+						()
+					| cf :: cfl ->
+						loop cfl;
+						write_class_field_forward writer cf;
+						incr i;
+				in
+				let restore = start_temporary_chunk writer 256 in
+				loop cfl;
+				let bytes = restore (fun new_chunk -> Chunk.get_bytes new_chunk) in
+				!i,bytes
+			in
+			let num_fields,field_bytes = write_fields c.cl_ordered_fields in
+			let num_statics,static_bytes = write_fields c.cl_ordered_statics in
+			Chunk.write_uleb128 writer.chunk num_fields;
+			Chunk.write_uleb128 writer.chunk num_statics;
+			Chunk.write_bytes writer.chunk field_bytes;
+			Chunk.write_bytes writer.chunk static_bytes;
+
 		| TEnumDecl e ->
 		| TEnumDecl e ->
 			Chunk.write_list writer.chunk (PMap.foldi (fun s f acc -> (s,f) :: acc) e.e_constrs []) (fun (s,ef) ->
 			Chunk.write_list writer.chunk (PMap.foldi (fun s f acc -> (s,f) :: acc) e.e_constrs []) (fun (s,ef) ->
 				Chunk.write_string writer.chunk s;
 				Chunk.write_string writer.chunk s;