浏览代码

field type parameters 2.0

Simon Krajewski 1 年之前
父节点
当前提交
5779ee9013
共有 2 个文件被更改,包括 41 次插入24 次删除
  1. 23 15
      src/compiler/hxb/hxbReader.ml
  2. 18 9
      src/compiler/hxb/hxbWriter.ml

+ 23 - 15
src/compiler/hxb/hxbReader.ml

@@ -84,6 +84,7 @@ class hxb_reader
 	val mutable local_type_parameters = Array.make 0 (mk_type_param null_class TPHLocal None None)
 
 	val mutable field_stack = []
+	val mutable field_type_parameter_offset = 0
 
 	method in_nested_scope = match field_stack with
 		| [] -> assert false
@@ -1136,18 +1137,30 @@ class hxb_reader
 		) in
 		create_field_reader_context self#read_pos a
 
+	method read_field_type_parameters kind =
+		let num_params = self#read_uleb128 in
+		if not self#in_nested_scope then begin
+			self#read_type_parameters kind (* TODO: need to encode this because we don't know *) (fun a ->
+				field_type_parameters <- a;
+			);
+			field_type_parameter_offset <- 0;
+		end;
+		let params = List.init num_params (fun offset ->
+			field_type_parameters.(field_type_parameter_offset + offset)
+		) in
+		field_type_parameter_offset <- field_type_parameter_offset + num_params;
+		params
+
 	method read_class_field_data (cf : tclass_field) : unit =
 		current_field <- cf;
 
 		let nested = self#in_nested_scope in
-		let params = ref [] in
-		self#read_type_parameters (if nested then TPHAnonField else TPHMethod) (fun a ->
-			params := Array.to_list a;
-			field_type_parameters <- if nested then Array.append field_type_parameters a else a
-		);
-		self#read_type_parameters TPHLocal (fun a ->
-			local_type_parameters <- if nested then Array.append local_type_parameters a else a
-		);
+		let params = self#read_field_type_parameters TPHMethod in
+
+		if not nested then
+			self#read_type_parameters TPHLocal (fun a ->
+				local_type_parameters <- a
+			);
 		let t = self#read_type_instance in
 
 		let flags = IO.read_i32 ch in
@@ -1172,7 +1185,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_and_overloads_data (cf : tclass_field) =
@@ -1234,12 +1247,7 @@ class hxb_reader
 			let name = self#read_string in
 			let close = self#open_field_scope in
 			let ef = PMap.find name e.e_constrs in
-			let params = ref [] in
-			self#read_type_parameters TPHEnumConstructor (fun a ->
-				params := Array.to_list a;
-				field_type_parameters <- a;
-			);
-			ef.ef_params <- !params;
+			ef.ef_params <- self#read_field_type_parameters TPHEnumConstructor;
 			ef.ef_type <- self#read_type_instance;
 			ef.ef_doc <- self#read_option (fun () -> self#read_documentation);
 			ef.ef_meta <- self#read_metadata;

+ 18 - 9
src/compiler/hxb/hxbWriter.ml

@@ -900,8 +900,6 @@ class hxb_writer
 			let index = anon_fields#add cf () in
 			chunk#write_u8 1;
 			chunk#write_uleb128 index;
-			(* TODO: nested here may or not be true. We should handle this accurately for type
-			   parameter reasons. This is also true for the reader. *)
 			let close = self#open_field_scope cf.cf_params in
 			self#write_class_field_data cf;
 			close()
@@ -1506,6 +1504,14 @@ class hxb_writer
 			)
 		)
 
+	method commit_field_type_parameters (params : type_params) =
+		chunk#write_uleb128 (List.length params);
+		if not self#in_nested_scope then begin
+			let ftp = List.map fst field_type_parameters#to_list in
+			chunk#write_list ftp self#write_type_parameter_forward;
+			chunk#write_list ftp self#write_type_parameter_data;
+		end
+
 	method write_class_field_data cf =
 		let restore = self#start_temporary_chunk in
 		(try self#write_type_instance cf.cf_type with e -> begin
@@ -1528,11 +1534,12 @@ class hxb_writer
 		end;
 
 		restore (fun new_chunk ->
-			chunk#write_list cf.cf_params self#write_type_parameter_forward;
-			chunk#write_list cf.cf_params self#write_type_parameter_data;
-			let ltp = List.map fst local_type_parameters#to_list in
-			chunk#write_list ltp self#write_type_parameter_forward;
-			chunk#write_list ltp self#write_type_parameter_data;
+			self#commit_field_type_parameters cf.cf_params;
+			if not self#in_nested_scope then begin
+				let ltp = List.map fst local_type_parameters#to_list in
+				chunk#write_list ltp self#write_type_parameter_forward;
+				chunk#write_list ltp self#write_type_parameter_data;
+			end;
 			new_chunk#export_data chunk
 		)
 
@@ -1808,9 +1815,11 @@ class hxb_writer
 					self#select_type e.e_path;
 					let close = self#open_field_scope ef.ef_params in
 					chunk#write_string s;
-					chunk#write_list ef.ef_params self#write_type_parameter_forward;
-					chunk#write_list ef.ef_params self#write_type_parameter_data;
+					let restore = self#start_temporary_chunk in
 					self#write_type_instance ef.ef_type;
+					let t_bytes = restore (fun new_chunk -> new_chunk#get_bytes) in
+					self#commit_field_type_parameters ef.ef_params;
+					chunk#write_bytes t_bytes;
 					chunk#write_option ef.ef_doc self#write_documentation;
 					self#write_metadata ef.ef_meta;
 					close();