Ver Fonte

more CFEX work

Simon Krajewski há 1 ano atrás
pai
commit
95656e324e
2 ficheiros alterados com 50 adições e 20 exclusões
  1. 26 11
      src/compiler/hxb/hxbReader.ml
  2. 24 9
      src/compiler/hxb/hxbWriter.ml

+ 26 - 11
src/compiler/hxb/hxbReader.ml

@@ -1237,6 +1237,13 @@ class hxb_reader
 				self#read_type_parameters (fun a ->
 				self#read_type_parameters (fun a ->
 					local_type_parameters <- a
 					local_type_parameters <- a
 				);
 				);
+			| 2 ->
+				let num_params = read_uleb128 ch in
+				field_type_parameters <- Array.make num_params (mk_type_param null_class TPHMethod None None);
+				field_type_parameter_offset <- 0;
+				self#read_type_parameters (fun a ->
+					local_type_parameters <- a
+				);
 			| i ->
 			| i ->
 				die "" __LOC__
 				die "" __LOC__
 		end;
 		end;
@@ -1250,7 +1257,7 @@ class hxb_reader
 		) in
 		) in
 		create_field_reader_context self#read_pos ts vars
 		create_field_reader_context self#read_pos ts vars
 
 
-	method read_field_type_parameters kind =
+	method read_field_type_parameters =
 		let num_params = read_uleb128 ch in
 		let num_params = read_uleb128 ch in
 		begin match IO.read_byte ch with
 		begin match IO.read_byte ch with
 			| 0 ->
 			| 0 ->
@@ -1259,7 +1266,7 @@ class hxb_reader
 				self#read_type_parameters (fun a ->
 				self#read_type_parameters (fun a ->
 					field_type_parameters <- a;
 					field_type_parameters <- a;
 				);
 				);
-				field_type_parameter_offset <- 0;
+				field_type_parameter_offset <- 0; (* num_params is added below *)
 			| i ->
 			| i ->
 				die "" __LOC__
 				die "" __LOC__
 		end;
 		end;
@@ -1269,8 +1276,7 @@ class hxb_reader
 		field_type_parameter_offset <- field_type_parameter_offset + num_params;
 		field_type_parameter_offset <- field_type_parameter_offset + num_params;
 		params
 		params
 
 
-	method read_expression =
-		let fctx = self#start_texpr in
+	method read_expression (fctx : field_reader_context) =
 		let e = self#read_texpr fctx in
 		let e = self#read_texpr fctx in
 		let e_unopt = self#read_option (fun () -> self#read_texpr fctx) in
 		let e_unopt = self#read_option (fun () -> self#read_texpr fctx) in
 		e,e_unopt
 		e,e_unopt
@@ -1278,7 +1284,7 @@ class hxb_reader
 	method read_class_field_data (cf : tclass_field) : unit =
 	method read_class_field_data (cf : tclass_field) : unit =
 		current_field <- cf;
 		current_field <- cf;
 
 
-		let params = self#read_field_type_parameters TPHMethod in
+		let params = self#read_field_type_parameters in
 
 
 		let t = self#read_type_instance in
 		let t = self#read_type_instance in
 
 
@@ -1292,7 +1298,8 @@ class hxb_reader
 			| 0 ->
 			| 0 ->
 				None,None
 				None,None
 			| _ ->
 			| _ ->
-				let e,e_unopt = self#read_expression in
+				let fctx = self#start_texpr in
+				let e,e_unopt = self#read_expression fctx in
 				(Some e,e_unopt)
 				(Some e,e_unopt)
 		in
 		in
 
 
@@ -1347,7 +1354,7 @@ class hxb_reader
 		ignore(self#read_list (fun () ->
 		ignore(self#read_list (fun () ->
 			let name = self#read_string in
 			let name = self#read_string in
 			let ef = PMap.find name e.e_constrs in
 			let ef = PMap.find name e.e_constrs in
-			ef.ef_params <- self#read_field_type_parameters TPHEnumConstructor;
+			ef.ef_params <- self#read_field_type_parameters;
 			ef.ef_type <- self#read_type_instance;
 			ef.ef_type <- self#read_type_instance;
 			ef.ef_doc <- self#read_option (fun () -> self#read_documentation);
 			ef.ef_doc <- self#read_option (fun () -> self#read_documentation);
 			ef.ef_meta <- self#read_metadata;
 			ef.ef_meta <- self#read_metadata;
@@ -1559,10 +1566,18 @@ class hxb_reader
 
 
 	method read_cfex =
 	method read_cfex =
 		ignore(self#read_list (fun () ->
 		ignore(self#read_list (fun () ->
-			let cf = self#read_field_ref in
-			let e,e_unopt = self#read_expression in
-			cf.cf_expr <- Some e;
-			cf.cf_expr_unoptimized <- e_unopt
+			let c = self#read_class_ref in
+			self#select_class_type_parameters c;
+			self#read_list (fun () ->
+				let cf = self#read_field_ref in
+				let fctx = self#start_texpr in
+				List.iteri (fun i ttp ->
+					field_type_parameters.(i) <- ttp
+				) cf.cf_params;
+				let e,e_unopt = self#read_expression fctx in
+				cf.cf_expr <- Some e;
+				cf.cf_expr_unoptimized <- e_unopt
+			)
 		))
 		))
 
 
 	method read_afld =
 	method read_afld =

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

@@ -184,6 +184,8 @@ class ['key,'value] identity_pool = object(self)
 		DynArray.to_list items
 		DynArray.to_list items
 
 
 	method items = items
 	method items = items
+
+	method length = DynArray.length items
 end
 end
 
 
 module SimnBuffer = struct
 module SimnBuffer = struct
@@ -1702,7 +1704,7 @@ class hxb_writer
 			self#write_class_field_forward cf;
 			self#write_class_field_forward cf;
 		);
 		);
 
 
-	method start_texpr (p: pos) =
+	method start_texpr (write_expr_immediately : bool) (p: pos) =
 		let restore = self#start_temporary_chunk 512 in
 		let restore = self#start_temporary_chunk 512 in
 		let fctx = create_field_writer_context (new pos_writer chunk stats p) in
 		let fctx = create_field_writer_context (new pos_writer chunk stats p) in
 		fctx,(fun () ->
 		fctx,(fun () ->
@@ -1711,7 +1713,15 @@ class hxb_writer
 				if self#in_nested_scope then
 				if self#in_nested_scope then
 					IOChunk.write_u8 chunk.io 0
 					IOChunk.write_u8 chunk.io 0
 				else begin
 				else begin
-					IOChunk.write_u8 chunk.io 1;
+					if write_expr_immediately then
+						IOChunk.write_u8 chunk.io 1
+					else begin
+						IOChunk.write_u8 chunk.io 2;
+						(* For CFEX, we give the total number of field type parameters so that
+						   the reader can allocate a fixed array. The first elements correspond
+						   to cf_params, the rest will be filled by nested anon field params. *)
+						IOChunk.write_uleb128 chunk.io field_type_parameters#length;
+					end;
 					let ltp = List.map fst local_type_parameters#to_list in
 					let ltp = List.map fst local_type_parameters#to_list in
 					self#write_type_parameters ltp
 					self#write_type_parameters ltp
 				end;
 				end;
@@ -1754,14 +1764,14 @@ class hxb_writer
 				None
 				None
 			(* | Some e when not write_expr_immediately ->
 			(* | Some e when not write_expr_immediately ->
 				IOChunk.write_u8 chunk.io 0;
 				IOChunk.write_u8 chunk.io 0;
-				let fctx,close = self#start_texpr e.epos in
+				let fctx,close = self#start_texpr false e.epos in
 				self#write_texpr fctx e;
 				self#write_texpr fctx e;
 				Chunk.write_option chunk cf.cf_expr_unoptimized (self#write_texpr fctx);
 				Chunk.write_option chunk cf.cf_expr_unoptimized (self#write_texpr fctx);
 				let expr_chunk = close() in
 				let expr_chunk = close() in
 				Some expr_chunk *)
 				Some expr_chunk *)
 			| Some e ->
 			| Some e ->
 				IOChunk.write_u8 chunk.io 1;
 				IOChunk.write_u8 chunk.io 1;
-				let fctx,close = self#start_texpr e.epos in
+				let fctx,close = self#start_texpr true e.epos in
 				self#write_texpr fctx e;
 				self#write_texpr fctx e;
 				Chunk.write_option chunk cf.cf_expr_unoptimized (self#write_texpr fctx);
 				Chunk.write_option chunk cf.cf_expr_unoptimized (self#write_texpr fctx);
 				let expr_chunk = close() in
 				let expr_chunk = close() in
@@ -2021,10 +2031,11 @@ class hxb_writer
 					self#select_type c.cl_path;
 					self#select_type c.cl_path;
 				end;
 				end;
 
 
+				let c_expr_chunks = ref [] in
 				let write_field ref_kind cf =
 				let write_field ref_kind cf =
 					let l = self#write_class_field_and_overloads_data false cf in
 					let l = self#write_class_field_and_overloads_data false cf in
 					List.iter (fun (cf,e) ->
 					List.iter (fun (cf,e) ->
-						expr_chunks := (c,cf,ref_kind,e) :: !expr_chunks
+						c_expr_chunks := (cf,ref_kind,e) :: !c_expr_chunks
 					) l
 					) l
 				in
 				in
 
 
@@ -2032,16 +2043,20 @@ class hxb_writer
 				Chunk.write_list chunk c.cl_ordered_fields (write_field CfrMember);
 				Chunk.write_list chunk c.cl_ordered_fields (write_field CfrMember);
 				Chunk.write_list chunk c.cl_ordered_statics (write_field CfrStatic);
 				Chunk.write_list chunk c.cl_ordered_statics (write_field CfrStatic);
 				Chunk.write_option chunk c.cl_init (fun e ->
 				Chunk.write_option chunk c.cl_init (fun e ->
-					let fctx,close = self#start_texpr e.epos in
+					let fctx,close = self#start_texpr true e.epos in
 					self#write_texpr fctx e;
 					self#write_texpr fctx e;
 					let new_chunk = close() in
 					let new_chunk = close() in
 					Chunk.export_data new_chunk chunk
 					Chunk.export_data new_chunk chunk
 				);
 				);
+				expr_chunks := (c,!c_expr_chunks) :: !expr_chunks
 			);
 			);
 			self#start_chunk CFEX;
 			self#start_chunk CFEX;
-			Chunk.write_list chunk !expr_chunks (fun (c,cf,ref_kind,e) ->
-				self#write_field_ref c ref_kind cf;
-				Chunk.export_data e chunk
+			Chunk.write_list chunk !expr_chunks (fun (c,l) ->
+				self#write_class_ref c;
+				Chunk.write_list chunk l (fun (cf,ref_kind,e) ->
+					self#write_field_ref c ref_kind cf;
+					Chunk.export_data e chunk
+				)
 			)
 			)
 		end;
 		end;
 		begin match own_enums#to_list with
 		begin match own_enums#to_list with