Просмотр исходного кода

[hxb] anons and type parameters

Rudy Ges 1 год назад
Родитель
Сommit
9481308624
3 измененных файлов с 218 добавлено и 158 удалено
  1. 6 12
      src/compiler/hxb/hxbData.ml
  2. 153 77
      src/compiler/hxb/hxbReader.ml
  3. 59 69
      src/compiler/hxb/hxbWriter.ml

+ 6 - 12
src/compiler/hxb/hxbData.ml

@@ -4,7 +4,6 @@ type chunk_kind =
 	| STRI (* string pool *)
 	| DOCS (* doc pool *)
 	| HHDR (* module header *)
-	| ANNR (* anon reference array *)
 	| TYPF (* forward types *)
 	| CLSR (* class reference array *)
 	| ABSR (* abstract reference array *)
@@ -16,7 +15,6 @@ type chunk_kind =
 	| TPDD (* typedef definition *)
 	| ENMD (* enum definition *)
 	| EFLD (* enum fields *)
-	| ANND (* anon definition *)
 	| HEND (* the end *)
 
 let string_of_chunk_kind = function
@@ -24,18 +22,16 @@ let string_of_chunk_kind = function
 	| DOCS -> "DOCS"
 	| HHDR -> "HHDR"
 	| TYPF -> "TYPF"
-	| ANNR -> "ANNR"
 	| CLSR -> "CLSR"
 	| ABSR -> "ABSR"
-	| ENMR -> "ENMR"
 	| TPDR -> "TPDR"
-	| ANND -> "ANND"
+	| ENMR -> "ENMR"
 	| CLSD -> "CLSD"
-	| CFLD -> "CFLD"
 	| ABSD -> "ABSD"
+	| CFLD -> "CFLD"
+	| TPDD -> "TPDD"
 	| ENMD -> "ENMD"
 	| EFLD -> "EFLD"
-	| TPDD -> "TPDD"
 	| HEND -> "HEND"
 
 let chunk_kind_of_string = function
@@ -43,18 +39,16 @@ let chunk_kind_of_string = function
 	| "DOCS" -> DOCS
 	| "HHDR" -> HHDR
 	| "TYPF" -> TYPF
-	| "ANNR" -> ANNR
 	| "CLSR" -> CLSR
 	| "ABSR" -> ABSR
-	| "ENMR" -> ENMR
 	| "TPDR" -> TPDR
-	| "ANND" -> ANND
+	| "ENMR" -> ENMR
 	| "CLSD" -> CLSD
-	| "CFLD" -> CFLD
 	| "ABSD" -> ABSD
+	| "CFLD" -> CFLD
+	| "TPDD" -> TPDD
 	| "ENMD" -> ENMD
 	| "EFLD" -> EFLD
-	| "TPDD" -> TPDD
 	| "HEND" -> HEND
 	| name -> raise (HxbFailure ("Invalid chunk name: " ^ name))
 

+ 153 - 77
src/compiler/hxb/hxbReader.ml

@@ -43,7 +43,7 @@ class hxb_reader
 
 	val vars = Hashtbl.create 0
 	val mutable type_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None)
-	val mutable field_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None)
+	val field_type_parameters = Hashtbl.create 0
 	val mutable local_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None)
 
 	method resolve_type sign pack mname tname =
@@ -195,12 +195,6 @@ class hxb_reader
 			prerr_endline (Printf.sprintf "[%s] %s reading typedef ref %i" (s_type_path m.m_path) todo_error i);
 			raise e
 
-	method read_anon_ref =
-		let i = self#read_uleb128 in
-		try anons.(i) with e ->
-			prerr_endline (Printf.sprintf "[%s] %s reading anon ref %i" (s_type_path m.m_path) todo_error i);
-			raise e
-
 	method read_field_ref fields =
 		let name = self#read_string in
 		try PMap.find name fields with e ->
@@ -216,6 +210,25 @@ class hxb_reader
 			prerr_endline (Printf.sprintf "    Available fields: %s" (PMap.fold (fun ef acc -> acc ^ " " ^ ef.ef_name) en.e_constrs ""));
 			null_enum_field
 
+	method read_anon_ref =
+		match IO.read_byte ch with
+		| 0 ->
+			let index = self#read_uleb128 in
+			(try anons.(index) with e ->
+				trace (Printf.sprintf "[%s] %s reading anon (0) ref %i" (s_type_path m.m_path) todo_error index);
+				raise e
+			)
+		| 1 ->
+			let index = self#read_uleb128 in
+			let an = (try anons.(index) with e ->
+				trace (Printf.sprintf "[%s] %s reading anon (1) ref %i" (s_type_path m.m_path) todo_error index);
+				trace (Printexc.to_string e);
+				raise e
+			) in
+			self#read_anon an
+		| _ ->
+			assert false
+
 	method read_anon_field_ref =
 		match IO.read_byte ch with
 		| 0 ->
@@ -622,8 +635,22 @@ class hxb_reader
 
 	method read_type_parameter_ref = function
 		| 5 ->
-			let i = self#read_uleb128 in
-			(field_type_parameters.(i)).ttp_type
+			let p = self#read_path in
+			(try
+				let ttp = Hashtbl.find field_type_parameters p in
+				(match follow ttp.ttp_type with
+					| TInst(c, _) ->
+						if c.cl_path <> p then begin
+							Printf.eprintf "Error loading ftp: %s <> %s\n" (s_type_path c.cl_path) (s_type_path p);
+							die "" __LOC__
+						end
+					| _ -> die "" __LOC__
+				);
+				ttp.ttp_type
+			with _ ->
+				Printf.eprintf "Error loading ftp for %s\n" (s_type_path p);
+				die "" __LOC__
+			)
 		| 6 ->
 			let i = self#read_uleb128 in
 			(type_type_parameters.(i)).ttp_type
@@ -656,13 +683,24 @@ class hxb_reader
 		| 11 ->
 			TEnum(self#read_enum_ref,[])
 		| 12 ->
+			let tp = self#read_path in
 			begin match self#read_u8 with
-				(* TODO does it make more sense to wrap in tdef like in source? *)
-				(* | 0 -> TType({null_typedef with t_type = (mk_anon (ref Closed))},[]) *)
-				(* | 1 -> TType({null_typedef with t_type = (TAnon self#read_anon_ref)},[]) *)
-				| 0 -> mk_anon (ref Closed)
-				| 1 -> TAnon self#read_anon_ref
-				| _ -> TType(self#read_typedef_ref,[])
+				| 0 -> TType({null_typedef with t_type = (mk_anon (ref Closed)); t_path = tp },[])
+				| 1 -> TType({null_typedef with t_type = (TAnon self#read_anon_ref); t_path = tp },[])
+				| 4 ->
+					let c = self#read_class_ref in
+					let t_tmp = class_module_type c in
+					TType(t_tmp,[])
+				| 5 ->
+					let e = self#read_enum_ref in
+					let t_tmp = enum_module_type e.e_module e.e_path e.e_pos in
+					TType(t_tmp,[])
+				| 6 ->
+					let a = self#read_abstract_ref in
+					let t_tmp = abstract_module_type a [] in
+					TType(t_tmp,[])
+				| _ ->
+					TType(self#read_typedef_ref,[])
 			end
 		| 13 ->
 			TAbstract(self#read_abstract_ref,[])
@@ -675,29 +713,43 @@ class hxb_reader
 			let tl = self#read_types in
 			TEnum(e,tl)
 		| 16 ->
+			let tp = self#read_path in
 			begin match self#read_u8 with
 				| 0 ->
 					let an = mk_anon (ref Closed) in
 					let tl = self#read_types in
-					let td = { null_typedef with t_type = an } in
+					let td = { null_typedef with t_type = an; t_path = tp } in
 					TType(td,tl)
 				| 1 ->
 					let an = TAnon self#read_anon_ref in
 					let tl = self#read_types in
-					let td = { null_typedef with t_type = an } in
+					let td = { null_typedef with t_type = an; t_path = tp } in
 					TType(td,tl)
+				| 4 ->
+					let c = self#read_class_ref in
+					let t_tmp = class_module_type c in
+					TType(t_tmp,[])
+				| 5 ->
+					let e = self#read_enum_ref in
+					let t_tmp = enum_module_type e.e_module e.e_path e.e_pos in
+					TType(t_tmp,[])
+				| 6 ->
+					let a = self#read_abstract_ref in
+					let t_tmp = abstract_module_type a [] in
+					TType(t_tmp,[])
 				(* TODO: does this help with anything? *)
 				(* | 2 -> *)
 				(* 	let t = self#read_type_instance in *)
 				(* 	let tl = self#read_types in *)
 				(* 	let tmono = !monomorph_create_ref () in (1* TODO identity *1) *)
 				(* 	tmono.tm_type <- Some t; *)
-				(* 	let td = { null_typedef with t_type = TMono tmono } in *)
+				(* 	let td = { null_typedef with t_type = TMono tmono; t_path = tp } in *)
 				(* 	TType(td,tl) *)
 				| _ ->
 					let t = self#read_type_instance in
 					let tl = self#read_types in
-					let td = { null_typedef with t_type = t } in
+					let td = { null_typedef with t_type = t; t_path = tp } in
+					(* let td = { null_typedef with t_type = t; t_path = ([], "708") } in *)
 					TType(td,tl)
 			end
 		| 17 ->
@@ -747,6 +799,13 @@ class hxb_reader
 
 	(* Fields *)
 
+	method add_field_type_parameters a = Array.iter (fun ttp ->
+			(match follow ttp.ttp_type with
+				| TInst(c,_) -> Hashtbl.add field_type_parameters c.cl_path ttp
+				| _ -> die "" __LOC__
+			)
+		) a
+
 	method read_type_parameters (path : path) (f : typed_type_param array -> unit) =
 		let l = self#read_uleb128 in
 		let a = Array.init l (fun _ ->
@@ -1124,13 +1183,21 @@ class hxb_reader
 	method read_class_field_data (nested : bool) (cf : tclass_field) : unit =
 		let name = cf.cf_name in
 		(* prerr_endline (Printf.sprintf "  Read class field %s" name); *)
+
+		if not nested then Hashtbl.clear field_type_parameters;
+		let params = ref [] in
 		self#read_type_parameters ([],name) (fun a ->
-			field_type_parameters <- if nested then Array.append field_type_parameters a else a
+			Array.iter (fun ttp ->
+				params := ttp :: !params;
+				(match follow ttp.ttp_type with
+					| TInst(c,_) -> Hashtbl.add field_type_parameters c.cl_path ttp
+					| _ -> die "" __LOC__
+				)
+			) a
 		);
 		self#read_type_parameters ([],name) (fun a ->
 			local_type_parameters <- if nested then Array.append local_type_parameters a else a
 		);
-		let params = Array.to_list field_type_parameters in
 		let t = self#read_type_instance in
 
 		let flags = IO.read_i32 ch in
@@ -1159,7 +1226,7 @@ class hxb_reader
 		cf.cf_kind <- kind;
 		cf.cf_expr <- expr;
 		cf.cf_expr_unoptimized <- expr_unoptimized;
-		cf.cf_params <- params;
+		cf.cf_params <- !params;
 		cf.cf_flags <- flags;
 
 	method read_class_field (nested : bool) =
@@ -1195,8 +1262,17 @@ class hxb_reader
 			let name = self#read_string in
 			(* prerr_endline (Printf.sprintf "  Read enum field %s" name); *)
 			let ef = PMap.find name e.e_constrs in
-			self#read_type_parameters ([],name) (fun a -> field_type_parameters <- a);
-			ef.ef_params <- Array.to_list field_type_parameters;
+			let params = ref [] in
+			self#read_type_parameters ([],name) (fun a ->
+				Array.iter (fun ttp ->
+					params := ttp :: !params;
+					(match follow ttp.ttp_type with
+						| TInst(c,_) -> Hashtbl.add field_type_parameters c.cl_path ttp
+						| _ -> die "" __LOC__
+					)
+				) a
+			);
+			ef.ef_params <- !params;
 			ef.ef_type <- self#read_type_instance;
 			ef.ef_doc <- self#read_option (fun () -> self#read_documentation);
 			ef.ef_meta <- self#read_metadata;
@@ -1256,7 +1332,7 @@ class hxb_reader
 		a.a_from <- self#read_list (fun () -> self#read_type_instance);
 		a.a_from_field <- self#read_list (fun () ->
 			let name = self#read_string in
-			self#read_type_parameters ([],name) (fun a -> field_type_parameters <- a);
+			self#read_type_parameters ([],name) self#add_field_type_parameters;
 			let t = self#read_type_instance in
 			let cf = self#read_field_ref impl.cl_statics in
 			(t,cf)
@@ -1264,7 +1340,7 @@ class hxb_reader
 		a.a_to <- self#read_list (fun () -> self#read_type_instance);
 		a.a_to_field <- self#read_list (fun () ->
 			let name = self#read_string in
-			self#read_type_parameters ([],name) (fun a -> field_type_parameters <- a);
+			self#read_type_parameters ([],name) self#add_field_type_parameters;
 			let t = self#read_type_instance in
 			let cf = self#read_field_ref impl.cl_statics in
 			(t,cf)
@@ -1278,6 +1354,9 @@ class hxb_reader
 
 	method read_enum (e : tenum) =
 		self#read_common_module_type (Obj.magic e);
+		(match self#read_u8 with
+		| 0 -> e.e_type.t_type <- (mk_anon (ref Closed))
+		| _ -> e.e_type.t_type <- TAnon self#read_anon_ref);
 		e.e_extern <- self#read_bool;
 		e.e_names <- self#read_list (fun () -> self#read_string);
 
@@ -1339,38 +1418,41 @@ class hxb_reader
 			self#read_enum_fields e;
 		done
 
-	method read_annd =
-		let l = self#read_uleb128 in
-		for i = 0 to l - 1 do
-			self#read_type_parameters ([],"") (fun a -> type_type_parameters <- a);
+	method read_anon an =
+		let old = type_type_parameters in
+		self#read_type_parameters ([],"") (fun a -> type_type_parameters <- Array.append type_type_parameters a);
+		let read_fields () =
+			let fields = self#read_list (fun () ->
+				let cf = self#read_class_field_forward in
+				self#read_class_field_data true cf;
+				cf
+			) in
+			List.iter (fun cf -> an.a_fields <- PMap.add cf.cf_name cf an.a_fields) fields;
+		in
 
-			let an = anons.(i) in
-			let read_fields () =
-				let fields = self#read_list (fun () -> self#read_class_field false) in
-				List.iter (fun cf -> an.a_fields <- PMap.add cf.cf_name cf an.a_fields;) fields;
-			in
+		begin match self#read_u8 with
+		| 0 ->
+			an.a_status := Closed;
+			read_fields ()
+		| 1 ->
+			an.a_status := Const;
+			read_fields ()
+		| 2 ->
+			an.a_status := Extend self#read_types;
+			read_fields ()
+		| 3 ->
+			an.a_status := ClassStatics self#read_class_ref;
+		| 4 ->
+			an.a_status := EnumStatics self#read_enum_ref;
+			read_fields ()
+		| 5 ->
+			an.a_status := AbstractStatics self#read_abstract_ref;
+			read_fields ()
+		| _ -> assert false
+		end;
 
-			begin match self#read_u8 with
-			| 0 ->
-				an.a_status := Closed;
-				read_fields ()
-			| 1 ->
-				an.a_status := Const;
-				read_fields ()
-			| 2 ->
-				an.a_status := Extend self#read_types;
-				read_fields ()
-			| 3 ->
-				an.a_status := ClassStatics self#read_class_ref;
-			| 4 ->
-				an.a_status := EnumStatics self#read_enum_ref;
-				read_fields ()
-			| 5 ->
-				an.a_status := AbstractStatics self#read_abstract_ref;
-				read_fields ()
-			| _ -> assert false
-			end;
-		done
+		type_type_parameters <- old;
+		an
 
 	method read_tpdd =
 		let l = self#read_uleb128 in
@@ -1427,10 +1509,6 @@ class hxb_reader
 				error ("Unexpected type where typedef was expected: " ^ (s_type_path (pack,tname)))
 		))
 
-	method read_annr =
-		let l = self#read_uleb128 in
-		anons <- Array.init l (fun _ -> { a_fields = PMap.empty; a_status = ref Closed });
-
 	method read_typf =
 		self#read_list (fun () ->
 			let kind = self#read_u8 in
@@ -1458,10 +1536,6 @@ class hxb_reader
 				TClassDecl c
 			| 1 ->
 				let en = mk_enum m path pos name_pos in
-				(match self#read_u8 with
-				| 0 -> en.e_type.t_type <- (mk_anon (ref Closed))
-				| _ -> en.e_type.t_type <- TAnon self#read_anon_ref);
-
 				enums <- Array.append enums (Array.make 1 en);
 
 				let read_field () =
@@ -1498,6 +1572,11 @@ class hxb_reader
 		let path = self#read_path in
 		let file = self#read_string in
 		(* prerr_endline (Printf.sprintf "Read hxb module %s" (s_type_path path)); *)
+
+		let l = self#read_uleb128 in
+		(* trace (Printf.sprintf "%d anons available" l); *)
+		anons <- Array.init l (fun _ -> { a_fields = PMap.empty; a_status = ref Closed });
+
 		anon_fields <- Array.make (self#read_uleb128) null_field;
 		make_module path file
 
@@ -1526,20 +1605,21 @@ class hxb_reader
 			| (kind,data) :: chunks ->
 				ch <- IO.input_bytes data;
 				match kind with
-				| HHDR ->
-					m <- self#read_hhdr;
-					chunks
 				| STRI ->
 					string_pool <- self#read_string_pool;
 					pass_0 chunks
 				| DOCS ->
 					doc_pool <- self#read_string_pool;
 					pass_0 chunks
+				| HHDR ->
+					m <- self#read_hhdr;
+					chunks
 				| _ ->
 					error ("Unexpected early chunk: " ^ (string_of_chunk_kind kind))
 		in
 		let chunks = pass_0 chunks in
 		assert(m != null_module);
+		(* trace (Printf.sprintf " Reading module %s from hxb" (s_type_path m.m_path)); *)
 		List.iter (fun (kind,data) ->
 			(* prerr_endline (Printf.sprintf " Reading chunk %s" (string_of_chunk_kind kind)); *)
 			ch <- IO.input_bytes data;
@@ -1551,27 +1631,23 @@ class hxb_reader
 				self#read_clsr;
 			| ABSR ->
 				self#read_absr;
-			| ENMR ->
-				self#read_enmr;
 			| TPDR ->
 				self#read_tpdr;
-			| ANNR ->
-				self#read_annr;
-			| ABSD ->
-				self#read_absd;
+			| ENMR ->
+				self#read_enmr;
 			| CLSD ->
 				self#read_clsd;
+			| ABSD ->
+				self#read_absd;
 			| CFLD ->
 				flush_fields ();
 				self#read_cfld;
+			| TPDD ->
+				self#read_tpdd;
 			| ENMD ->
 				self#read_enmd;
 			| EFLD ->
 				self#read_efld;
-			| ANND ->
-				self#read_annd;
-			| TPDD ->
-				self#read_tpdd;
 			| _ ->
 				error ("Unexpected late chunk: " ^ (string_of_chunk_kind kind))
 		) chunks;

+ 59 - 69
src/compiler/hxb/hxbWriter.ml

@@ -349,10 +349,15 @@ class ['a] hxb_writer
 
 	method write_anon_ref (an : tanon) (ttp : type_params) =
 		let pfm = Option.get (anon_id#identify true (TAnon an)) in
-		let ftp = field_type_parameters#to_list in
-		let ttp = ttp @ type_type_parameters#to_list in
-		let i = anons#get_or_add pfm.pfm_path (an,ttp,ftp) in
-		chunk#write_uleb128 i
+		try
+			let index = anons#get pfm.pfm_path in
+			chunk#write_byte 0;
+			chunk#write_uleb128 index
+		with Not_found ->
+			let index = anons#add pfm.pfm_path an in
+			chunk#write_byte 1;
+			chunk#write_uleb128 index;
+			self#write_anon an ttp
 
 	method write_field_ref (source : field_source) (cf : tclass_field) =
 		chunk#write_string cf.cf_name
@@ -369,24 +374,28 @@ class ['a] hxb_writer
 			let index = anon_fields#add cf () in
 			chunk#write_byte 1;
 			chunk#write_uleb128 index;
-			List.iter (fun ttp ->
-				ignore(field_type_parameters#add ttp.ttp_name ttp);
+			let close = self#open_field_scope true cf in
+			List.iter (fun ttp -> match follow ttp.ttp_type with
+				| TInst(c,_) -> ignore(field_type_parameters#add c.cl_path ttp)
+				| _ -> die "" __LOC__
 			) cf.cf_params;
 			self#write_class_field_forward cf;
 			self#write_class_field_data cf;
+			close()
 
 	(* Type instances *)
 
 	method write_type_parameter_ref (c : tclass) =
 		begin try
-			let i = field_type_parameters#get (snd c.cl_path) in
+			let _ = field_type_parameters#get c.cl_path in
 			chunk#write_byte 5;
-			chunk#write_uleb128 i
+			self#write_path c.cl_path;
 		with Not_found -> try
-			let i = type_type_parameters#get (snd c.cl_path) in
+			let i = type_type_parameters#get c.cl_path in
 			chunk#write_byte 6;
 			chunk#write_uleb128 i
 		with Not_found -> try
+			(* trace (s_type_path c.cl_path); *)
 			let index = local_type_parameters#get c in
 			chunk#write_byte 7;
 			chunk#write_uleb128 index;
@@ -431,6 +440,7 @@ class ['a] hxb_writer
 			self#write_enum_ref en;
 		| TType(td,[]) ->
 			chunk#write_byte 12;
+			self#write_path td.t_path;
 			begin match td.t_type with
 				| TAnon an when PMap.is_empty an.a_fields ->
 					chunk#write_byte 0;
@@ -455,6 +465,7 @@ class ['a] hxb_writer
 			self#write_types tl
 		| TType(td,tl) ->
 			chunk#write_byte 16;
+			self#write_path td.t_path;
 			begin match td.t_type with
 				| TAnon an when PMap.is_empty an.a_fields ->
 					chunk#write_byte 0;
@@ -463,13 +474,8 @@ class ['a] hxb_writer
 					chunk#write_byte 1;
 					self#write_anon_ref an td.t_params;
 					self#write_types tl
-				(* TODO: does this help with anything? *)
-				| TMono _ ->
-					chunk#write_byte 2;
-					self#write_type_instance ~debug (apply_typedef td tl);
-					self#write_types tl
 				| _ ->
-					chunk#write_byte 3;
+					chunk#write_byte 2;
 					self#write_type_instance ~debug (apply_typedef td tl);
 					self#write_types tl
 			end;
@@ -1121,10 +1127,11 @@ class ['a] hxb_writer
 
 	(* Fields *)
 
-	method set_field_type_parameters (params : typed_type_param list) =
-		field_type_parameters <- new pool;
-		List.iter (fun ttp ->
-			ignore(field_type_parameters#add ttp.ttp_name ttp);
+	method set_field_type_parameters (nested : bool) params =
+		if not nested then field_type_parameters <- new pool;
+		List.iter (fun ttp -> match follow ttp.ttp_type with
+			| TInst(c,_) -> ignore(field_type_parameters#add c.cl_path ttp);
+			| _ -> die "" __LOC__
 		) params
 
 	method write_type_parameter_forward ttp = match follow ttp.ttp_type with
@@ -1179,11 +1186,11 @@ class ['a] hxb_writer
 			f r;
 			f w;
 
-	method open_field_scope (cf : tclass_field) =
+	method open_field_scope (nested : bool) (cf : tclass_field) =
 		let old_field_params = field_type_parameters in
 		let old_local_params = local_type_parameters in
-		local_type_parameters <- new identity_pool;
-		self#set_field_type_parameters cf.cf_params;
+		if not nested then local_type_parameters <- new identity_pool;
+		self#set_field_type_parameters nested cf.cf_params;
 		(fun () ->
 			field_type_parameters <- old_field_params;
 			local_type_parameters <- old_local_params;
@@ -1223,12 +1230,6 @@ class ['a] hxb_writer
 			new_chunk#export_data chunk#ch
 		)
 
-	method write_class_field cf =
-		let close = self#open_field_scope cf in
-		self#write_class_field_forward cf;
-		self#write_class_field_data cf;
-		close()
-
 	(* Module types *)
 
 	method select_type (path : path) =
@@ -1317,7 +1318,7 @@ class ['a] hxb_writer
 		chunk#write_list a.a_from self#write_type_instance;
 		chunk#write_list a.a_from_field (fun (t,cf) ->
 			chunk#write_string cf.cf_name;
-			self#set_field_type_parameters cf.cf_params;
+			self#set_field_type_parameters false cf.cf_params;
 			chunk#write_list cf.cf_params self#write_type_parameter_forward;
 			chunk#write_list cf.cf_params self#write_type_parameter_data;
 			self#write_type_instance t;
@@ -1326,7 +1327,7 @@ class ['a] hxb_writer
 		chunk#write_list a.a_to self#write_type_instance;
 		chunk#write_list a.a_to_field (fun (t,cf) ->
 			chunk#write_string cf.cf_name;
-			self#set_field_type_parameters cf.cf_params;
+			self#set_field_type_parameters false cf.cf_params;
 			chunk#write_list cf.cf_params self#write_type_parameter_forward;
 			chunk#write_list cf.cf_params self#write_type_parameter_data;
 			self#write_type_instance t;
@@ -1342,6 +1343,15 @@ class ['a] hxb_writer
 		(* debug_msg (Printf.sprintf "Write enum %s" (snd e.e_path)); *)
 		self#select_type e.e_path;
 		self#write_common_module_type (Obj.magic e);
+
+		(match e.e_type.t_type with
+		| TAnon an when PMap.is_empty an.a_fields ->
+			chunk#write_byte 0;
+		| TAnon an ->
+			chunk#write_byte 1;
+			self#write_anon_ref an e.e_type.t_params
+		| _ -> assert false);
+
 		chunk#write_bool e.e_extern;
 		chunk#write_list e.e_names chunk#write_string;
 
@@ -1351,15 +1361,22 @@ class ['a] hxb_writer
 		self#write_common_module_type (Obj.magic td);
 		self#write_type_instance td.t_type;
 
-	method write_anon (m : module_def) ((an : tanon), (ttp : type_params), (ftp : type_params)) =
+	method write_anon (an : tanon) (ttp : type_params) =
+		let old = type_type_parameters in
 		type_type_parameters <- new pool;
-		List.iter (fun ttp -> ignore(type_type_parameters#add ttp.ttp_name ttp)) ttp;
+		List.iter (fun ttp -> match follow ttp.ttp_type with
+			| TInst(c,_) -> ignore(type_type_parameters#add c.cl_path ttp)
+			| _ -> die "" __LOC__
+		) ttp;
 		chunk#write_list ttp self#write_type_parameter_forward;
 		chunk#write_list ttp self#write_type_parameter_data;
 
 		let write_fields () =
 			chunk#write_list (PMap.foldi (fun s f acc -> (s,f) :: acc) an.a_fields []) (fun (_,cf) ->
-				self#write_class_field { cf with cf_params = (cf.cf_params @ ftp) };
+				let close = self#open_field_scope true cf in
+				self#write_class_field_forward cf;
+				self#write_class_field_data cf;
+				close()
 			)
 		in
 
@@ -1385,7 +1402,9 @@ class ['a] hxb_writer
 			chunk#write_byte 5;
 			self#write_abstract_ref a;
 			write_fields ()
-		end
+		end;
+
+		type_type_parameters <- old
 
 	(* Module *)
 
@@ -1424,8 +1443,9 @@ class ['a] hxb_writer
 		let params = new pool in
 		type_type_parameters <- params;
 		ignore(type_param_lut#add infos.mt_path params);
-		List.iter (fun ttp ->
-			ignore(type_type_parameters#add ttp.ttp_name ttp);
+		List.iter (fun ttp -> match follow ttp.ttp_type with
+			| TInst(c,_) -> ignore(type_type_parameters#add c.cl_path ttp)
+			| _ -> die "" __LOC__
 		) infos.mt_params;
 
 		(* Forward declare fields *)
@@ -1435,14 +1455,6 @@ class ['a] hxb_writer
 			chunk#write_list c.cl_ordered_fields self#write_class_field_forward;
 			chunk#write_list c.cl_ordered_statics self#write_class_field_forward;
 		| TEnumDecl e ->
-			(match e.e_type.t_type with
-			| TAnon an when PMap.is_empty an.a_fields ->
-				chunk#write_byte 0;
-			| TAnon an ->
-				chunk#write_byte 1;
-				self#write_anon_ref an e.e_type.t_params
-			| _ -> assert false);
-
 			chunk#write_list (PMap.foldi (fun s f acc -> (s,f) :: acc) e.e_constrs []) (fun (s,ef) ->
 				(* debug_msg (Printf.sprintf "  forward declare enum field %s.%s" (s_type_path e.e_path) s); *)
 				chunk#write_string s;
@@ -1491,7 +1503,7 @@ class ['a] hxb_writer
 
 				let write_field with_name cf =
 					if with_name then chunk#write_string cf.cf_name;
-					let close = self#open_field_scope cf in
+					let close = self#open_field_scope false cf in
 					self#write_class_field_data cf;
 					close();
 				in
@@ -1514,7 +1526,7 @@ class ['a] hxb_writer
 					self#select_type e.e_path;
 					(* debug_msg (Printf.sprintf "  Write enum field %s.%s" (s_type_path e.e_path) s); *)
 					chunk#write_string s;
-					self#set_field_type_parameters ef.ef_params;
+					self#set_field_type_parameters false ef.ef_params;
 					chunk#write_list ef.ef_params self#write_type_parameter_forward;
 					chunk#write_list ef.ef_params self#write_type_parameter_data;
 					self#write_type_instance ef.ef_type;
@@ -1531,29 +1543,6 @@ class ['a] hxb_writer
 			chunk#write_list own_typedefs self#write_typedef;
 		end;
 
-		begin match anons#to_list with
-		| [] ->
-			()
-		| al ->
-			(* TODO clean this... currently loops until writing anons doesn't register any new anon *)
-			let rec loop written al =
-				let len = List.length al in
-				let temp_chunk = new chunk ANND cp in
-				chunk <- temp_chunk;
-				chunk#write_list al (fun an -> self#write_anon m an);
-
-				let al = anons#to_list in
-				let new_len = List.length al in
-				if len = new_len then begin
-					DynArray.add chunks temp_chunk;
-
-					self#start_chunk ANNR;
-					chunk#write_uleb128 len;
-				end else loop len al;
-			in
-			loop 0 al
-		end;
-
 		begin match classes#to_list with
 		| [] ->
 			()
@@ -1605,6 +1594,7 @@ class ['a] hxb_writer
 		self#start_chunk HHDR;
 		self#write_path m.m_path;
 		chunk#write_string (Path.UniqueKey.lazy_path m.m_extra.m_file);
+		chunk#write_uleb128 (DynArray.length anons#items);
 		chunk#write_uleb128 (DynArray.length anon_fields#items);
 		self#start_chunk HEND;