Browse Source

Merge branch 'development' into java_vs_jvm

Rudy Ges 1 năm trước cách đây
mục cha
commit
495b4a4d9e

+ 3 - 3
src/compiler/args.ml

@@ -265,9 +265,9 @@ let parse_args com =
 		("Services",["--json"],[],Arg.String (fun file ->
 		("Services",["--json"],[],Arg.String (fun file ->
 			actx.json_out <- Some file
 			actx.json_out <- Some file
 		),"<file>","generate JSON types description");
 		),"<file>","generate JSON types description");
-		("Services",["--hxb"],[], Arg.String (fun dir ->
-			actx.hxb_out <- Some dir;
-		),"<directory>", "generate haxe binary representation in target directory");
+		("Services",["--hxb"],[], Arg.String (fun file ->
+			actx.hxb_out <- Some file;
+		),"<file>", "generate haxe binary representation to target archive");
 		("Optimization",["--no-output"],[], Arg.Unit (fun() -> actx.no_output <- true),"","compiles but does not generate any file");
 		("Optimization",["--no-output"],[], Arg.Unit (fun() -> actx.no_output <- true),"","compiles but does not generate any file");
 		("Debug",["--times"],[], Arg.Unit (fun() -> Timer.measure_times := true),"","measure compilation times");
 		("Debug",["--times"],[], Arg.Unit (fun() -> Timer.measure_times := true),"","measure compilation times");
 		("Optimization",["--no-inline"],[],Arg.Unit (fun () ->
 		("Optimization",["--no-inline"],[],Arg.Unit (fun () ->

+ 2 - 2
src/compiler/compilationCache.ml

@@ -69,12 +69,12 @@ class context_cache (index : int) (sign : Digest.t) = object(self)
 	method find_module_extra path =
 	method find_module_extra path =
 		try (Hashtbl.find modules path).m_extra with Not_found -> (Hashtbl.find binary_cache path).mc_extra
 		try (Hashtbl.find modules path).m_extra with Not_found -> (Hashtbl.find binary_cache path).mc_extra
 
 
-	method cache_module warn anon_identification hxb_writer_stats path m =
+	method cache_module config warn anon_identification hxb_writer_stats path m =
 		match m.m_extra.m_kind with
 		match m.m_extra.m_kind with
 		| MImport ->
 		| MImport ->
 			Hashtbl.add modules m.m_path m
 			Hashtbl.add modules m.m_path m
 		| _ ->
 		| _ ->
-			let writer = HxbWriter.create warn anon_identification hxb_writer_stats in
+			let writer = HxbWriter.create config warn anon_identification hxb_writer_stats in
 			HxbWriter.write_module writer m;
 			HxbWriter.write_module writer m;
 			let chunks = HxbWriter.get_chunks writer in
 			let chunks = HxbWriter.get_chunks writer in
 			Hashtbl.replace binary_cache path {
 			Hashtbl.replace binary_cache path {

+ 11 - 1
src/compiler/compiler.ml

@@ -363,6 +363,12 @@ let compile ctx actx callbacks =
 	callbacks.after_target_init ctx;
 	callbacks.after_target_init ctx;
 	let t = Timer.timer ["init"] in
 	let t = Timer.timer ["init"] in
 	List.iter (fun f -> f()) (List.rev (actx.pre_compilation));
 	List.iter (fun f -> f()) (List.rev (actx.pre_compilation));
+	begin match actx.hxb_out with
+		| None ->
+			()
+		| Some file ->
+			com.hxb_writer_config <- HxbWriterConfig.process_argument file
+	end;
 	t();
 	t();
 	enter_stage com CInitialized;
 	enter_stage com CInitialized;
 	ServerMessage.compiler_stage com;
 	ServerMessage.compiler_stage com;
@@ -376,7 +382,11 @@ let compile ctx actx callbacks =
 		let is_compilation = is_compilation com in
 		let is_compilation = is_compilation com in
 		com.callbacks#add_after_save (fun () ->
 		com.callbacks#add_after_save (fun () ->
 			callbacks.after_save ctx;
 			callbacks.after_save ctx;
-			if is_compilation then Generate.check_hxb_output ctx actx;
+			if is_compilation then match com.hxb_writer_config with
+				| Some config ->
+					Generate.check_hxb_output ctx config;
+				| None ->
+					()
 		);
 		);
 		if is_diagnostics com then
 		if is_diagnostics com then
 			filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)
 			filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)

+ 26 - 17
src/compiler/generate.ml

@@ -21,7 +21,7 @@ let check_auxiliary_output com actx =
 			Genjson.generate com.types file
 			Genjson.generate com.types file
 	end
 	end
 
 
-let export_hxb com cc platform zip m =
+let export_hxb com config cc platform zip m =
 	let open HxbData in
 	let open HxbData in
 	match m.m_extra.m_kind with
 	match m.m_extra.m_kind with
 		| MCode | MMacro | MFake | MExtern -> begin
 		| MCode | MMacro | MFake | MExtern -> begin
@@ -42,7 +42,7 @@ let export_hxb com cc platform zip m =
 			with Not_found ->
 			with Not_found ->
 				let anon_identification = new tanon_identification in
 				let anon_identification = new tanon_identification in
 				let warn w s p = com.Common.warning w com.warning_options s p in
 				let warn w s p = com.Common.warning w com.warning_options s p in
-				let writer = HxbWriter.create warn anon_identification com.hxb_writer_stats in
+				let writer = HxbWriter.create config warn anon_identification com.hxb_writer_stats in
 				HxbWriter.write_module writer m;
 				HxbWriter.write_module writer m;
 				let out = IO.output_string () in
 				let out = IO.output_string () in
 				HxbWriter.export writer out;
 				HxbWriter.export writer out;
@@ -51,37 +51,46 @@ let export_hxb com cc platform zip m =
 	| _ ->
 	| _ ->
 		()
 		()
 
 
-let check_hxb_output ctx actx =
+let check_hxb_output ctx config =
+	let open HxbWriterConfig in
 	let com = ctx.com in
 	let com = ctx.com in
-	let try_write path =
+	let match_path_list l sl_path =
+		List.exists (fun sl -> Ast.match_path true sl_path sl) l
+	in
+	let try_write () =
+		let path = config.HxbWriterConfig.archive_path in
+		let path = Str.global_replace (Str.regexp "\\$target") (platform_name ctx.com.platform) path in
 		let t = Timer.timer ["generate";"hxb"] in
 		let t = Timer.timer ["generate";"hxb"] in
 		Path.mkdir_from_path path;
 		Path.mkdir_from_path path;
 		let zip = new Zip_output.zip_output path 6 in
 		let zip = new Zip_output.zip_output path 6 in
-		let export com =
+		let export com config =
 			let cc = CommonCache.get_cache com in
 			let cc = CommonCache.get_cache com in
 			let target = Common.platform_name_macro com in
 			let target = Common.platform_name_macro com in
 			List.iter (fun m ->
 			List.iter (fun m ->
 				let t = Timer.timer ["generate";"hxb";s_type_path m.m_path] in
 				let t = Timer.timer ["generate";"hxb";s_type_path m.m_path] in
-				Std.finally t (export_hxb com cc target zip) m
+				let sl_path = fst m.m_path @ [snd m.m_path] in
+				if not (match_path_list config.exclude sl_path) || match_path_list config.include' sl_path then
+					Std.finally t (export_hxb com config cc target zip) m
 			) com.modules;
 			) com.modules;
 		in
 		in
 		Std.finally (fun () ->
 		Std.finally (fun () ->
 			zip#close;
 			zip#close;
 			t()
 			t()
 		) (fun () ->
 		) (fun () ->
-			export com;
-			Option.may export (com.get_macros());
+			if  config.target_config.generate then
+				export com config.target_config;
+			begin match com.get_macros() with
+				| Some mcom when config.macro_config.generate ->
+					export mcom config.macro_config
+				| _ ->
+					()
+			end;
 		) ()
 		) ()
 	in
 	in
-	begin match actx.hxb_out with
-		| None ->
-			()
-		| Some path ->
-			try
-				try_write path
-			with Sys_error s ->
-				error ctx (Printf.sprintf "Could not write to %s: %s" path s) null_pos
-	end
+	try
+		try_write ()
+	with Sys_error s ->
+		CompilationContext.error ctx (Printf.sprintf "Could not write to %s: %s" config.archive_path s) null_pos
 
 
 let parse_swf_header ctx h = match ExtString.String.nsplit h ":" with
 let parse_swf_header ctx h = match ExtString.String.nsplit h ":" with
 		| [width; height; fps] ->
 		| [width; height; fps] ->

+ 19 - 12
src/compiler/hxb/hxbWriter.ml

@@ -511,6 +511,7 @@ let create_field_writer_context pos_writer = {
 }
 }
 
 
 type hxb_writer = {
 type hxb_writer = {
+	config : HxbWriterConfig.writer_target_config;
 	warn : Warning.warning -> string -> Globals.pos -> unit;
 	warn : Warning.warning -> string -> Globals.pos -> unit;
 	anon_id : Type.t Tanon_identification.tanon_identification;
 	anon_id : Type.t Tanon_identification.tanon_identification;
 	stats : hxb_writer_stats;
 	stats : hxb_writer_stats;
@@ -601,13 +602,18 @@ module HxbWriter = struct
 		Chunk.write_string writer.chunk mname;
 		Chunk.write_string writer.chunk mname;
 		Chunk.write_string writer.chunk tname
 		Chunk.write_string writer.chunk tname
 
 
-	let write_documentation writer (doc : doc_block) =
-		Chunk.write_option writer.chunk doc.doc_own (fun s ->
-			Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s)
-		);
-		Chunk.write_list writer.chunk doc.doc_inherited (fun s ->
-			Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s)
-		)
+	let maybe_write_documentation writer (doc : doc_block option) =
+		match doc with
+		| Some doc when writer.config.generate_docs ->
+			Chunk.write_u8 writer.chunk 1;
+			Chunk.write_option writer.chunk doc.doc_own (fun s ->
+				Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s)
+			);
+			Chunk.write_list writer.chunk doc.doc_inherited (fun s ->
+				Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s)
+			)
+		| _ ->
+			Chunk.write_u8 writer.chunk 0
 
 
 	let write_pos writer (p : pos) =
 	let write_pos writer (p : pos) =
 		Chunk.write_string writer.chunk p.pfile;
 		Chunk.write_string writer.chunk p.pfile;
@@ -753,7 +759,7 @@ module HxbWriter = struct
 
 
 	and write_cfield writer cff =
 	and write_cfield writer cff =
 		write_placed_name writer cff.cff_name;
 		write_placed_name writer cff.cff_name;
-		Chunk.write_option writer.chunk cff.cff_doc (write_documentation writer);
+		maybe_write_documentation writer cff.cff_doc;
 		write_pos writer cff.cff_pos;
 		write_pos writer cff.cff_pos;
 		write_metadata writer cff.cff_meta;
 		write_metadata writer cff.cff_meta;
 		Chunk.write_list writer.chunk cff.cff_access (write_placed_access writer);
 		Chunk.write_list writer.chunk cff.cff_access (write_placed_access writer);
@@ -1829,7 +1835,7 @@ module HxbWriter = struct
 		let restore = start_temporary_chunk writer 512 in
 		let restore = start_temporary_chunk writer 512 in
 		write_type_instance writer cf.cf_type;
 		write_type_instance writer cf.cf_type;
 		Chunk.write_uleb128 writer.chunk cf.cf_flags;
 		Chunk.write_uleb128 writer.chunk cf.cf_flags;
-		Chunk.write_option writer.chunk cf.cf_doc (write_documentation writer);
+		maybe_write_documentation writer cf.cf_doc;
 		write_metadata writer cf.cf_meta;
 		write_metadata writer cf.cf_meta;
 		write_field_kind writer cf.cf_kind;
 		write_field_kind writer cf.cf_kind;
 		let expr_chunk = match cf.cf_expr with
 		let expr_chunk = match cf.cf_expr with
@@ -1876,7 +1882,7 @@ module HxbWriter = struct
 
 
 	let write_common_module_type writer (infos : tinfos) : unit =
 	let write_common_module_type writer (infos : tinfos) : unit =
 		Chunk.write_bool writer.chunk infos.mt_private;
 		Chunk.write_bool writer.chunk infos.mt_private;
-		Chunk.write_option writer.chunk infos.mt_doc (write_documentation writer);
+		maybe_write_documentation writer infos.mt_doc;
 		write_metadata writer infos.mt_meta;
 		write_metadata writer infos.mt_meta;
 		write_type_parameters_data writer infos.mt_params;
 		write_type_parameters_data writer infos.mt_params;
 		Chunk.write_list writer.chunk infos.mt_using (fun (c,p) ->
 		Chunk.write_list writer.chunk infos.mt_using (fun (c,p) ->
@@ -2141,7 +2147,7 @@ module HxbWriter = struct
 					let t_bytes = restore (fun new_chunk -> Chunk.get_bytes new_chunk) in
 					let t_bytes = restore (fun new_chunk -> Chunk.get_bytes new_chunk) in
 					commit_field_type_parameters writer ef.ef_params;
 					commit_field_type_parameters writer ef.ef_params;
 					Chunk.write_bytes writer.chunk t_bytes;
 					Chunk.write_bytes writer.chunk t_bytes;
-					Chunk.write_option writer.chunk ef.ef_doc (write_documentation writer);
+					maybe_write_documentation writer ef.ef_doc;
 					write_metadata writer ef.ef_meta;
 					write_metadata writer ef.ef_meta;
 					close();
 					close();
 				);
 				);
@@ -2281,9 +2287,10 @@ module HxbWriter = struct
 		l
 		l
 end
 end
 
 
-let create warn anon_id stats =
+let create config warn anon_id stats =
 	let cp = StringPool.create () in
 	let cp = StringPool.create () in
 	{
 	{
+		config;
 		warn;
 		warn;
 		anon_id;
 		anon_id;
 		stats;
 		stats;

+ 118 - 0
src/compiler/hxb/hxbWriterConfig.ml

@@ -0,0 +1,118 @@
+open Globals
+open Json.Reader
+
+type writer_target_config = {
+	mutable generate : bool;
+	mutable exclude : string list list;
+	mutable include' : string list list;
+	mutable hxb_version : int;
+	mutable generate_docs : bool;
+}
+
+type t = {
+	mutable archive_path : string;
+	target_config : writer_target_config;
+	macro_config : writer_target_config;
+}
+
+let create_target_config () = {
+	generate = true;
+	exclude = [];
+	include'= [];
+	hxb_version = HxbData.hxb_version;
+	generate_docs = true;
+}
+
+let create () = {
+	archive_path = "";
+	target_config = create_target_config ();
+	macro_config = create_target_config ()
+}
+let error s =
+	Error.raise_typing_error s null_pos
+
+module WriterConfigReader (API : DataReaderApi.DataReaderApi) = struct
+	let read_target_config config fl =
+		List.iter (fun (s,data) -> match s with
+			| "generate" ->
+				config.generate <- API.read_bool data;
+			| "exclude" ->
+				API.read_optional data (fun data ->
+					let l = API.read_array data in
+					config.exclude <- List.map (fun data -> ExtString.String.nsplit (API.read_string data) ".") l
+				)
+			| "include" ->
+				API.read_optional data (fun data ->
+					let l = API.read_array data in
+					config.include'<- List.map (fun data -> ExtString.String.nsplit (API.read_string data) ".") l
+				)
+			| "hxbVersion" ->
+				config.hxb_version <- API.read_int data
+			| "generateDocumentation" ->
+				config.generate_docs <- API.read_bool data
+			| s ->
+				error (Printf.sprintf "Unknown key for target config: %s" s)
+		) fl
+
+	let read_writer_config config data =
+		let read data =
+			let fl = API.read_object data in
+			List.iter (fun (s,data) ->
+				match s with
+				| "archivePath" ->
+					config.archive_path <- API.read_string data;
+				| "targetConfig" ->
+					API.read_optional data (fun data -> read_target_config config.target_config (API.read_object data))
+				| "macroConfig" ->
+					API.read_optional data (fun data -> read_target_config config.macro_config (API.read_object data))
+				| s ->
+					error (Printf.sprintf "Unknown key for writer config: %s" s)
+			) fl
+		in
+		API.read_optional data read
+end
+
+module WriterConfigReaderJson = WriterConfigReader(JsonDataApi.JsonReaderApi)
+
+module WriterConfigWriter (API : DataWriterApi.DataWriterApi) = struct
+	let write_target_config config =
+		API.write_object [
+			"generate",API.write_bool config.generate;
+			"exclude",API.write_array (List.map (fun sl -> API.write_string (String.concat "." sl)) config.exclude);
+			"include",API.write_array (List.map (fun sl -> API.write_string (String.concat "." sl)) config.include');
+			"hxbVersion",API.write_int config.hxb_version;
+			"generateDocumentation",API.write_bool config.generate_docs;
+		]
+
+	let write_writer_config config =
+		API.write_object [
+			"archivePath",API.write_string config.archive_path;
+			"targetConfig",write_target_config config.target_config;
+			"macroConfig",write_target_config config.macro_config;
+		]
+end
+
+let process_json config json =
+	WriterConfigReaderJson.read_writer_config config json
+
+let parse config input =
+	let lexbuf = Sedlexing.Utf8.from_string input in
+	let json = read_json lexbuf in
+	process_json config json
+
+let process_argument file =
+	let config = create () in
+	begin match Path.file_extension file with
+		| "json" ->
+			let file = try
+				open_in file
+			with exc ->
+				error (Printf.sprintf "Could not open file %s: %s" file (Printexc.to_string exc))
+			in
+			let data = Std.input_all file in
+			close_in file;
+			parse config data;
+		| _ ->
+			config.archive_path <- file;
+	end;
+	Some config

+ 2 - 0
src/context/common.ml

@@ -420,6 +420,7 @@ type context = {
 	memory_marker : float array;
 	memory_marker : float array;
 	hxb_reader_stats : HxbReader.hxb_reader_stats;
 	hxb_reader_stats : HxbReader.hxb_reader_stats;
 	hxb_writer_stats : HxbWriter.hxb_writer_stats;
 	hxb_writer_stats : HxbWriter.hxb_writer_stats;
+	mutable hxb_writer_config : HxbWriterConfig.t option;
 }
 }
 
 
 let enter_stage com stage =
 let enter_stage com stage =
@@ -844,6 +845,7 @@ let create compilation_step cs version args display_mode =
 		is_macro_context = false;
 		is_macro_context = false;
 		hxb_reader_stats = HxbReader.create_hxb_reader_stats ();
 		hxb_reader_stats = HxbReader.create_hxb_reader_stats ();
 		hxb_writer_stats = HxbWriter.create_hxb_writer_stats ();
 		hxb_writer_stats = HxbWriter.create_hxb_writer_stats ();
+		hxb_writer_config = None;
 	} in
 	} in
 	com
 	com
 
 

+ 7 - 1
src/context/commonCache.ml

@@ -85,11 +85,17 @@ let rec cache_context cs com =
 	let cc = get_cache com in
 	let cc = get_cache com in
 	let sign = Define.get_signature com.defines in
 	let sign = Define.get_signature com.defines in
 	let anon_identification = new Tanon_identification.tanon_identification in
 	let anon_identification = new Tanon_identification.tanon_identification in
+	let config = match com.hxb_writer_config with
+		| None ->
+			HxbWriterConfig.create_target_config ()
+		| Some config ->
+			if com.is_macro_context then config.macro_config else config.target_config
+	in
 	let cache_module m =
 	let cache_module m =
 		(* If we have a signature mismatch, look-up cache for module. Physical equality check is fine as a heueristic. *)
 		(* If we have a signature mismatch, look-up cache for module. Physical equality check is fine as a heueristic. *)
 		let cc = if m.m_extra.m_sign = sign then cc else cs#get_context m.m_extra.m_sign in
 		let cc = if m.m_extra.m_sign = sign then cc else cs#get_context m.m_extra.m_sign in
 		let warn w s p = com.warning w com.warning_options s p in
 		let warn w s p = com.warning w com.warning_options s p in
-		cc#cache_module warn anon_identification com.hxb_writer_stats m.m_path m;
+		cc#cache_module config warn anon_identification com.hxb_writer_stats m.m_path m;
 	in
 	in
 	List.iter cache_module com.modules;
 	List.iter cache_module com.modules;
 	begin match com.get_macros() with
 	begin match com.get_macros() with

+ 17 - 0
src/core/data/dataReaderApi.ml

@@ -0,0 +1,17 @@
+module type DataReaderApi = sig
+	type data
+
+	val read_optional : data -> (data -> unit) -> unit
+
+	val read_object : data -> (string * data) list
+
+	val read_array : data -> data list
+
+	val read_string : data -> string
+
+	val read_bool : data -> bool
+
+	val read_int : data -> int
+
+	val data_to_string : data -> string
+end

+ 15 - 0
src/core/data/dataWriterApi.ml

@@ -0,0 +1,15 @@
+module type DataWriterApi = sig
+	type data
+
+	val write_optional : data option -> data
+
+	val write_object : (string * data) list -> data
+
+	val write_array : data list -> data
+
+	val write_string : string -> data
+
+	val write_bool : bool -> data
+
+	val write_int : int -> data
+end

+ 48 - 0
src/core/data/jsonDataApi.ml

@@ -0,0 +1,48 @@
+open Json
+
+let error s =
+	(* TODO: should this raise something else? *)
+	Error.raise_typing_error s Globals.null_pos
+
+module JsonReaderApi = struct
+	type data = Json.t
+
+	let read_optional json f = match json with
+		| JNull ->
+			()
+		| _ ->
+			f json
+
+	let read_object json = match json with
+		| JObject fl ->
+			fl
+		| _ ->
+			error (Printf.sprintf "Expected JObject, found %s" (string_of_json json))
+
+	let read_array json = match json with
+		| JArray l ->
+			l
+		| _ ->
+			error (Printf.sprintf "Expected JArray, found %s" (string_of_json json))
+
+	let read_string json = match json with
+		| JString s ->
+			s
+		| _ ->
+			error (Printf.sprintf "Expected JString, found %s" (string_of_json json))
+
+	let read_int json = match json with
+		| JInt i ->
+			i
+		| _ ->
+			error (Printf.sprintf "Expected JInt, found %s" (string_of_json json))
+
+	let read_bool json = match json with
+		| JBool b ->
+			b
+		| _ ->
+			error (Printf.sprintf "Expected JBool, found %s" (string_of_json json))
+
+	let data_to_string json =
+		string_of_json json
+end

+ 11 - 1
src/generators/genjvm.ml

@@ -2392,6 +2392,7 @@ class tclass_to_jvm gctx c = object(self)
 		let jsig_empty = method_sig [haxe_empty_constructor_sig] None in
 		let jsig_empty = method_sig [haxe_empty_constructor_sig] None in
 		let jm_empty_ctor = jc#spawn_method "<init>" jsig_empty [MPublic;MSynthetic] in
 		let jm_empty_ctor = jc#spawn_method "<init>" jsig_empty [MPublic;MSynthetic] in
 		let _,load,_ = jm_empty_ctor#add_local "_" haxe_empty_constructor_sig VarArgument in
 		let _,load,_ = jm_empty_ctor#add_local "_" haxe_empty_constructor_sig VarArgument in
+		jm_empty_ctor#finalize_arguments;
 		jm_empty_ctor#load_this;
 		jm_empty_ctor#load_this;
 		if c.cl_constructor = None then begin
 		if c.cl_constructor = None then begin
 			let handler = new texpr_to_jvm gctx None jc jm_empty_ctor None in
 			let handler = new texpr_to_jvm gctx None jc jm_empty_ctor None in
@@ -2432,6 +2433,7 @@ class tclass_to_jvm gctx c = object(self)
 					let _,load,_ = jm#add_local n (jsignature_of_type gctx t) VarArgument in
 					let _,load,_ = jm#add_local n (jsignature_of_type gctx t) VarArgument in
 					load();
 					load();
 				) tl;
 				) tl;
+				jm#finalize_arguments;
 				jm#call_super_ctor cmode jm#get_jsig;
 				jm#call_super_ctor cmode jm#get_jsig;
 				DynArray.iter (fun e ->
 				DynArray.iter (fun e ->
 					handler#texpr RVoid e;
 					handler#texpr RVoid e;
@@ -2548,7 +2550,15 @@ class tclass_to_jvm gctx c = object(self)
 				let ethis = mk (TConst TThis) (TInst(c,tl)) null_pos in
 				let ethis = mk (TConst TThis) (TInst(c,tl)) null_pos in
 				let efield = mk (TField(ethis,FInstance(c,tl,cf))) cf.cf_type null_pos in
 				let efield = mk (TField(ethis,FInstance(c,tl,cf))) cf.cf_type null_pos in
 				let eop = mk (TBinop(OpAssign,efield,e)) cf.cf_type null_pos in
 				let eop = mk (TBinop(OpAssign,efield,e)) cf.cf_type null_pos in
-				DynArray.add (match cf.cf_kind with Method MethDynamic -> delayed_field_inits | _ -> field_inits) eop;
+				begin match cf.cf_kind with
+					| Method MethDynamic ->
+						let enull = Texpr.Builder.make_null efield.etype null_pos in
+						let echeck = Texpr.Builder.binop OpEq efield enull gctx.com.basic.tbool null_pos in
+						let eif = mk (TIf(echeck,eop,None)) gctx.com.basic.tvoid null_pos in
+						DynArray.add delayed_field_inits eif
+					| _ ->
+						DynArray.add field_inits eop
+				end
 			| Some e ->
 			| Some e ->
 				match e.eexpr with
 				match e.eexpr with
 				| TConst ct ->
 				| TConst ct ->

+ 61 - 0
src/macro/eval/evalDataApi.ml

@@ -0,0 +1,61 @@
+open EvalValue
+open EvalContext
+
+module EvalReaderApi = struct
+	open EvalDecode
+
+	type data = value
+
+	let read_optional v f = match v with
+		| VNull ->
+			()
+		| _ ->
+			f v
+
+	let read_object v =
+		List.map (fun (i,v) ->
+			EvalHash.rev_hash i,v
+		) (object_fields (decode_object v))
+
+	let read_array v =
+		EvalArray.to_list (decode_varray v)
+
+	let read_string v =
+		decode_string v
+
+	let read_int v =
+		decode_int v
+
+	let read_bool v =
+		decode_bool v
+
+	let data_to_string v =
+		(EvalPrinting.s_value 0 v).sstring
+end
+
+module EvalWriterApi = struct
+	open EvalEncode
+
+	type data = value
+
+	let write_optional vo = match vo with
+		| None -> vnull
+		| Some v -> v
+
+	let write_object fl =
+		encode_obj (List.map (fun (s,v) ->
+			EvalHash.hash s,v
+		) fl)
+
+	let write_array vl =
+		encode_array vl
+
+	let write_string s =
+		encode_string s
+
+	let write_bool b =
+		vbool b
+
+	let write_int i =
+		vint i
+end

+ 9 - 0
src/macro/macroApi.ml

@@ -70,6 +70,8 @@ type 'value compiler_api = {
 	with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a;
 	with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a;
 	with_options : 'a . compiler_options -> (unit -> 'a) -> 'a;
 	with_options : 'a . compiler_options -> (unit -> 'a) -> 'a;
 	exc_string : 'a . string -> 'a;
 	exc_string : 'a . string -> 'a;
+	get_hxb_writer_config : unit -> 'value;
+	set_hxb_writer_config : 'value -> unit;
 }
 }
 
 
 
 
@@ -2394,5 +2396,12 @@ let macro_api ccom get_api =
 				vbool false
 				vbool false
 			end
 			end
 		);
 		);
+		"get_hxb_writer_config", vfun0 (fun () ->
+			(get_api()).get_hxb_writer_config ()
+		);
+		"set_hxb_writer_config", vfun1 (fun v ->
+			(get_api()).set_hxb_writer_config v;
+			vnull
+		)
 	]
 	]
 end
 end

+ 26 - 0
src/typing/macroContext.ml

@@ -34,6 +34,10 @@ module Interp = struct
 	include BuiltApi
 	include BuiltApi
 end
 end
 
 
+
+module HxbWriterConfigReaderEval = HxbWriterConfig.WriterConfigReader(EvalDataApi.EvalReaderApi)
+module HxbWriterConfigWriterEval = HxbWriterConfig.WriterConfigWriter(EvalDataApi.EvalWriterApi)
+
 let macro_interp_cache = ref None
 let macro_interp_cache = ref None
 
 
 let safe_decode com v expected t p f =
 let safe_decode com v expected t p f =
@@ -305,6 +309,28 @@ let make_macro_com_api com mcom p =
 			com.warning ~depth w [] msg p
 			com.warning ~depth w [] msg p
 		);
 		);
 		exc_string = Interp.exc_string;
 		exc_string = Interp.exc_string;
+		get_hxb_writer_config = (fun () ->
+			match com.hxb_writer_config with
+			| Some config ->
+				HxbWriterConfigWriterEval.write_writer_config config
+			| None ->
+				VNull
+		);
+		set_hxb_writer_config = (fun v ->
+			if v == VNull then
+				com.hxb_writer_config <- None
+			else begin
+				let config = match com.hxb_writer_config with
+					| Some config ->
+						config
+					| None ->
+						let config = HxbWriterConfig.create () in
+						com.hxb_writer_config <- Some config;
+						config
+				in
+				HxbWriterConfigReaderEval.read_writer_config config v
+			end
+		);
 	}
 	}
 
 
 let make_macro_api ctx mctx p =
 let make_macro_api ctx mctx p =

+ 3 - 6
src/typing/typeloadModule.ml

@@ -813,12 +813,9 @@ let rec load_hxb_module ctx path p =
 			let api = (new hxb_reader_api_typeload ctx load_module' p :> HxbReaderApi.hxb_reader_api) in
 			let api = (new hxb_reader_api_typeload ctx load_module' p :> HxbReaderApi.hxb_reader_api) in
 			let reader = new HxbReader.hxb_reader path ctx.com.hxb_reader_stats in
 			let reader = new HxbReader.hxb_reader path ctx.com.hxb_reader_stats in
 			let read = reader#read api bytes in
 			let read = reader#read api bytes in
-			let m = read MTF in
-			delay ctx PBuildClass (fun () ->
-				ignore(read EOT);
-				delay ctx PConnectField (fun () ->
-					ignore(read EOM);
-				);
+			let m = read EOT in
+			delay ctx PConnectField (fun () ->
+				ignore(read EOM);
 			);
 			);
 			m
 			m
 		with e ->
 		with e ->

+ 51 - 0
std/haxe/hxb/WriterConfig.hx

@@ -0,0 +1,51 @@
+package haxe.hxb;
+
+typedef WriterTargetConfig = {
+	/**
+		If `false`, this target is ignored by the writer.
+	**/
+	var ?generate:Null<Bool>;
+
+	/**
+		Dot paths of modules or packages to be exluded from the archive.
+	**/
+	var ?exclude:Null<Array<String>>;
+
+	/**
+		Dot paths of modules or packages to be included in the archive. This takes priority
+		over exclude. By default, all modules that aren't explicitly excluded are
+		included.
+	**/
+	var ?include:Null<Array<String>>;
+
+	/**
+		The hxb version to target. By default, the version of the Haxe compiler itself
+		is targeted. See https://github.com/HaxeFoundation/haxe/issues/11505
+	**/
+	var ?hxbVersion:Null<Int>;
+
+	/**
+		If false, no documentation
+	**/
+	var ?generateDocumentation:Null<Bool>;
+}
+
+typedef WriterConfig = {
+	/**
+		The file path for the archive. Occurrences of `$target` are replaced
+		by the name of the current target (js, hl, etc.).
+	**/
+	var archivePath:String;
+
+	/**
+		The configuration for the current target context. If it is `null`, all data
+		for the target context is generated.
+	**/
+	var ?targetConfig:Null<WriterTargetConfig>;
+
+	/**
+		The configuration for the macro context. If it is `null`, all data for the
+		macro context is generated.
+	**/
+	var ?macroConfig:Null<WriterTargetConfig>;
+}

+ 35 - 0
std/haxe/macro/Compiler.hx

@@ -24,6 +24,7 @@ package haxe.macro;
 
 
 import haxe.display.Display;
 import haxe.display.Display;
 import haxe.macro.Expr;
 import haxe.macro.Expr;
+import haxe.hxb.WriterConfig;
 
 
 /**
 /**
 	All these methods can be called for compiler configuration macros.
 	All these methods can be called for compiler configuration macros.
@@ -567,6 +568,40 @@ class Compiler {
 		}
 		}
 	}
 	}
 	#end
 	#end
+
+	/**
+		Gets the current hxb writer configuration, if any.
+	**/
+	static public function getHxbWriterConfiguration():Null<WriterConfig> {
+		#if macro
+		return load("get_hxb_writer_config", 0)();
+		#else
+		return null;
+		#end
+	}
+
+	/**
+		Sets the hxb writer configuration to `config`. If no hxb writer configuration
+		exists, it is created.
+
+		The intended usage is
+
+		```
+		var config = Compiler.getHxbWriterConfiguration();
+		config.archivePath = "newPath.zip";
+		// Other changes
+		Compiler.setHxbWriterConfiguration(config);
+		```
+
+		If `config` is `null`, hxb writing is disabled.
+
+		@see haxe.hxb.WriterConfig
+	**/
+	static public function setHxbWriterConfiguration(config:Null<WriterConfig>) {
+		#if macro
+		load("set_hxb_writer_config", 1)(config);
+		#end
+	}
 }
 }
 
 
 enum abstract IncludePosition(String) from String to String {
 enum abstract IncludePosition(String) from String to String {

+ 1 - 1
tests/misc/projects/Issue10844/user-defined-define-json-fail.hxml.stderr

@@ -1,3 +1,3 @@
 (unknown) : Uncaught exception Could not read file define.jsno
 (unknown) : Uncaught exception Could not read file define.jsno
-$$normPath(::std::)/haxe/macro/Compiler.hx:496: characters 11-39 : Called from here
+$$normPath(::std::)/haxe/macro/Compiler.hx:506: characters 11-39 : Called from here
 (unknown) : Called from here
 (unknown) : Called from here

+ 1 - 1
tests/misc/projects/Issue10844/user-defined-meta-json-fail.hxml.stderr

@@ -1,3 +1,3 @@
 (unknown) : Uncaught exception Could not read file meta.jsno
 (unknown) : Uncaught exception Could not read file meta.jsno
-$$normPath(::std::)/haxe/macro/Compiler.hx:485: characters 11-39 : Called from here
+$$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 : Called from here
 (unknown) : Called from here
 (unknown) : Called from here

+ 1 - 1
tests/misc/projects/Issue10844/user-defined-meta-json-indent-fail.hxml.stderr

@@ -1,3 +1,3 @@
 (unknown) : Uncaught exception Could not read file meta.jsno
 (unknown) : Uncaught exception Could not read file meta.jsno
-  $$normPath(::std::)/haxe/macro/Compiler.hx:485: characters 11-39 : Called from here
+  $$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 : Called from here
   (unknown) : Called from here
   (unknown) : Called from here

+ 2 - 2
tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr

@@ -2,9 +2,9 @@
 
 
    | Uncaught exception Could not read file meta.jsno
    | Uncaught exception Could not read file meta.jsno
 
 
-    ->  $$normPath(::std::)/haxe/macro/Compiler.hx:485: characters 11-39
+    ->  $$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39
 
 
-    485 |   var f = sys.io.File.getContent(path);
+    495 |   var f = sys.io.File.getContent(path);
         |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         | Called from here
         | Called from here
 
 

+ 2 - 2
tests/unit/compile-hxb-jvm-roundtrip.hxml

@@ -1,7 +1,7 @@
 compile-jvm-only.hxml
 compile-jvm-only.hxml
---hxb bin/hxb/jvm.zip
+--hxb hxb-config/jvm.json
 
 
 --next
 --next
 
 
 compile-jvm-only.hxml
 compile-jvm-only.hxml
---hxb-lib bin/hxb/jvm.zip
+--hxb-lib bin/hxb/unit.java.zip

+ 10 - 0
tests/unit/hxb-config/jvm.json

@@ -0,0 +1,10 @@
+{
+	"archivePath": "bin/hxb/unit.$target.zip",
+	"targetConfig": {
+		"exclude": ["unit.TestMainNow"],
+		"generateDocumentation": false
+	},
+	"macroConfig": {
+		"generateDocumentation": false
+	}
+}

+ 1 - 3
tests/unit/src/unit/TestMain.hx

@@ -27,9 +27,7 @@ function main() {
 
 
 	var verbose = #if (cpp || neko || php) Sys.args().indexOf("-v") >= 0 #else false #end;
 	var verbose = #if (cpp || neko || php) Sys.args().indexOf("-v") >= 0 #else false #end;
 
 
-	#if !macro
-	trace("Generated at: " + HelperMacros.getCompilationDate());
-	#end
+	TestMainNow.printNow();
 	trace("START");
 	trace("START");
 	#if flash
 	#if flash
 	var tf:flash.text.TextField = untyped flash.Boot.getTrace();
 	var tf:flash.text.TextField = untyped flash.Boot.getTrace();

+ 9 - 0
tests/unit/src/unit/TestMainNow.hx

@@ -0,0 +1,9 @@
+package unit;
+
+class TestMainNow {
+	static public function printNow() {
+		#if !macro
+		trace("Generated at: " + HelperMacros.getCompilationDate());
+		#end
+	}
+}

+ 224 - 226
tests/unit/src/unit/TestMisc.hx

@@ -2,8 +2,7 @@ package unit;
 import unit.MyClass;
 import unit.MyClass;
 
 
 class MyDynamicClass {
 class MyDynamicClass {
-
-	var v : Int;
+	var v:Int;
 
 
 	public function new(v) {
 	public function new(v) {
 		this.v = v;
 		this.v = v;
@@ -13,74 +12,74 @@ class MyDynamicClass {
 		return v;
 		return v;
 	}
 	}
 
 
-	public dynamic function add(x,y) {
+	public dynamic function add(x, y) {
 		return v + x + y;
 		return v + x + y;
 	}
 	}
 
 
-	public inline function iadd(x,y) {
+	public inline function iadd(x, y) {
 		return v + x + y;
 		return v + x + y;
 	}
 	}
 
 
 	static var Z = 10;
 	static var Z = 10;
 
 
-	public dynamic static function staticDynamic(x,y) {
+	public dynamic static function staticDynamic(x, y) {
 		return Z + x + y;
 		return Z + x + y;
 	}
 	}
 
 
-	@:isVar public static var W(get, set) : Int = 55;
-	static function get_W() return W + 2;
-	static function set_W(v) { W = v; return v; }
+	@:isVar public static var W(get, set):Int = 55;
+
+	static function get_W()
+		return W + 2;
 
 
+	static function set_W(v) {
+		W = v;
+		return v;
+	}
 }
 }
 
 
 class MyDynamicSubClass extends MyDynamicClass {
 class MyDynamicSubClass extends MyDynamicClass {
-
-	override function add(x,y) {
+	override function add(x, y) {
 		return (v + x + y) * 2;
 		return (v + x + y) * 2;
 	}
 	}
-
 }
 }
 
 
 class MyDynamicSubClass2 extends MyDynamicClass {
 class MyDynamicSubClass2 extends MyDynamicClass {
-
-	override dynamic function add(x,y) {
+	override dynamic function add(x, y) {
 		return (v + x + y) * 2;
 		return (v + x + y) * 2;
 	}
 	}
-
 }
 }
 
 
 class MyOtherDynamicClass extends MyDynamicClass {
 class MyOtherDynamicClass extends MyDynamicClass {
-
 	public function new(v) {
 	public function new(v) {
-		add = function(x,y) return x + y + 10;
+		add = function(x, y) return x + y + 10;
 		super(v);
 		super(v);
 	}
 	}
-
 }
 }
 
 
 interface IDefArgs {
 interface IDefArgs {
-	public function get( x : Int = 5 ) : Int;
+	public function get(x:Int = 5):Int;
 }
 }
 
 
 class BaseDefArgs {
 class BaseDefArgs {
-	public function get( x = 3 ) {
+	public function get(x = 3) {
 		return x;
 		return x;
 	}
 	}
 }
 }
 
 
 class ExtDefArgs extends BaseDefArgs implements IDefArgs {
 class ExtDefArgs extends BaseDefArgs implements IDefArgs {
-	public function new() {
-	}
-	override function get( x = 7 ) {
+	public function new() {}
+
+	override function get(x = 7) {
 		return x;
 		return x;
 	}
 	}
 }
 }
 
 
 class BaseConstrOpt {
 class BaseConstrOpt {
-	public var s : String;
-	public var i : Int;
-	public var b : Bool;
-	public function new( s = "test", i = -5, b = true ) {
+	public var s:String;
+	public var i:Int;
+	public var b:Bool;
+
+	public function new(s = "test", i = -5, b = true) {
 		this.s = s;
 		this.s = s;
 		this.i = i;
 		this.i = i;
 		this.b = b;
 		this.b = b;
@@ -98,8 +97,8 @@ class SubConstrOpt2 extends BaseConstrOpt {
 }
 }
 
 
 class SubConstrOpt3 extends BaseConstrOpt {
 class SubConstrOpt3 extends BaseConstrOpt {
-	public function new( s = "test2", i = -6 ) {
-		super(s,i);
+	public function new(s = "test2", i = -6) {
+		super(s, i);
 	}
 	}
 }
 }
 
 
@@ -110,127 +109,125 @@ enum abstract MyEnumAbstract(Int) {
 }
 }
 
 
 class TestMisc extends Test {
 class TestMisc extends Test {
-
 	static var unit = "testing package conflict";
 	static var unit = "testing package conflict";
 
 
-	function testPackageConflict()
-	{
-		eq( unit, "testing package conflict" );
+	function testPackageConflict() {
+		eq(unit, "testing package conflict");
 		var unit = unit;
 		var unit = unit;
-		eq( unit, TestMisc.unit );
+		eq(unit, TestMisc.unit);
 	}
 	}
 
 
 	function testDate() {
 	function testDate() {
 		var d = new Date(2012, 7, 17, 1, 2, 3);
 		var d = new Date(2012, 7, 17, 1, 2, 3);
-		eq( d.getDay(), 5 );
+		eq(d.getDay(), 5);
 
 
-		eq( d.getDate(), 17 );
-		eq( d.getMonth(), 7 );
-		eq( d.getFullYear(), 2012 );
+		eq(d.getDate(), 17);
+		eq(d.getMonth(), 7);
+		eq(d.getFullYear(), 2012);
 
 
-		eq( d.getHours(), 1 );
-		eq( d.getMinutes(), 2 );
-		eq( d.getSeconds(), 3 );
+		eq(d.getHours(), 1);
+		eq(d.getMinutes(), 2);
+		eq(d.getSeconds(), 3);
 
 
-		//seems to be system-dependent?
-		//eq( d.getTime(), 1345158123000 );
-		eq( d.toString(), "2012-08-17 01:02:03" );
+		// seems to be system-dependent?
+		// eq( d.getTime(), 1345158123000 );
+		eq(d.toString(), "2012-08-17 01:02:03");
 	}
 	}
 
 
 	function testClosure() {
 	function testClosure() {
 		var c = new MyClass(100);
 		var c = new MyClass(100);
 		var add = c.add;
 		var add = c.add;
-		eq( c.add(1,2), 103 );
-		eq( c.add.bind(1)(2), 103 );
-		eq( add(1,2), 103 );
+		eq(c.add(1, 2), 103);
+		eq(c.add.bind(1)(2), 103);
+		eq(add(1, 2), 103);
 
 
 		var x = 4;
 		var x = 4;
 		var f = function() return x;
 		var f = function() return x;
-		eq( f(), 4 );
+		eq(f(), 4);
 		x++;
 		x++;
-		eq( f(), 5 );
+		eq(f(), 5);
 
 
-		var o = { f : f };
-		eq( o.f(), 5 );
-		eq( o.f, o.f ); // we shouldn't create a new closure here
+		var o = {f: f};
+		eq(o.f(), 5);
+		eq(o.f, o.f); // we shouldn't create a new closure here
 
 
-		var o = { add : c.add };
-		eq( o.add(1,2), 103 );
-		eq( o.add, o.add ); // we shouldn't create a new closure here
+		var o = {add: c.add};
+		eq(o.add(1, 2), 103);
+		eq(o.add, o.add); // we shouldn't create a new closure here
 
 
-		var o = { cos : Math.cos };
-		eq( o.cos(0), 1. );
+		var o = {cos: Math.cos};
+		eq(o.cos(0), 1.);
 
 
 		// check enum
 		// check enum
 		var c = MyEnum.C;
 		var c = MyEnum.C;
-		t( Type.enumEq(MyEnum.C(1,"hello"), c(1,"hello")) );
+		t(Type.enumEq(MyEnum.C(1, "hello"), c(1, "hello")));
 	}
 	}
 
 
 	// make sure that captured variables does not overlap each others even if in different scopes
 	// make sure that captured variables does not overlap each others even if in different scopes
 	function testCaptureUnique() {
 	function testCaptureUnique() {
 		var foo = null, bar = null;
 		var foo = null, bar = null;
 		var flag = true;
 		var flag = true;
-		if( flag ) {
+		if (flag) {
 			var x = 1;
 			var x = 1;
 			foo = function() return x;
 			foo = function() return x;
 		}
 		}
-		if( flag ) {
+		if (flag) {
 			var x = 2;
 			var x = 2;
 			bar = function() return x;
 			bar = function() return x;
 		}
 		}
-		eq( foo(), 1);
-		eq( bar(), 2);
+		eq(foo(), 1);
+		eq(bar(), 2);
 	}
 	}
 
 
 	function testCaptureUnique2() {
 	function testCaptureUnique2() {
 		// another more specialized test (was actually the original broken code - but not reproducible when optimization is off)
 		// another more specialized test (was actually the original broken code - but not reproducible when optimization is off)
 		var foo = id.bind(3);
 		var foo = id.bind(3);
 		var bar = sq.bind(5);
 		var bar = sq.bind(5);
-		eq( foo(), 3 );
-		eq( bar(), 25 );
+		eq(foo(), 3);
+		eq(bar(), 25);
 	}
 	}
 
 
 	function testSelfRef() {
 	function testSelfRef() {
 		// check for self-name binding
 		// check for self-name binding
 		var bla = 55;
 		var bla = 55;
 		var bla = function() return bla;
 		var bla = function() return bla;
-		eq( bla(), 55);
+		eq(bla(), 55);
 	}
 	}
 
 
 	function testHiddenType() {
 	function testHiddenType() {
 		var haxe = 20;
 		var haxe = 20;
-		eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
-		eq( haxe, 20);
+		eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
+		eq(haxe, 20);
 		var Std = 50;
 		var Std = 50;
-		eq( std.Std.int(45.3), 45);
-		eq( Std, 50);
+		eq(std.Std.int(45.3), 45);
+		eq(Std, 50);
 	}
 	}
 
 
 	function testHiddenTypeScope() {
 	function testHiddenTypeScope() {
 		var flag = true;
 		var flag = true;
-		if( flag ) {
+		if (flag) {
 			var haxe = 20;
 			var haxe = 20;
 			var Std = 50;
 			var Std = 50;
-			eq( haxe, 20);
-			eq( Std, 50);
+			eq(haxe, 20);
+			eq(Std, 50);
 		}
 		}
-		eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
-		eq( std.Std.int(45.3), 45);
+		eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
+		eq(std.Std.int(45.3), 45);
 	}
 	}
 
 
 	function testHiddenTypeCapture() {
 	function testHiddenTypeCapture() {
 		var flag = true;
 		var flag = true;
 		var foo = null, bar = null;
 		var foo = null, bar = null;
-		if( flag ) {
+		if (flag) {
 			var haxe = 20;
 			var haxe = 20;
 			var Std = 50;
 			var Std = 50;
 			foo = function() return haxe;
 			foo = function() return haxe;
 			bar = function() return Std;
 			bar = function() return Std;
 		}
 		}
-		eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
-		eq( std.Std.int(45.3), 45);
-		eq( foo(), 20);
-		eq( bar(), 50);
+		eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
+		eq(std.Std.int(45.3), 45);
+		eq(foo(), 20);
+		eq(bar(), 50);
 	}
 	}
 
 
 	function id<T>(x:T) {
 	function id<T>(x:T) {
@@ -248,80 +245,81 @@ class TestMisc extends Test {
 	function testInlineClosure() {
 	function testInlineClosure() {
 		var inst = new MyDynamicClass(100);
 		var inst = new MyDynamicClass(100);
 		var add = inst.iadd;
 		var add = inst.iadd;
-		eq( inst.iadd(1,2), 103 );
-		eq( add(1,2), 103 );
+		eq(inst.iadd(1, 2), 103);
+		eq(add(1, 2), 103);
 	}
 	}
 
 
 	function testDynamicClosure() {
 	function testDynamicClosure() {
 		var inst = new MyDynamicClass(100);
 		var inst = new MyDynamicClass(100);
 		var add = inst.add;
 		var add = inst.add;
-		eq( inst.add(1,2), 103 );
-		eq( inst.add.bind(1)(2), 103 );
-		eq( add(1,2), 103 );
+		eq(inst.add(1, 2), 103);
+		eq(inst.add.bind(1)(2), 103);
+		eq(add(1, 2), 103);
 
 
 		// check overridden dynamic method
 		// check overridden dynamic method
 		var inst = new MyDynamicSubClass(100);
 		var inst = new MyDynamicSubClass(100);
 		var add = inst.add;
 		var add = inst.add;
-		eq( inst.add(1,2), 206 );
-		eq( inst.add.bind(1)(2), 206 );
-		eq( add(1,2), 206 );
+		eq(inst.add(1, 2), 206);
+		eq(inst.add.bind(1)(2), 206);
+		eq(add(1, 2), 206);
 
 
 		// check overridden dynamic method
 		// check overridden dynamic method
 		var inst = new MyDynamicSubClass2(100);
 		var inst = new MyDynamicSubClass2(100);
 		var add = inst.add;
 		var add = inst.add;
-		eq( inst.add(1,2), 206 );
-		eq( inst.add.bind(1)(2), 206 );
-		eq( add(1,2), 206 );
+		eq(inst.add(1, 2), 206);
+		eq(inst.add.bind(1)(2), 206);
+		eq(add(1, 2), 206);
 
 
 		// check redefined dynamic method
 		// check redefined dynamic method
-		inst.add = function(x,y) return inst.get() * 2 + x + y;
+		inst.add = function(x, y) return inst.get() * 2 + x + y;
 		var add = inst.add;
 		var add = inst.add;
-		eq( inst.add(1,2), 203 );
-		eq( inst.add.bind(1)(2), 203 );
-		eq( add(1,2), 203 );
+		eq(inst.add(1, 2), 203);
+		eq(inst.add.bind(1)(2), 203);
+		eq(add(1, 2), 203);
 
 
 		// check inherited dynamic method
 		// check inherited dynamic method
 		var inst = new MyOtherDynamicClass(0);
 		var inst = new MyOtherDynamicClass(0);
 		var add = inst.add;
 		var add = inst.add;
-		#if (!java) //see https://groups.google.com/d/msg/haxedev/TUaUykoTpq8/Q4XwcL4UyNUJ
 		eq( inst.add(1,2), 13 );
 		eq( inst.add(1,2), 13 );
 		eq( inst.add.bind(1)(2), 13 );
 		eq( inst.add.bind(1)(2), 13 );
 		eq( add(1,2), 13 );
 		eq( add(1,2), 13 );
-		#end
 
 
 		// check static dynamic
 		// check static dynamic
-		eq( MyDynamicClass.staticDynamic(1,2), 13 );
-		MyDynamicClass.staticDynamic = function(x,y) return x + y + 100;
-		eq( MyDynamicClass.staticDynamic(1,2), 103 );
+		eq(MyDynamicClass.staticDynamic(1, 2), 13);
+		MyDynamicClass.staticDynamic = function(x, y) return x + y + 100;
+		eq(MyDynamicClass.staticDynamic(1, 2), 103);
 	}
 	}
 
 
-	function testMakeVarArgs () {
-		var f = function (a:Array<Dynamic>) {
+	function testMakeVarArgs() {
+		var f = function(a:Array<Dynamic>) {
 			eq(a.length, 2);
 			eq(a.length, 2);
 			return a[0] + a[1];
 			return a[0] + a[1];
 		}
 		}
 		var g = Reflect.makeVarArgs(f);
 		var g = Reflect.makeVarArgs(f);
-		var res = g(1,2);
+		var res = g(1, 2);
 		eq(3, res);
 		eq(3, res);
 	}
 	}
 
 
 	function testMD5() {
 	function testMD5() {
-		eq( haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e" );
-		eq( haxe.crypto.Md5.encode("hello"), "5d41402abc4b2a76b9719d911017c592" );
+		eq(haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e");
+		eq(haxe.crypto.Md5.encode("hello"), "5d41402abc4b2a76b9719d911017c592");
 		// depending of ISO/UTF8 native
 		// depending of ISO/UTF8 native
-		allow( haxe.crypto.Md5.encode("héllo"), ["1a722f7e6c801d9e470a10cb91ba406d", "be50e8478cf24ff3595bc7307fb91b50"] );
+		allow(haxe.crypto.Md5.encode("héllo"), ["1a722f7e6c801d9e470a10cb91ba406d", "be50e8478cf24ff3595bc7307fb91b50"]);
 
 
-		eq( haxe.io.Bytes.ofString("héllo").toHex(), "68c3a96c6c6f");
-		eq( haxe.crypto.Md5.make(haxe.io.Bytes.ofString("héllo")).toHex(), "be50e8478cf24ff3595bc7307fb91b50" );
+		eq(haxe.io.Bytes.ofString("héllo").toHex(), "68c3a96c6c6f");
+		eq(haxe.crypto.Md5.make(haxe.io.Bytes.ofString("héllo")).toHex(), "be50e8478cf24ff3595bc7307fb91b50");
 	}
 	}
 
 
 	function testSHA1() {
 	function testSHA1() {
-		eq( haxe.crypto.Sha1.encode(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709" );
-		eq( haxe.crypto.Sha1.encode("hello"), "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d" );
+		eq(haxe.crypto.Sha1.encode(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709");
+		eq(haxe.crypto.Sha1.encode("hello"), "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d");
 		// depending of ISO/UTF8 native
 		// depending of ISO/UTF8 native
-		allow( haxe.crypto.Sha1.encode("héllo"), ["028db752c14604d624e8b1c121d600c427b8a3ba","35b5ea45c5e41f78b46a937cc74d41dfea920890"] );
+		allow(haxe.crypto.Sha1.encode("héllo"), [
+			"028db752c14604d624e8b1c121d600c427b8a3ba",
+			"35b5ea45c5e41f78b46a937cc74d41dfea920890"
+		]);
 
 
-		eq( haxe.crypto.Sha1.make(haxe.io.Bytes.ofString("héllo")).toHex(), "35b5ea45c5e41f78b46a937cc74d41dfea920890" );
+		eq(haxe.crypto.Sha1.make(haxe.io.Bytes.ofString("héllo")).toHex(), "35b5ea45c5e41f78b46a937cc74d41dfea920890");
 	}
 	}
 
 
 	function testBaseCode() {
 	function testBaseCode() {
@@ -338,84 +336,84 @@ class TestMisc extends Test {
 
 
 		// alternative base64
 		// alternative base64
 		var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"));
 		var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"));
-		eq( b.encodeString("Héllow"), "iceFr6NLtM" );
-		eq( b.decodeString("iceFr6NLtM"), "Héllow" );
+		eq(b.encodeString("Héllow"), "iceFr6NLtM");
+		eq(b.decodeString("iceFr6NLtM"), "Héllow");
 
 
 		// base32-hex
 		// base32-hex
 		var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789ABCDEFGHIJKLMNOPQRSTUV"));
 		var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789ABCDEFGHIJKLMNOPQRSTUV"));
-		eq( b.encodeString("foo"), "CPNMU" );
-		eq( b.decodeString("CPNMU"), "foo" );
+		eq(b.encodeString("foo"), "CPNMU");
+		eq(b.decodeString("CPNMU"), "foo");
 	}
 	}
 
 
 	function testUrlEncode() {
 	function testUrlEncode() {
-		eq( StringTools.urlEncode("é"), "%C3%A9" );
-		eq( StringTools.urlDecode("%C3%A9"), "é" );
+		eq(StringTools.urlEncode("é"), "%C3%A9");
+		eq(StringTools.urlDecode("%C3%A9"), "é");
 
 
-		eq( StringTools.urlEncode("a/b+c"), "a%2Fb%2Bc");
-		eq( StringTools.urlDecode("a%2Fb%2Bc"), "a/b+c");
+		eq(StringTools.urlEncode("a/b+c"), "a%2Fb%2Bc");
+		eq(StringTools.urlDecode("a%2Fb%2Bc"), "a/b+c");
 	}
 	}
 
 
-	function opt1( ?x : Int, ?y : String ) {
-		return { x : x, y : y };
+	function opt1(?x:Int, ?y:String) {
+		return {x: x, y: y};
 	}
 	}
 
 
-	function opt2( ?x = 5, ?y = "hello" ) {
-		return { x : x, y : y };
+	function opt2(?x = 5, ?y = "hello") {
+		return {x: x, y: y};
 	}
 	}
 
 
-	function opt3( ?x : Null<Int> = 5, ?y : Null<Float> = 6 ) {
-		return { x : x, y : y };
+	function opt3(?x:Null<Int> = 5, ?y:Null<Float> = 6) {
+		return {x: x, y: y};
 	}
 	}
 
 
-	function opt4( x = 10 ) : Null<Int> {
+	function opt4(x = 10):Null<Int> {
 		return x + 1;
 		return x + 1;
 	}
 	}
 
 
 	function testOptionalParams() {
 	function testOptionalParams() {
-		eq( opt1().x, null );
-		eq( opt1().y, null );
-		eq( opt1(55).x, 55 );
-		eq( opt1(55).y, null );
-		eq( opt1("str").x, null );
-		eq( opt1("str").y, "str" );
-		eq( opt1(66,"hello").x, 66 );
-		eq( opt1(66, "hello").y, "hello" );
-
-		eq( opt2().x, 5 );
-		eq( opt2().y, "hello" );
+		eq(opt1().x, null);
+		eq(opt1().y, null);
+		eq(opt1(55).x, 55);
+		eq(opt1(55).y, null);
+		eq(opt1("str").x, null);
+		eq(opt1("str").y, "str");
+		eq(opt1(66, "hello").x, 66);
+		eq(opt1(66, "hello").y, "hello");
+
+		eq(opt2().x, 5);
+		eq(opt2().y, "hello");
 
 
 		#if !(flash || cpp || java)
 		#if !(flash || cpp || java)
-		eq( opt2(null, null).x, 5 );
+		eq(opt2(null, null).x, 5);
 		#end
 		#end
-		eq( opt2(0, null).y, "hello" );
-
-		eq( opt3().x, 5 );
-		eq( opt3().y, 6 );
-		eq( opt3(9).x, 9 );
-		eq( opt3(9).y, 6 );
-		eq( opt3(9,10).x, 9 );
-		eq( opt3(9,10).y, 10 );
-		eq( opt3(null,null).x, 5 );
-		eq( opt3(null,null).y, 6 );
-		eq( opt3(null).x, 5 );
-		eq( opt3(null).y, 6 );
-		eq( opt3(null,7).x, 5 );
-		eq( opt3(null, 7).y, 7 );
+		eq(opt2(0, null).y, "hello");
+
+		eq(opt3().x, 5);
+		eq(opt3().y, 6);
+		eq(opt3(9).x, 9);
+		eq(opt3(9).y, 6);
+		eq(opt3(9, 10).x, 9);
+		eq(opt3(9, 10).y, 10);
+		eq(opt3(null, null).x, 5);
+		eq(opt3(null, null).y, 6);
+		eq(opt3(null).x, 5);
+		eq(opt3(null).y, 6);
+		eq(opt3(null, 7).x, 5);
+		eq(opt3(null, 7).y, 7);
 
 
 		// skipping
 		// skipping
-		eq( opt3(7.4).x, 5 );
-		eq( opt3(7.4).y, 7.4 );
+		eq(opt3(7.4).x, 5);
+		eq(opt3(7.4).y, 7.4);
 
 
-		eq( opt4(), 11 );
+		eq(opt4(), 11);
 		#if !static
 		#if !static
-		eq( opt4(null), 11 );
+		eq(opt4(null), 11);
 		#end
 		#end
 
 
-		var opt4b : ?Int -> Null<Int> = opt4;
-		eq( opt4b(), 11 );
-		eq( opt4b(3), 4 );
+		var opt4b:?Int->Null<Int> = opt4;
+		eq(opt4b(), 11);
+		eq(opt4b(3), 4);
 		#if !static
 		#if !static
-		eq( opt4b(null), 11 );
+		eq(opt4b(null), 11);
 		#end
 		#end
 
 
 		// don't compile because we restrict nullability of function param or return type
 		// don't compile because we restrict nullability of function param or return type
@@ -430,107 +428,108 @@ class TestMisc extends Test {
 
 
 	function testIncr() {
 	function testIncr() {
 		var z = 0;
 		var z = 0;
-		eq( z++, 0 );
-		eq( z, 1 );
-		eq( ++z, 2 );
-		eq( z, 2 );
+		eq(z++, 0);
+		eq(z, 1);
+		eq(++z, 2);
+		eq(z, 2);
 		z++;
 		z++;
-		eq( z, 3 );
+		eq(z, 3);
 		++z;
 		++z;
-		eq( z, 4 );
+		eq(z, 4);
 
 
-		eq( z += 3, 7 );
+		eq(z += 3, 7);
 
 
 		var x = 0;
 		var x = 0;
 		var arr = [3];
 		var arr = [3];
-		eq( arr[x++]++, 3 );
-		eq( x, 1 );
-		eq( arr[0], 4 );
+		eq(arr[x++]++, 3);
+		eq(x, 1);
+		eq(arr[0], 4);
 		x = 0;
 		x = 0;
-		eq( arr[x++] += 3, 7 );
-		eq( arr[0], 7 );
+		eq(arr[x++] += 3, 7);
+		eq(arr[0], 7);
 
 
 		var x = 0;
 		var x = 0;
-		var arr = [{ v : 3 }];
-		eq( arr[x++].v++, 3 );
-		eq( x, 1 );
-		eq( arr[0].v, 4 );
+		var arr = [{v: 3}];
+		eq(arr[x++].v++, 3);
+		eq(x, 1);
+		eq(arr[0].v, 4);
 
 
 		x = 0;
 		x = 0;
-		eq( arr[x++].v += 3, 7 );
-		eq( arr[0].v, 7 );
+		eq(arr[x++].v += 3, 7);
+		eq(arr[0].v, 7);
 
 
 		x = 0;
 		x = 0;
-		var arr:Dynamic = [{ v : 3 }];
-		eq( arr[x++].v++, 3 );
-		eq( x, 1 );
-		eq( arr[0].v, 4 );
+		var arr:Dynamic = [{v: 3}];
+		eq(arr[x++].v++, 3);
+		eq(x, 1);
+		eq(arr[0].v, 4);
 
 
 		x = 0;
 		x = 0;
-		eq( arr[x++].v += 3, 7 );
-		eq( arr[0].v, 7 );
+		eq(arr[x++].v += 3, 7);
+		eq(arr[0].v, 7);
 	}
 	}
 
 
 	function testInitOrder() {
 	function testInitOrder() {
 		var i = 0;
 		var i = 0;
 		var o = {
 		var o = {
-			y : i++,
-			x : i++,
-			z : i++,
-			blabla : i++,
+			y: i++,
+			x: i++,
+			z: i++,
+			blabla: i++,
 		};
 		};
-		eq(o.y,0);
-		eq(o.x,1);
-		eq(o.z,2);
-		eq(o.blabla,3);
+		eq(o.y, 0);
+		eq(o.x, 1);
+		eq(o.z, 2);
+		eq(o.blabla, 3);
 	}
 	}
 
 
-	static inline function foo(x) return x + 5;
+	static inline function foo(x)
+		return x + 5;
 
 
 	function testInline() {
 	function testInline() {
 		// check that operations are correctly generated
 		// check that operations are correctly generated
 		var x = 3; // prevent optimization
 		var x = 3; // prevent optimization
-		eq( 2 * foo(x), 16 );
-		eq( -foo(x), -8 );
+		eq(2 * foo(x), 16);
+		eq(-foo(x), -8);
 	}
 	}
 
 
 	function testEvalAccessOrder() {
 	function testEvalAccessOrder() {
-		var a = [0,0];
+		var a = [0, 0];
 		var x = 0;
 		var x = 0;
 		a[x++]++;
 		a[x++]++;
-		eq(a[0],1);
-		eq(a[1],0);
+		eq(a[0], 1);
+		eq(a[1], 0);
 
 
 		var x = 0;
 		var x = 0;
 		var a = new Array();
 		var a = new Array();
 		a[x++] = x++;
 		a[x++] = x++;
-		eq(a[0],1);
+		eq(a[0], 1);
 
 
 		var x = 0;
 		var x = 0;
 		var foo = function() return x++;
 		var foo = function() return x++;
 		a[foo()] = foo();
 		a[foo()] = foo();
-		eq(a[0],1);
+		eq(a[0], 1);
 	}
 	}
 
 
-	static var add = function (x, y) return x + y;
+	static var add = function(x, y) return x + y;
 
 
 	function testStaticVarFun() {
 	function testStaticVarFun() {
-		eq( add(2,3), 5);
+		eq(add(2, 3), 5);
 	}
 	}
 
 
 	function testDefArgs() {
 	function testDefArgs() {
 		var e = new ExtDefArgs();
 		var e = new ExtDefArgs();
-		eq( e.get(), 7 );
-		var b : BaseDefArgs = e;
-		eq( b.get(), 7 );
-		var i : IDefArgs = e;
-		eq( i.get(), 7 );
+		eq(e.get(), 7);
+		var b:BaseDefArgs = e;
+		eq(b.get(), 7);
+		var i:IDefArgs = e;
+		eq(i.get(), 7);
 	}
 	}
 
 
 	function testStringBuf() {
 	function testStringBuf() {
 		var b = new StringBuf();
 		var b = new StringBuf();
 		eq(b.length, 0);
 		eq(b.length, 0);
-		b.add( -45);
+		b.add(-45);
 		b.add(1.456);
 		b.add(1.456);
 		b.add(null);
 		b.add(null);
 		b.add(true);
 		b.add(true);
@@ -542,26 +541,23 @@ class TestMisc extends Test {
 		eq(b.length, 30);
 		eq(b.length, 30);
 	}
 	}
 
 
-	function testToString():Void
-	{
-		var x = { toString : function() return "foo" };
-		eq( Std.string(x), "foo" );
-
-		//var x1:Dynamic = new MyDynamicChildWithToString();
-		//eq( Std.string(x1), "Custom toString" );
-//
-		//var x2:Dynamic = new MyDynamicChildWithoutToString();
-		//x2.toString = function() return "foo";
-		//eq( Std.string(x2), "foo" );
+	function testToString():Void {
+		var x = {toString: function() return "foo"};
+		eq(Std.string(x), "foo");
 
 
+		// var x1:Dynamic = new MyDynamicChildWithToString();
+		// eq( Std.string(x1), "Custom toString" );
+		//
+		// var x2:Dynamic = new MyDynamicChildWithoutToString();
+		// x2.toString = function() return "foo";
+		// eq( Std.string(x2), "foo" );
 	}
 	}
 
 
 	#if !macro
 	#if !macro
-	function testFormat()
-	{
+	function testFormat() {
 		var x = 5;
 		var x = 5;
 		var y = 6;
 		var y = 6;
-		eq('$x${x+y}', "511");
+		eq('$x${x + y}', "511");
 	}
 	}
 	#end
 	#end
 
 
@@ -596,16 +592,18 @@ class TestMisc extends Test {
 		function test():String {
 		function test():String {
 			throw "never call me";
 			throw "never call me";
 		};
 		};
-		var s = try test() catch(e:String) e;
-		eq(s,"never call me");
+		var s = try test() catch (e:String) e;
+		eq(s, "never call me");
 
 
-		function test():String throw "never call me";
-		var s = try test() catch(e:String) e;
-		eq(s,"never call me");
+		function test():String
+			throw "never call me";
+		var s = try test() catch (e:String) e;
+		eq(s, "never call me");
 	}
 	}
 
 
 	static var nf1:Base = null;
 	static var nf1:Base = null;
 	static var nf2:{s:String} = null;
 	static var nf2:{s:String} = null;
+
 	function testNullFieldAccess() {
 	function testNullFieldAccess() {
 		eq("NPE", try nf1.s catch (e:Any) "NPE");
 		eq("NPE", try nf1.s catch (e:Any) "NPE");
 		eq("NPE", try nf2.s catch (e:Any) "NPE");
 		eq("NPE", try nf2.s catch (e:Any) "NPE");