Selaa lähdekoodia

fix overloads a bit more

but it's still not 100% working
Simon Krajewski 1 vuosi sitten
vanhempi
commit
d35eb2a672

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

@@ -2,6 +2,7 @@ open Globals
 open Ast
 open Type
 open HxbData
+open HxbShared
 
 (* Debug utils *)
 let no_color = false
@@ -1145,11 +1146,15 @@ class hxb_reader
 		in
 		let expr_unoptimized = self#read_option (fun () -> self#read_texpr) in
 
-		let l = self#read_uleb128 in
-		for i = 0 to l - 1 do
-			let f = List.nth cf.cf_overloads i in
-			self#read_class_field_data false f
-		done;
+		let rec loop depth cfl = match cfl with
+			| cf :: cfl ->
+				assert (depth > 0);
+				self#read_class_field_data false cf;
+				loop (depth - 1) cfl
+			| [] ->
+				assert (depth = 0)
+		in
+		loop self#read_uleb128 cf.cf_overloads;
 
 		cf.cf_type <- t;
 		cf.cf_doc <- doc;
@@ -1184,17 +1189,21 @@ class hxb_reader
 			List.iter set_feature (Feature.check_if_feature cf.cf_meta);
 		in
 		let _ = self#read_option (fun f ->
-			let cf = self#read_field_ref in
+			let cf = Option.get c.cl_constructor in
 			handle_feature CfrConstructor cf;
 			self#read_class_field_data false cf
 		) in
-		let f ref_kind =
-			let cf = self#read_field_ref in
-			self#read_class_field_data false cf;
-			handle_feature ref_kind cf;
+		let rec loop ref_kind num cfl = match cfl with
+			| cf :: cfl ->
+				assert (num > 0);
+				handle_feature ref_kind cf;
+				self#read_class_field_data false cf;
+				loop ref_kind (num - 1) cfl
+			| [] ->
+				assert (num = 0)
 		in
-		let _ = self#read_list (fun () -> f CfrMember) in
-		let _ = self#read_list (fun () -> f CfrStatic) in
+		loop CfrMember (self#read_uleb128) c.cl_ordered_fields;
+		loop CfrStatic (self#read_uleb128) c.cl_ordered_statics;
 		c.cl_init <- self#read_option (fun () -> self#read_texpr);
 		(match c.cl_kind with KModuleFields md -> md.m_statics <- Some c; | _ -> ());
 
@@ -1349,28 +1358,33 @@ class hxb_reader
 
 	method read_cflr =
 		let l = self#read_uleb128 in
+		let instance_overload_cache = Hashtbl.create 0 in
 		let a = Array.init l (fun i ->
 			let c = self#read_class_ref in
 			ignore(c.cl_build());
-			let cf =  match self#read_u8 with
-				| 0 ->
+			let kind = match self#read_u8 with
+				| 0 -> CfrStatic
+				| 1 -> CfrMember
+				| 2 -> CfrConstructor
+				| _ -> die "" __LOC__
+			in
+			let cf =  match kind with
+				| CfrStatic ->
 					let name = self#read_string in
 					begin try
 						PMap.find name c.cl_statics
 					with Not_found ->
 						raise (HxbFailure (Printf.sprintf "Could not read static field %s on %s while hxbing %s" name (s_type_path c.cl_path) (s_type_path current_module.m_path)))
 					end;
-				| 1 ->
+				| CfrMember ->
 					let name = self#read_string in
 					begin try
 						PMap.find name c.cl_fields
 					with Not_found ->
 						raise (HxbFailure (Printf.sprintf "Could not read instance field %s on %s while hxbing %s" name (s_type_path c.cl_path) (s_type_path current_module.m_path)))
 					end
-				| 2 ->
+				| CfrConstructor ->
 					Option.get c.cl_constructor
-				| _ ->
-					die "" __LOC__
 			in
 			let depth = self#read_uleb128 in
 			let pick_overload cf depth =
@@ -1383,7 +1397,19 @@ class hxb_reader
 					| [] ->
 						raise (HxbFailure (Printf.sprintf "Bad overload depth for %s on %s: %i" cf.cf_name (s_type_path c.cl_path) depth))
 				in
-				loop depth (cf :: cf.cf_overloads)
+				let cfl = match kind with
+					| CfrStatic | CfrConstructor ->
+						(cf :: cf.cf_overloads)
+					| CfrMember ->
+						let key = (c.cl_path,cf.cf_name) in
+						try
+							Hashtbl.find instance_overload_cache key
+						with Not_found ->
+							let l = get_instance_overloads c cf in
+							Hashtbl.add instance_overload_cache key l;
+							l
+				in
+				loop depth cfl
 			in
 			pick_overload cf depth;
 		) in

+ 25 - 0
src/compiler/hxb/hxbShared.ml

@@ -0,0 +1,25 @@
+open Type
+
+let get_instance_overloads c cf =
+	let acc = DynArray.create () in
+	let rec loop c cf =
+		ignore(c.cl_build());
+		List.iter (DynArray.add acc) (cf :: cf.cf_overloads);
+		let maybe_recurse c =
+			try
+				loop c (PMap.find cf.cf_name c.cl_fields)
+			with Not_found ->
+				()
+		in
+		if has_class_flag c CInterface then
+			List.iter (fun (c,_) ->
+				maybe_recurse c
+			) c.cl_implements
+		else match c.cl_super with
+			| Some(c,_) ->
+				maybe_recurse c
+			| None ->
+				()
+	in
+	loop c cf;
+	DynArray.to_list acc

+ 16 - 5
src/compiler/hxb/hxbWriter.ml

@@ -3,6 +3,7 @@ open Ast
 open Type
 open HxbData
 open Tanon_identification
+open HxbShared
 
 (* Debug utils *)
 let no_color = false
@@ -272,6 +273,8 @@ class ['a] hxb_writer
 	val mutable field_type_parameters = new identity_pool
 	val mutable local_type_parameters = new identity_pool
 
+	val instance_overload_cache = Hashtbl.create 0
+
 	(* Chunks *)
 
 	method start_chunk (kind : chunk_kind) =
@@ -378,7 +381,19 @@ class ['a] hxb_writer
 						print_endline (Printf.sprintf "Could not resolve %s overload for %s on %s" (s_class_field_ref_kind kind) cf.cf_name (s_type_path c.cl_path));
 						0,cf
 				in
-				loop 0 (cf_base :: cf_base.cf_overloads)
+				let cfl = match kind with
+					| CfrStatic | CfrConstructor ->
+						(cf_base :: cf_base.cf_overloads)
+					| CfrMember ->
+						let key = (c.cl_path,cf_base.cf_name) in
+						try
+							Hashtbl.find instance_overload_cache key
+						with Not_found ->
+							let l = get_instance_overloads c cf_base in
+							Hashtbl.add instance_overload_cache key l;
+							l
+				in
+				loop 0 cfl
 			end in
 			chunk#write_uleb128 (class_fields#add cf (c,kind,depth));
 
@@ -1080,9 +1095,6 @@ class ['a] hxb_writer
 				in
 				self#write_enum_field_ref en ef;
 				chunk#write_i32 i;
-			(* | TEnumParameter(e1,({ ef_type = eft}),i) -> *)
-			(* 	prerr_endline (Printf.sprintf "en = %s" (s_type_kind eft)); *)
-			(* 	assert false *)
 			| TField(e1,FInstance(c,tl,cf)) ->
 				chunk#write_byte 102;
 				loop e1;
@@ -1530,7 +1542,6 @@ class ['a] hxb_writer
 				end;
 
 				let write_field source cf =
-					self#write_field_ref c source cf;
 					let close = self#open_field_scope false cf in
 					self#write_class_field_data cf;
 					close();

+ 1 - 0
tests/unit/src/unit/TestOverloads.hx

@@ -2,6 +2,7 @@ package unit;
 import haxe.io.Bytes;
 import unit.HelperMacros.typeError;
 import unit.HelperMacros.typedAs;
+
 using unit.TestOverloads.UsingTest2;
 using unit.TestOverloads.UsingTest3;