浏览代码

Merge branch 'development' of https://github.com/HaxeFoundation/haxe into development

Miha Lunar 11 年之前
父节点
当前提交
55d661d562
共有 100 个文件被更改,包括 1954 次插入1047 次删除
  1. 3 0
      .gitignore
  2. 16 12
      .travis.yml
  3. 2 2
      Makefile
  4. 2 0
      ast.ml
  5. 102 49
      codegen.ml
  6. 32 2
      common.ml
  7. 45 5
      dce.ml
  8. 40 18
      doc/CHANGES.txt
  9. 1 1
      doc/extract.hxml
  10. 4 2
      doc/extract.patch
  11. 10 3
      filters.ml
  12. 23 3
      genas3.ml
  13. 11 3
      gencommon.ml
  14. 28 8
      gencpp.ml
  15. 13 1
      gencs.ml
  16. 4 0
      genjava.ml
  17. 31 11
      genjs.ml
  18. 31 28
      genswf.ml
  19. 24 3
      genswf9.ml
  20. 2 2
      genxml.ml
  21. 2 0
      haxe.hxproj
  22. 40 9
      interp.ml
  23. 1 1
      libs
  24. 10 1
      main.ml
  25. 88 64
      matcher.ml
  26. 53 7
      optimizer.ml
  27. 24 11
      parser.ml
  28. 2 2
      std/Lambda.hx
  29. 2 2
      std/Map.hx
  30. 15 4
      std/Std.hx
  31. 70 69
      std/UInt.hx
  32. 3 0
      std/cpp/_std/Date.hx
  33. 2 2
      std/cpp/_std/Std.hx
  34. 3 1
      std/cpp/_std/haxe/Utf8.hx
  35. 2 2
      std/cpp/_std/sys/FileSystem.hx
  36. 202 0
      std/cpp/_std/sys/db/Mysql.hx
  37. 186 0
      std/cpp/_std/sys/db/Sqlite.hx
  38. 15 0
      std/cpp/vm/Debugger.hx
  39. 20 8
      std/cs/_std/Array.hx
  40. 2 2
      std/cs/_std/Std.hx
  41. 5 0
      std/cs/internal/StringExt.hx
  42. 2 2
      std/flash/_std/Std.hx
  43. 16 6
      std/flash/_std/haxe/Json.hx
  44. 1 0
      std/flash/display/DisplayObjectContainer.hx
  45. 1 0
      std/flash/display/Stage3D.hx
  46. 2 0
      std/flash/display3D/Context3D.hx
  47. 1 0
      std/flash/display3D/Context3DProfile.hx
  48. 1 0
      std/flash/events/AVStatusEvent.hx
  49. 10 0
      std/flash/events/DRMReturnVoucherCompleteEvent.hx
  50. 10 0
      std/flash/events/DRMReturnVoucherErrorEvent.hx
  51. 1 0
      std/flash/events/GameInputEvent.hx
  52. 2 1
      std/flash/events/HTTPStatusEvent.hx
  53. 1 0
      std/flash/events/StageVideoAvailabilityEvent.hx
  54. 2 1
      std/flash/media/AVPeriodInfo.hx
  55. 1 0
      std/flash/media/AVPlayState.hx
  56. 24 0
      std/flash/media/AVResult.hx
  57. 3 0
      std/flash/media/AVStream.hx
  58. 10 0
      std/flash/media/StageVideoAvailabilityReason.hx
  59. 1 0
      std/flash/net/NetStream.hx
  60. 1 0
      std/flash/net/URLRequest.hx
  61. 3 0
      std/flash/net/drm/DRMManager.hx
  62. 6 0
      std/flash/net/drm/DRMReturnVoucherContext.hx
  63. 3 0
      std/flash/net/drm/DRMVoucher.hx
  64. 1 0
      std/flash/net/drm/VoucherAccessInfo.hx
  65. 10 0
      std/flash/system/ConnexionsClient.hx
  66. 2 2
      std/flash8/_std/Std.hx
  67. 0 4
      std/flash8/display/BitmapData.hx
  68. 0 4
      std/flash8/filters/BitmapFilter.hx
  69. 0 4
      std/flash8/geom/ColorTransform.hx
  70. 0 4
      std/flash8/geom/Matrix.hx
  71. 0 4
      std/flash8/geom/Point.hx
  72. 0 4
      std/flash8/geom/Rectangle.hx
  73. 0 4
      std/flash8/geom/Transform.hx
  74. 0 4
      std/flash8/net/FileReference.hx
  75. 0 4
      std/flash8/net/FileReferenceList.hx
  76. 0 4
      std/flash8/text/TextRenderer.hx
  77. 42 5
      std/haxe/Http.hx
  78. 17 453
      std/haxe/Json.hx
  79. 2 2
      std/haxe/Resource.hx
  80. 1 1
      std/haxe/Template.hx
  81. 43 12
      std/haxe/Timer.hx
  82. 1 1
      std/haxe/crypto/Base64.hx
  83. 1 0
      std/haxe/ds/Vector.hx
  84. 210 0
      std/haxe/format/JsonParser.hx
  85. 168 0
      std/haxe/format/JsonPrinter.hx
  86. 10 7
      std/haxe/io/Path.hx
  87. 0 136
      std/haxe/macro/Build.hx
  88. 31 0
      std/haxe/macro/Context.hx
  89. 1 0
      std/haxe/macro/Expr.hx
  90. 34 19
      std/haxe/macro/Printer.hx
  91. 11 1
      std/haxe/macro/Type.hx
  92. 1 1
      std/haxe/web/Dispatch.hx
  93. 20 8
      std/java/_std/Array.hx
  94. 2 2
      std/java/_std/Std.hx
  95. 5 0
      std/java/internal/StringExt.hx
  96. 6 3
      std/js/Boot.hx
  97. 9 0
      std/js/Browser.hx
  98. 3 3
      std/js/_std/Std.hx
  99. 47 0
      std/js/_std/haxe/Json.hx
  100. 3 3
      std/js/_std/haxe/ds/ObjectMap.hx

+ 3 - 0
.gitignore

@@ -7,6 +7,9 @@
 *.exe
 *.exe
 .*.swp
 .*.swp
 
 
+/doc/hxclasses
+/doc/*.swf
+/doc/*.swc
 
 
 /version.ml
 /version.ml
 /haxe
 /haxe

+ 16 - 12
.travis.yml

@@ -1,26 +1,30 @@
 language: node_js
 language: node_js
 
 
 env:
 env:
-  - TARGET=macro
-  - TARGET=neko
-  - TARGET=js
-  - TARGET=php
-  - TARGET=cpp
-  - TARGET=flash9
-  - TARGET=flash8
-  - TARGET=as3
-  - TARGET=java
-  - TARGET=cs
+  global:
+    # SAUCE_USERNAME
+    - secure: SjyKefmjUEXi0IKHGGpcbLAajU0mLHONg8aA8LoY7Q9nAkSN6Aql+fzS38Boq7w1jWn+2FOpr+4jy0l6wVd/bftsF+huFfYpFJmdh8BlKmE0K71zZAral0H1c7YxkuQpPiJCIFGXqtkvev7SWTy0z31u7kuuQeEyW27boXe5cDA=
+    # SAUCE_ACCESS_KEY
+    - secure: sUvWUjCyPuWht4seNa4f2VG9DkvXkhZyLZfjJO9TUAHB2JndS16E2j/qrvKEjycyH6w8tU/B9vnjDRvvGrYXxEXcBEwsJVfkorFnRl9uwGCGIYrzjMhssEl3fMYZK7P304f+gAp5ULrDBX2gIaKeSa8lUNRtz2PsZOieE4kMdhk=
+  matrix:
+    - TARGET=macro
+    - TARGET=neko
+    - TARGET=js
+    - TARGET=php
+    - TARGET=cpp
+    - TARGET=flash9
+    - TARGET=flash8
+    - TARGET=as3
+    - TARGET=java
+    - TARGET=cs
 
 
 matrix:
 matrix:
   allow_failures:
   allow_failures:
     - env: TARGET=flash8
     - env: TARGET=flash8
-    - env: TARGET=as3
     - env: TARGET=java
     - env: TARGET=java
     - env: TARGET=cs
     - env: TARGET=cs
 
 
 before_install:
 before_install:
-  - export TRAVIS_BUILD_DIR=$(pwd) #tmp fix, see https://github.com/travis-ci/travis-build/pull/182
   - sudo apt-get update
   - sudo apt-get update
   - sudo apt-get install ocaml zlib1g-dev libgc-dev -y
   - sudo apt-get install ocaml zlib1g-dev libgc-dev -y
   - git clone https://github.com/HaxeFoundation/neko.git ~/neko && cd ~/neko && make && sudo make install && cd $TRAVIS_BUILD_DIR
   - git clone https://github.com/HaxeFoundation/neko.git ~/neko && cd ~/neko && make && sudo make install && cd $TRAVIS_BUILD_DIR

+ 2 - 2
Makefile

@@ -96,7 +96,7 @@ install_tools: tools
 	chmod a+rx $(INSTALL_DIR)/bin/haxelib $(INSTALL_DIR)/bin/haxedoc
 	chmod a+rx $(INSTALL_DIR)/bin/haxelib $(INSTALL_DIR)/bin/haxedoc
 
 
 uninstall:
 uninstall:
-	rm -rf $(INSTALL_DIR)/bin/haxe $(INSTALL_DIR)/bin/haxelib $(INSTALL_DIR)/lib/haxe
+	rm -rf $(INSTALL_DIR)/bin/haxe $(INSTALL_DIR)/bin/haxelib $(INSTALL_DIR)/lib/haxe $(INSTALL_DIR)/bin/haxedoc
 
 
 export:
 export:
 	cp haxe*.exe doc/CHANGES.txt $(EXPORT)
 	cp haxe*.exe doc/CHANGES.txt $(EXPORT)
@@ -172,7 +172,7 @@ clean_libs:
 	make -C libs/ttflib clean
 	make -C libs/ttflib clean
 
 
 clean_haxe:
 clean_haxe:
-	rm -f $(MODULES:=.obj) $(MODULES:=.o) $(MODULES:=.cmx) $(MODULES:=.cmi) lexer.ml
+	rm -f $(MODULES:=.obj) $(MODULES:=.o) $(MODULES:=.cmx) $(MODULES:=.cmi) lexer.ml haxe.exe
 
 
 clean_tools:
 clean_tools:
 	rm -f $(OUTPUT) haxelib haxedoc
 	rm -f $(OUTPUT) haxelib haxedoc

+ 2 - 0
ast.ml

@@ -30,6 +30,7 @@ module Meta = struct
 	type strict_meta =
 	type strict_meta =
 		| Abstract
 		| Abstract
 		| Access
 		| Access
+		| Accessor
 		| Allow
 		| Allow
 		| Annotation
 		| Annotation
 		| ArrayAccess
 		| ArrayAccess
@@ -70,6 +71,7 @@ module Meta = struct
 		| FunctionCode
 		| FunctionCode
 		| FunctionTailCode
 		| FunctionTailCode
 		| Generic
 		| Generic
+		| GenericBuild
 		| Getter
 		| Getter
 		| Hack
 		| Hack
 		| HaxeGeneric
 		| HaxeGeneric

+ 102 - 49
codegen.ml

@@ -89,17 +89,21 @@ let rec has_properties c =
 		match f.cf_kind with
 		match f.cf_kind with
 		| Var { v_read = AccCall } -> true
 		| Var { v_read = AccCall } -> true
 		| Var { v_write = AccCall } -> true
 		| Var { v_write = AccCall } -> true
+		| _ when Meta.has Meta.Accessor f.cf_meta -> true
 		| _ -> false
 		| _ -> false
 	) c.cl_ordered_fields || (match c.cl_super with Some (c,_) -> has_properties c | _ -> false)
 	) c.cl_ordered_fields || (match c.cl_super with Some (c,_) -> has_properties c | _ -> false)
 
 
 let get_properties fields =
 let get_properties fields =
 	List.fold_left (fun acc f ->
 	List.fold_left (fun acc f ->
-		let acc = (match f.cf_kind with
-		| Var { v_read = AccCall } -> ("get_" ^ f.cf_name , "get_" ^ f.cf_name) :: acc
-		| _ -> acc) in
-		match f.cf_kind with
-		| Var { v_write = AccCall } -> ("set_" ^ f.cf_name , "set_" ^ f.cf_name) :: acc
-		| _ -> acc
+		if Meta.has Meta.Accessor f.cf_meta then
+			(f.cf_name, f.cf_name) :: acc
+		else
+			let acc = (match f.cf_kind with
+			| Var { v_read = AccCall } -> ("get_" ^ f.cf_name , "get_" ^ f.cf_name) :: acc
+			| _ -> acc) in
+			match f.cf_kind with
+			| Var { v_write = AccCall } -> ("set_" ^ f.cf_name , "set_" ^ f.cf_name) :: acc
+			| _ -> acc
 	) [] fields
 	) [] fields
 
 
 let add_property_field com c =
 let add_property_field com c =
@@ -222,16 +226,19 @@ let make_generic ctx ps pt p =
 	in
 	in
 	let name =
 	let name =
 		String.concat "_" (List.map2 (fun (s,_) t ->
 		String.concat "_" (List.map2 (fun (s,_) t ->
-			let path = (match follow t with
-				| TInst (ct,_) -> ct.cl_path
-				| TEnum (e,_) -> e.e_path
-				| TAbstract (a,_) when Meta.has Meta.RuntimeValue a.a_meta -> a.a_path
+			let s_type_path_underscore (p,s) = match p with [] -> s | _ -> String.concat "_" p ^ "_" ^ s in
+			let rec loop top t = match follow t with
+				| TInst(c,tl) -> (s_type_path_underscore c.cl_path) ^ (loop_tl tl)
+				| TEnum(en,tl) -> (s_type_path_underscore en.e_path) ^ (loop_tl tl)
+				| TAbstract(a,tl) -> (s_type_path_underscore a.a_path) ^ (loop_tl tl)
+				| _ when not top -> "_" (* allow unknown/incompatible types as type parameters to retain old behavior *)
 				| TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
 				| TMono _ -> raise (Generic_Exception (("Could not determine type for parameter " ^ s), p))
 				| t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
 				| t -> raise (Generic_Exception (("Type parameter must be a class or enum instance (found " ^ (s_type (print_context()) t) ^ ")"), p))
-			) in
-			match path with
-			| [] , name -> name
-			| l , name -> String.concat "_" l ^ "_" ^ name
+			and loop_tl tl = match tl with
+				| [] -> ""
+				| tl -> "_" ^ String.concat "_" (List.map (loop false) tl)
+			in
+			loop true t
 		) ps pt)
 		) ps pt)
 	in
 	in
 	{
 	{
@@ -395,9 +402,9 @@ let rec build_generic ctx c p tl =
 		cg.cl_kind <- KGenericInstance (c,tl);
 		cg.cl_kind <- KGenericInstance (c,tl);
 		cg.cl_interface <- c.cl_interface;
 		cg.cl_interface <- c.cl_interface;
 		cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
 		cg.cl_constructor <- (match cg.cl_constructor, c.cl_constructor, c.cl_super with
+			| _, Some c, _ -> Some (build_field c)
 			| Some ctor, _, _ -> Some ctor
 			| Some ctor, _, _ -> Some ctor
 			| None, None, None -> None
 			| None, None, None -> None
-			| None, Some c, _ -> Some (build_field c)
 			| _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
 			| _ -> error "Please define a constructor for this class in order to use it as generic" c.cl_pos
 		);
 		);
 		cg.cl_implements <- List.map (fun (i,tl) ->
 		cg.cl_implements <- List.map (fun (i,tl) ->
@@ -507,19 +514,22 @@ let build_metadata com t =
 (* -------------------------------------------------------------------------- *)
 (* -------------------------------------------------------------------------- *)
 (* MACRO TYPE *)
 (* MACRO TYPE *)
 
 
+let get_macro_path e args p =
+	let rec loop e =
+		match fst e with
+		| EField (e,f) -> f :: loop e
+		| EConst (Ident i) -> [i]
+		| _ -> error "Invalid macro call" p
+	in
+	(match loop e with
+	| meth :: cl :: path -> (List.rev path,cl), meth, args
+	| _ -> error "Invalid macro call" p)
+
 let build_macro_type ctx pl p =
 let build_macro_type ctx pl p =
 	let path, field, args = (match pl with
 	let path, field, args = (match pl with
 		| [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
 		| [TInst ({ cl_kind = KExpr (ECall (e,args),_) },_)]
 		| [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
 		| [TInst ({ cl_kind = KExpr (EArrayDecl [ECall (e,args),_],_) },_)] ->
-			let rec loop e =
-				match fst e with
-				| EField (e,f) -> f :: loop e
-				| EConst (Ident i) -> [i]
-				| _ -> error "Invalid macro call" p
-			in
-			(match loop e with
-			| meth :: cl :: path -> (List.rev path,cl), meth, args
-			| _ -> error "Invalid macro call" p)
+			get_macro_path e args p
 		| _ ->
 		| _ ->
 			error "MacroType require a single expression call parameter" p
 			error "MacroType require a single expression call parameter" p
 	) in
 	) in
@@ -531,6 +541,21 @@ let build_macro_type ctx pl p =
 	ctx.ret <- old;
 	ctx.ret <- old;
 	t
 	t
 
 
+let build_macro_build ctx c pl cfl p =
+	let path, field, args = match Meta.get Meta.GenericBuild c.cl_meta with
+		| _,[ECall(e,args),_],_ -> get_macro_path e args p
+		| _ -> assert false
+	in
+	let old = ctx.ret,ctx.g.get_build_infos in
+	ctx.g.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl));
+	let t = (match ctx.g.do_macro ctx MMacroType path field args p with
+		| None -> mk_mono()
+		| Some _ -> ctx.ret
+	) in
+	ctx.ret <- fst old;
+	ctx.g.get_build_infos <- snd old;
+	t
+
 (* -------------------------------------------------------------------------- *)
 (* -------------------------------------------------------------------------- *)
 (* API EVENTS *)
 (* API EVENTS *)
 
 
@@ -538,26 +563,24 @@ let build_instance ctx mtype p =
 	match mtype with
 	match mtype with
 	| TClassDecl c ->
 	| TClassDecl c ->
 		if ctx.pass > PBuildClass then c.cl_build();
 		if ctx.pass > PBuildClass then c.cl_build();
+		let build f s =
+			let r = exc_protect ctx (fun r ->
+				let t = mk_mono() in
+				r := (fun() -> t);
+				unify_raise ctx (f()) t p;
+				t
+			) s in
+			delay ctx PForce (fun() -> ignore ((!r)()));
+			TLazy r
+		in
 		let ft = (fun pl ->
 		let ft = (fun pl ->
 			match c.cl_kind with
 			match c.cl_kind with
 			| KGeneric ->
 			| KGeneric ->
-				let r = exc_protect ctx (fun r ->
-					let t = mk_mono() in
-					r := (fun() -> t);
-					unify_raise ctx (build_generic ctx c p pl) t p;
-					t
-				) "build_generic" in
-				delay ctx PForce (fun() -> ignore ((!r)()));
-				TLazy r
+				build (fun () -> build_generic ctx c p pl) "build_generic"
 			| KMacroType ->
 			| KMacroType ->
-				let r = exc_protect ctx (fun r ->
-					let t = mk_mono() in
-					r := (fun() -> t);
-					unify_raise ctx (build_macro_type ctx pl p) t p;
-					t
-				) "macro_type" in
-				delay ctx PForce (fun() -> ignore ((!r)()));
-				TLazy r
+				build (fun () -> build_macro_type ctx pl p) "macro_type"
+			| KGenericBuild cfl ->
+				build (fun () -> build_macro_build ctx c pl cfl p) "generic_build"
 			| _ ->
 			| _ ->
 				TInst (c,pl)
 				TInst (c,pl)
 		) in
 		) in
@@ -610,15 +633,35 @@ module Abstract = struct
 	let find_from ab pl a b = List.find (Type.unify_from_field ab pl a b) ab.a_from
 	let find_from ab pl a b = List.find (Type.unify_from_field ab pl a b) ab.a_from
 
 
 	let cast_stack = ref []
 	let cast_stack = ref []
-
-	let get_underlying_type a pl =
+	let underlying_type_stack = ref []
+
+	let rec get_underlying_type a pl =
+		let maybe_recurse t =
+			underlying_type_stack := a :: !underlying_type_stack;
+			let t = match follow t with
+				| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
+					if List.mem a !underlying_type_stack then begin
+						let s = String.concat " -> " (List.map (fun a -> s_type_path a.a_path) (List.rev (a :: !underlying_type_stack))) in
+						(* technically this should be done at type declaration level *)
+						error ("Abstract chain detected: " ^ s) a.a_pos
+					end;
+					get_underlying_type a tl
+				| _ ->
+					t
+			in
+			underlying_type_stack := List.tl !underlying_type_stack;
+			t
+		in
 		try
 		try
 			if not (Meta.has Meta.MultiType a.a_meta) then raise Not_found;
 			if not (Meta.has Meta.MultiType a.a_meta) then raise Not_found;
 			let m = mk_mono() in
 			let m = mk_mono() in
 			let _ = find_to a pl m in
 			let _ = find_to a pl m in
-			follow m
+			maybe_recurse (follow m)
 		with Not_found ->
 		with Not_found ->
-			apply_params a.a_types pl a.a_this
+			if Meta.has Meta.CoreType a.a_meta then
+				t_dynamic
+			else
+				maybe_recurse (apply_params a.a_types pl a.a_this)
 
 
 	let make_static_call ctx c cf a pl args t p =
 	let make_static_call ctx c cf a pl args t p =
 		let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
 		let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
@@ -684,10 +727,21 @@ module Abstract = struct
 
 
 	let find_multitype_specialization a pl p =
 	let find_multitype_specialization a pl p =
 		let m = mk_mono() in
 		let m = mk_mono() in
-		let at = apply_params a.a_types pl a.a_this in
+		let tl = match Meta.get Meta.MultiType a.a_meta with
+			| _,[],_ -> pl
+			| _,el,_ ->
+				let relevant = Hashtbl.create 0 in
+				List.iter (fun e -> match fst e with
+					| EConst(Ident s) -> Hashtbl.replace relevant s true
+					| _ -> error "Type parameter expected" (pos e)
+				) el;
+				let tl = List.map2 (fun (n,_) t -> if Hashtbl.mem relevant n || not (has_mono t) then t else t_dynamic) a.a_types pl in
+				tl
+		in
 		let _,cfo =
 		let _,cfo =
-			try find_to a pl m
+			try find_to a tl m
 			with Not_found ->
 			with Not_found ->
+				let at = apply_params a.a_types pl a.a_this in
 				let st = s_type (print_context()) at in
 				let st = s_type (print_context()) at in
 				if has_mono at then
 				if has_mono at then
 					error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
 					error ("Type parameters of multi type abstracts must be known (for " ^ st ^ ")") p
@@ -1141,10 +1195,9 @@ let set_default ctx a c p =
 	mk (TIf (mk_parent (mk cond ctx.basic.tbool p), mk (TBinop (OpAssign,ve,mk (TConst c) t p)) t p,None)) ctx.basic.tvoid p
 	mk (TIf (mk_parent (mk cond ctx.basic.tbool p), mk (TBinop (OpAssign,ve,mk (TConst c) t p)) t p,None)) ctx.basic.tvoid p
 
 
 let bytes_serialize data =
 let bytes_serialize data =
-	let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%:" in
+	let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" in
 	let tbl = Array.init (String.length b64) (fun i -> String.get b64 i) in
 	let tbl = Array.init (String.length b64) (fun i -> String.get b64 i) in
-	let str = Base64.str_encode ~tbl data in
-	"s" ^ string_of_int (String.length str) ^ ":" ^ str
+	Base64.str_encode ~tbl data
 
 
 (*
 (*
 	Tells if the constructor might be called without any issue whatever its parameters
 	Tells if the constructor might be called without any issue whatever its parameters

+ 32 - 2
common.ml

@@ -220,6 +220,7 @@ module Define = struct
 		| SwfPreloaderFrame
 		| SwfPreloaderFrame
 		| SwfProtected
 		| SwfProtected
 		| SwfScriptTimeout
 		| SwfScriptTimeout
+		| SwfUseDoAbc
 		| Sys
 		| Sys
 		| Unsafe
 		| Unsafe
 		| UseNekoc
 		| UseNekoc
@@ -289,6 +290,7 @@ module Define = struct
 		| SwfPreloaderFrame -> ("swf_preloader_frame", "Insert empty first frame in swf")
 		| SwfPreloaderFrame -> ("swf_preloader_frame", "Insert empty first frame in swf")
 		| SwfProtected -> ("swf_protected","Compile Haxe private as protected in the SWF instead of public")
 		| SwfProtected -> ("swf_protected","Compile Haxe private as protected in the SWF instead of public")
 		| SwfScriptTimeout -> ("swf_script_timeout", "Maximum ActionScript processing time before script stuck dialog box displays (in seconds)")
 		| SwfScriptTimeout -> ("swf_script_timeout", "Maximum ActionScript processing time before script stuck dialog box displays (in seconds)")
+		| SwfUseDoAbc -> ("swf_use_doabc", "Use DoAbc swf-tag instead of DoAbcDefine")
 		| Sys -> ("sys","Defined for all system platforms")
 		| Sys -> ("sys","Defined for all system platforms")
 		| Unsafe -> ("unsafe","Allow unsafe code when targeting C#")
 		| Unsafe -> ("unsafe","Allow unsafe code when targeting C#")
 		| UseNekoc -> ("use_nekoc","Use nekoc compiler instead of internal one")
 		| UseNekoc -> ("use_nekoc","Use nekoc compiler instead of internal one")
@@ -320,6 +322,7 @@ module MetaInfo = struct
 	let to_string = function
 	let to_string = function
 		| Abstract -> ":abstract",("Sets the underlying class implementation as 'abstract'",[Platforms [Java;Cs]])
 		| Abstract -> ":abstract",("Sets the underlying class implementation as 'abstract'",[Platforms [Java;Cs]])
 		| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
 		| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
+		| Accessor -> ":accessor",("Used internally by DCE to mark property accessors",[UsedOn TClassField;Internal])
 		| Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
 		| Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
 		| Annotation -> ":annotation",("Annotation (@interface) definitions on -java-lib imports will be annotated with this metadata. Has no effect on types compiled by Haxe",[Platform Java; UsedOn TClass])
 		| Annotation -> ":annotation",("Annotation (@interface) definitions on -java-lib imports will be annotated with this metadata. Has no effect on types compiled by Haxe",[Platform Java; UsedOn TClass])
 		| ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
 		| ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
@@ -360,6 +363,7 @@ module MetaInfo = struct
 		| FunctionCode -> ":functionCode",("",[Platform Cpp])
 		| FunctionCode -> ":functionCode",("",[Platform Cpp])
 		| FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
 		| FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
 		| Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
 		| Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
+		| GenericBuild -> ":genericBuild",("Builds instances of a type using the specified macro",[UsedOn TClass])
 		| Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
 		| Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
 		| Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
 		| Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
 		| HaxeGeneric -> ":haxeGeneric",("Used internally to annotate non-native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
 		| HaxeGeneric -> ":haxeGeneric",("Used internally to annotate non-native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
@@ -381,7 +385,7 @@ module MetaInfo = struct
 		| Macro -> ":macro",("(deprecated)",[])
 		| Macro -> ":macro",("(deprecated)",[])
 		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
 		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
 		| MergeBlock -> ":mergeBlock",("Internally used by typer to mark block that should be merged into the outer scope",[Internal])
 		| MergeBlock -> ":mergeBlock",("Internally used by typer to mark block that should be merged into the outer scope",[Internal])
-		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract])
+		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract; HasParam "Relevant type parameters"])
 		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
 		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
 		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]])
 		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]])
 		| NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
 		| NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
@@ -732,7 +736,33 @@ let flash_versions = List.map (fun v ->
 	let maj = int_of_float v in
 	let maj = int_of_float v in
 	let min = int_of_float (mod_float (v *. 10.) 10.) in
 	let min = int_of_float (mod_float (v *. 10.) 10.) in
 	v, string_of_int maj ^ (if min = 0 then "" else "_" ^ string_of_int min)
 	v, string_of_int maj ^ (if min = 0 then "" else "_" ^ string_of_int min)
-) [9.;10.;10.1;10.2;10.3;11.;11.1;11.2;11.3;11.4;11.5;11.6;11.7;11.8]
+) [9.;10.;10.1;10.2;10.3;11.;11.1;11.2;11.3;11.4;11.5;11.6;11.7;11.8;11.9;12.0;12.1;12.2;12.3;12.4;12.5]
+
+let flash_version_tag = function
+	| 6. -> 6
+	| 7. -> 7
+	| 8. -> 8
+	| 9. -> 9
+	| 10. | 10.1 -> 10
+	| 10.2 -> 11
+	| 10.3 -> 12
+	| 11. -> 13
+	| 11.1 -> 14
+	| 11.2 -> 15
+	| 11.3 -> 16
+	| 11.4 -> 17
+	| 11.5 -> 18
+	| 11.6 -> 19
+	| 11.7 -> 20
+	| 11.8 -> 21
+	| 11.9 -> 22
+	| 12.0 -> 23
+	| 12.1 -> 24
+	| 12.2 -> 25
+	| 12.3 -> 26
+	| 12.4 -> 27
+	| 12.5 -> 28
+	| v -> failwith ("Invalid SWF version " ^ string_of_float v)
 
 
 let raw_defined ctx v =
 let raw_defined ctx v =
 	PMap.mem v ctx.defines
 	PMap.mem v ctx.defines

+ 45 - 5
dce.ml

@@ -62,6 +62,10 @@ let keep_whole_class dce c =
 		| { cl_path = [],"Array" } -> not (dce.com.platform = Js)
 		| { cl_path = [],"Array" } -> not (dce.com.platform = Js)
 		| _ -> false)
 		| _ -> false)
 
 
+let keep_whole_enum dce en =
+	Meta.has Meta.Keep en.e_meta
+	|| not (dce.full || is_std_file dce en.e_module.m_extra.m_file || has_meta Meta.Dce en.e_meta)
+
 (* check if a field is kept *)
 (* check if a field is kept *)
 let keep_field dce cf =
 let keep_field dce cf =
 	Meta.has Meta.Keep cf.cf_meta
 	Meta.has Meta.Keep cf.cf_meta
@@ -157,7 +161,11 @@ and mark_t dce p t =
 			mark_enum dce e;
 			mark_enum dce e;
 			List.iter (mark_t dce p) pl
 			List.iter (mark_t dce p) pl
 		| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
 		| TAbstract(a,pl) when Meta.has Meta.MultiType a.a_meta ->
-			mark_t dce p (snd (Codegen.Abstract.find_multitype_specialization a pl p))
+			begin try
+				mark_t dce p (snd (Codegen.Abstract.find_multitype_specialization a pl p))
+			with Typecore.Error _ ->
+				()
+			end
 		| TAbstract(a,pl) ->
 		| TAbstract(a,pl) ->
 			mark_abstract dce a;
 			mark_abstract dce a;
 			List.iter (mark_t dce p) pl
 			List.iter (mark_t dce p) pl
@@ -213,8 +221,11 @@ let rec to_string dce t = match t with
 			dce.ts_stack <- t :: dce.ts_stack;
 			dce.ts_stack <- t :: dce.ts_stack;
 			to_string dce (apply_params tt.t_types tl tt.t_type)
 			to_string dce (apply_params tt.t_types tl tt.t_type)
 		end
 		end
-	| TAbstract(a,tl) ->
-		to_string dce (Codegen.Abstract.get_underlying_type a tl)
+	| TAbstract({a_impl = Some c} as a,tl) ->
+		if Meta.has Meta.CoreType a.a_meta then
+			field dce c "toString" false
+		else
+			to_string dce (Codegen.Abstract.get_underlying_type a tl)
 	| TMono r ->
 	| TMono r ->
 		(match !r with
 		(match !r with
 		| Some t -> to_string dce t
 		| Some t -> to_string dce t
@@ -226,7 +237,7 @@ let rec to_string dce t = match t with
 			()
 			()
 		else
 		else
 			to_string dce t
 			to_string dce t
-	| TEnum _ | TFun _ | TAnon _ ->
+	| TEnum _ | TFun _ | TAnon _ | TAbstract({a_impl = None},_) ->
 		(* if we to_string these it does not imply that we need all its sub-types *)
 		(* if we to_string these it does not imply that we need all its sub-types *)
 		()
 		()
 
 
@@ -403,6 +414,8 @@ let run com main full =
 				| Some cf -> loop false cf
 				| Some cf -> loop false cf
 				| None -> ()
 				| None -> ()
 			end
 			end
+		| TEnumDecl en when keep_whole_enum dce en ->
+			mark_enum dce en
 		| _ ->
 		| _ ->
 			()
 			()
 	) com.types;
 	) com.types;
@@ -440,12 +453,38 @@ let run com main full =
 		| (TClassDecl c) as mt :: l when keep_whole_class dce c ->
 		| (TClassDecl c) as mt :: l when keep_whole_class dce c ->
 			loop (mt :: acc) l
 			loop (mt :: acc) l
 		| (TClassDecl c) as mt :: l ->
 		| (TClassDecl c) as mt :: l ->
+			let check_property cf stat =
+				let add_accessor_metadata cf =
+					if not (Meta.has Meta.Accessor cf.cf_meta) then cf.cf_meta <- (Meta.Accessor,[],c.cl_pos) :: cf.cf_meta
+				in
+				begin match cf.cf_kind with
+				| Var {v_read = AccCall} ->
+					begin try
+						add_accessor_metadata (PMap.find ("get_" ^ cf.cf_name) (if stat then c.cl_statics else c.cl_fields))
+					with Not_found ->
+						()
+					end
+				| _ ->
+					()
+				end;
+				begin match cf.cf_kind with
+				| Var {v_write = AccCall} ->
+					begin try
+						add_accessor_metadata (PMap.find ("set_" ^ cf.cf_name) (if stat then c.cl_statics else c.cl_fields))
+					with Not_found ->
+						()
+					end
+				| _ ->
+					()
+				end;
+			in
 			(* add :keep so subsequent filter calls do not process class fields again *)
 			(* add :keep so subsequent filter calls do not process class fields again *)
 			c.cl_meta <- (Meta.Keep,[],c.cl_pos) :: c.cl_meta;
 			c.cl_meta <- (Meta.Keep,[],c.cl_pos) :: c.cl_meta;
  			c.cl_ordered_statics <- List.filter (fun cf ->
  			c.cl_ordered_statics <- List.filter (fun cf ->
 				let b = keep_field dce cf in
 				let b = keep_field dce cf in
 				if not b then begin
 				if not b then begin
 					if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
 					if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
+					check_property cf true;
 					c.cl_statics <- PMap.remove cf.cf_name c.cl_statics;
 					c.cl_statics <- PMap.remove cf.cf_name c.cl_statics;
 				end;
 				end;
 				b
 				b
@@ -454,6 +493,7 @@ let run com main full =
 				let b = keep_field dce cf in
 				let b = keep_field dce cf in
 				if not b then begin
 				if not b then begin
 					if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
 					if dce.debug then print_endline ("[DCE] Removed field " ^ (s_type_path c.cl_path) ^ "." ^ (cf.cf_name));
+					check_property cf false;
 					c.cl_fields <- PMap.remove cf.cf_name c.cl_fields;
 					c.cl_fields <- PMap.remove cf.cf_name c.cl_fields;
 				end;
 				end;
 				b
 				b
@@ -470,7 +510,7 @@ let run com main full =
 					if dce.debug then print_endline ("[DCE] Removed class " ^ (s_type_path c.cl_path));
 					if dce.debug then print_endline ("[DCE] Removed class " ^ (s_type_path c.cl_path));
 					loop acc l)
 					loop acc l)
 			end
 			end
- 		| (TEnumDecl e) as mt :: l when Meta.has Meta.Used e.e_meta || Meta.has Meta.Keep e.e_meta || e.e_extern || not (dce.full || is_std_file dce e.e_module.m_extra.m_file || has_meta Meta.Dce e.e_meta) ->
+ 		| (TEnumDecl en) as mt :: l when Meta.has Meta.Used en.e_meta || en.e_extern || keep_whole_enum dce en ->
 			loop (mt :: acc) l
 			loop (mt :: acc) l
 		| TEnumDecl e :: l ->
 		| TEnumDecl e :: l ->
 			if dce.debug then print_endline ("[DCE] Removed enum " ^ (s_type_path e.e_path));
 			if dce.debug then print_endline ("[DCE] Removed enum " ^ (s_type_path e.e_path));

+ 40 - 18
doc/CHANGES.txt

@@ -1,42 +1,64 @@
 2013-??-??: 3.1.0
 2013-??-??: 3.1.0
+
+	New features:
+
 	all : allowed null-patterns in pattern matching
 	all : allowed null-patterns in pattern matching
-	all : optimized pattern matching output
 	all : allowed extractors in pattern matching using => syntax
 	all : allowed extractors in pattern matching using => syntax
-	all : added length field to BytesBuffer, BytesOutput, BytesInput and StringBuf
-	all : evaluate conditional expressions in @:require
-	all : allowed (expr : type) syntax (ECheckType)
-	all : support abstract types in haxe.rtti.XmlParser
 	all : allowed extending generic type parameters
 	all : allowed extending generic type parameters
-	all : added EnumValue.match
-	all : added Std.instance
-	all : allowed recursive type parameter constraints
+	all : allowed (expr : type) syntax (ECheckType)
 	all : allowed @:enum and @:forward on abstracts
 	all : allowed @:enum and @:forward on abstracts
-	all : improved support of custom @:coreType abstracts
 	all : allowed using abstracts as static extension
 	all : allowed using abstracts as static extension
 	all : allowed Class.new
 	all : allowed Class.new
-	all : inlining a parameter which has side effects will not remove it even if not used
-	all : implemented constraints check on enum and enum field type parameters
-	all : fixed memory leak in compilation server and optimized caching in general
+	all : added EnumValue.match
+	all : allow multiple structural extension using { > T1, > T2, fields }
+	all : inline array and structure declarations if possible
+	cs : added -net-lib
+	js : added -D js-flatten
+
+	Standard Library:
+
+	all : support abstract types in haxe.rtti.XmlParser
+	all : added Std.instance
+	all : added length field to BytesBuffer, BytesOutput, BytesInput and StringBuf
 	all : added UInt for all targets
 	all : added UInt for all targets
 	all : added Array.indexOf and Array.lastIndexOf
 	all : added Array.indexOf and Array.lastIndexOf
 	all : added haxe.xml.Printer
 	all : added haxe.xml.Printer
 	all : added haxe.Int32 as abstract type
 	all : added haxe.Int32 as abstract type
+	all : added haxe.format.JsonParser/Printer
+
+	General improvements and optimizations:
+
+	all : optimized pattern matching output
+	all : allowed recursive type parameter constraints
+	all : improved support of custom @:coreType abstracts
+	all : evaluate conditional expressions in @:require
 	all : improved inline constructors by detecting more cases where it can be applied
 	all : improved inline constructors by detecting more cases where it can be applied
-	all : allow multiple structural extension using { > T1, > T2, fields }
-	js : window and console are reserved words. Access them with __js__ instead of untyped.
-	js : added -D js-flatten
 	js : improved inlining
 	js : improved inlining
 	js : always use JSON extern (compile with -D old-browser to disable)
 	js : always use JSON extern (compile with -D old-browser to disable)
 	cpp : improved side-effect detection
 	cpp : improved side-effect detection
-	cs : added -net-lib
+
+	Bugfixes:
+
+	all : inlining a parameter which has side effects will not remove it even if not used
+	all : implemented constraints check on enum and enum field type parameters
+	all : fixed memory leak in compilation server and optimized caching in general
+	all : fixed issue with invalid lowercase class name in Windows completion
+	js : window and console are reserved words. Access them with __js__ instead of untyped.
+	flash : fixed font embedding with UTF8 chars
+	flash : give error if non-nullable basic types are skipped in a call
+
+	Macro features and changes:
+
 	macro : add Context.onAfterGenerate
 	macro : add Context.onAfterGenerate
+	macro : add Context.typeExpr
+	macro : add Context.getExpectedType
 	macro : allowed $v{(c:Float|Int|String)}
 	macro : allowed $v{(c:Float|Int|String)}
 	macro : resolve error line number in external files
 	macro : resolve error line number in external files
 	macro : rewrote macros used as static extension
 	macro : rewrote macros used as static extension
 	macro : exposed typed AST
 	macro : exposed typed AST
+	macro : added @:genericBuild
 	macro : [breaking] first argument of ComplexType.TExtend is now Array<TypePath> instead of TypePath
 	macro : [breaking] first argument of ComplexType.TExtend is now Array<TypePath> instead of TypePath
-	flash : fixed font embedding with UTF8 chars
-	flash : give error if non-nullable basic types are skipped in a call
+	macro : improved expression printing
 
 
 2013-09-25: 3.0.1
 2013-09-25: 3.0.1
 	all : minor DCE bug fix
 	all : minor DCE bug fix

+ 1 - 1
doc/extract.hxml

@@ -1,6 +1,6 @@
 -debug
 -debug
 -swf-lib library.swf
 -swf-lib library.swf
 -swf test.swf
 -swf test.swf
--swf-version 11.7
+-swf-version 11.8
 --macro patchTypes("../doc/extract.patch")
 --macro patchTypes("../doc/extract.patch")
 --gen-hx-classes
 --gen-hx-classes

+ 4 - 2
doc/extract.patch

@@ -879,7 +879,7 @@ flash.globalization.StringTools.lastOperationStatus : LastOperationStatus;
 @:require(flash10_2) flash.media.Microphone.enhancedOptions;
 @:require(flash10_2) flash.media.Microphone.enhancedOptions;
 @:require(flash10_2) static flash.media.Microphone.getEnhancedMicrophone;
 @:require(flash10_2) static flash.media.Microphone.getEnhancedMicrophone;
 
 
-@:require(flash10_2) static flash.system.Capabilities.allowsFullScreen;
+@:require(flash11) static flash.system.Capabilities.allowsFullScreen;
 
 
 @:require(flash10_2) static flash.ui.Keyboard.AUDIO;
 @:require(flash10_2) static flash.ui.Keyboard.AUDIO;
 @:require(flash10_2) static flash.ui.Keyboard.BACK;
 @:require(flash10_2) static flash.ui.Keyboard.BACK;
@@ -1149,7 +1149,6 @@ flash.display.JPEGXREncoderOptions.colorSpace : BitmapEncodingColorSpace;
 
 
 // 11.4
 // 11.4
 
 
-@:require(flash11_4) flash.display3D.Context3D.createRectangleTexture
 @:require(flash11_4) flash.display.BitmapData.copyPixelsToByteArray;
 @:require(flash11_4) flash.display.BitmapData.copyPixelsToByteArray;
 
 
 @:require(flash11_4) flash.concurrent.Mutex;
 @:require(flash11_4) flash.concurrent.Mutex;
@@ -1222,3 +1221,6 @@ flash.display3D.Context3D.$mipfilter : Context3DMipFilter;
 @:require(flash11_7) flash.system.AuthorizedFeaturesLoader.loadAuthorizedFeaturesFromData;
 @:require(flash11_7) flash.system.AuthorizedFeaturesLoader.loadAuthorizedFeaturesFromData;
 
 
 
 
+@:require(flash11_8) flash.display.DisplayObjectContainer.stopAllMovieClips
+@:require(flash11_8) flash.display3D.Context3D.createRectangleTexture
+

+ 10 - 3
filters.ml

@@ -71,6 +71,8 @@ let handle_side_effects com gen_temp e =
 		match e.eexpr with
 		match e.eexpr with
 		| TBlock el ->
 		| TBlock el ->
 			{e with eexpr = TBlock (block loop el)}
 			{e with eexpr = TBlock (block loop el)}
+		| TCall({eexpr = TLocal v},_) when Meta.has Meta.Unbound v.v_meta ->
+			e
 		| TCall(e1,el) ->
 		| TCall(e1,el) ->
 			let e1 = loop e1 in
 			let e1 = loop e1 in
 			{e with eexpr = TCall(e1,ordered_list el)}
 			{e with eexpr = TCall(e1,ordered_list el)}
@@ -119,13 +121,18 @@ let handle_side_effects com gen_temp e =
 		let rec no_side_effect e = match e.eexpr with
 		let rec no_side_effect e = match e.eexpr with
 			| TNew _ | TCall _ | TArrayDecl _ | TObjectDecl _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) ->
 			| TNew _ | TCall _ | TArrayDecl _ | TObjectDecl _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) ->
 				bind e;
 				bind e;
+			| TIf _ | TTry _ | TSwitch _ ->
+				(* Technically these are not side-effects, but we have to move them out anyway because their blocks code have side-effects.
+				   This also probably improves readability of the generated code. We can ignore TWhile and TFor because their type is Void,
+				   so they could never appear in a place where side-effects matter. *)
+				bind e
 			| TBinop(op,e1,e2) when Optimizer.has_side_effect e1 || Optimizer.has_side_effect e2 ->
 			| TBinop(op,e1,e2) when Optimizer.has_side_effect e1 || Optimizer.has_side_effect e2 ->
 				bind e;
 				bind e;
 			| TConst _ | TLocal _ | TTypeExpr _ | TFunction _
 			| TConst _ | TLocal _ | TTypeExpr _ | TFunction _
 			| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) ->
 			| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) ->
 				e
 				e
 			| TBlock _ ->
 			| TBlock _ ->
-				loop e
+				bind e
 			| _ ->
 			| _ ->
 				Type.map_expr no_side_effect e
 				Type.map_expr no_side_effect e
 		in
 		in
@@ -203,7 +210,7 @@ let promote_complex_rhs ctx e =
 		List.rev !r
 		List.rev !r
 	and find e = match e.eexpr with
 	and find e = match e.eexpr with
 		| TReturn (Some e1) -> loop (fun e -> {e with eexpr = TReturn (Some e)}) e1
 		| TReturn (Some e1) -> loop (fun e -> {e with eexpr = TReturn (Some e)}) e1
-		| TBinop(OpAssign, ({eexpr = TLocal _ | TField _ | TArray _} as e1), e2) -> loop (fun er -> {e with eexpr = TBinop(OpAssign, e1, er)}) e2
+		| TBinop(OpAssign | OpAssignOp _ as op, ({eexpr = TLocal _ | TField _ | TArray _} as e1), e2) -> loop (fun er -> {e with eexpr = TBinop(op, e1, er)}) e2
 		| TBlock(el) -> {e with eexpr = TBlock (block el)}
 		| TBlock(el) -> {e with eexpr = TBlock (block el)}
 		| _ -> Type.map_expr find e
 		| _ -> Type.map_expr find e
 	in
 	in
@@ -672,7 +679,7 @@ let rename_local_vars com e =
 	in
 	in
 	let save() =
 	let save() =
 		let old = !vars in
 		let old = !vars in
-		if cfg.pf_unique_locals then (fun() -> ()) else (fun() -> vars := if !rebuild_vars then rebuild old else old)
+		if cfg.pf_unique_locals || not cfg.pf_locals_scope then (fun() -> ()) else (fun() -> vars := if !rebuild_vars then rebuild old else old)
 	in
 	in
 	let rename vars v =
 	let rename vars v =
 		let count = ref 1 in
 		let count = ref 1 in

+ 23 - 3
genas3.ml

@@ -119,6 +119,22 @@ let reserved =
 let s_ident n =
 let s_ident n =
 	if Hashtbl.mem reserved n then "_" ^ n else n
 	if Hashtbl.mem reserved n then "_" ^ n else n
 
 
+let valid_as3_ident s =
+	try
+		for i = 0 to String.length s - 1 do
+			match String.unsafe_get s i with
+			| 'a'..'z' | 'A'..'Z' | '$' | '_' -> ()
+			| '0'..'9' when i > 0 -> ()
+			| _ -> raise Exit
+		done;
+		true
+	with Exit ->
+		false
+
+let anon_field s =
+	let s = s_ident s in
+	if not (valid_as3_ident s) then "\"" ^ s ^ "\"" else s
+
 let rec create_dir acc = function
 let rec create_dir acc = function
 	| [] -> ()
 	| [] -> ()
 	| d :: l ->
 	| d :: l ->
@@ -246,7 +262,7 @@ let rec type_str ctx t p =
 	| TInst (c,_) ->
 	| TInst (c,_) ->
 		(match c.cl_kind with
 		(match c.cl_kind with
 		| KNormal | KGeneric | KGenericInstance _ | KAbstractImpl _ -> s_path ctx false c.cl_path p
 		| KNormal | KGeneric | KGenericInstance _ | KAbstractImpl _ -> s_path ctx false c.cl_path p
-		| KTypeParameter _ | KExtension _ | KExpr _ | KMacroType -> "*")
+		| KTypeParameter _ | KExtension _ | KExpr _ | KMacroType | KGenericBuild _ -> "*")
 	| TFun _ ->
 	| TFun _ ->
 		"Function"
 		"Function"
 	| TMono r ->
 	| TMono r ->
@@ -696,7 +712,7 @@ and gen_expr ctx e =
 		handle_break();
 		handle_break();
 	| TObjectDecl fields ->
 	| TObjectDecl fields ->
 		spr ctx "{ ";
 		spr ctx "{ ";
-		concat ctx ", " (fun (f,e) -> print ctx "%s : " (s_ident f); gen_value ctx e) fields;
+		concat ctx ", " (fun (f,e) -> print ctx "%s : " (anon_field f); gen_value ctx e) fields;
 		spr ctx "}"
 		spr ctx "}"
 	| TFor (v,it,e) ->
 	| TFor (v,it,e) ->
 		let handle_break = handle_break ctx e in
 		let handle_break = handle_break ctx e in
@@ -930,7 +946,11 @@ let generate_field ctx static f =
 			print ctx "]";
 			print ctx "]";
 		| _ -> ()
 		| _ -> ()
 	) f.cf_meta;
 	) f.cf_meta;
-	let public = f.cf_public || Hashtbl.mem ctx.get_sets (f.cf_name,static) || (f.cf_name = "main" && static) || f.cf_name = "resolve" || Ast.Meta.has Ast.Meta.Public f.cf_meta in
+	let public = f.cf_public || Hashtbl.mem ctx.get_sets (f.cf_name,static) || (f.cf_name = "main" && static)
+	    || f.cf_name = "resolve" || Ast.Meta.has Ast.Meta.Public f.cf_meta
+	    (* consider all abstract methods public to avoid issues with inlined private access *)
+	    || (match ctx.curclass.cl_kind with KAbstractImpl _ -> true | _ -> false)
+	in
 	let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in
 	let rights = (if static then "static " else "") ^ (if public then "public" else "protected") in
 	let p = ctx.curclass.cl_pos in
 	let p = ctx.curclass.cl_pos in
 	match f.cf_expr, f.cf_kind with
 	match f.cf_expr, f.cf_kind with

+ 11 - 3
gencommon.ml

@@ -2766,7 +2766,7 @@ struct
 				| TArray ({ eexpr = TLocal ({ v_extra = Some( _ :: _, _) } as v) }, _) -> (* captured transformation *)
 				| TArray ({ eexpr = TLocal ({ v_extra = Some( _ :: _, _) } as v) }, _) -> (* captured transformation *)
 					(match tparam_anon_acc with
 					(match tparam_anon_acc with
 					| None -> Type.map_expr run e
 					| None -> Type.map_expr run e
-					| Some tparam_anon_acc -> tparam_anon_acc v e)
+          | Some tparam_anon_acc -> tparam_anon_acc v e)
         | TCall( { eexpr = TField(_, FEnum _) }, _ ) ->
         | TCall( { eexpr = TField(_, FEnum _) }, _ ) ->
           Type.map_expr run e
           Type.map_expr run e
         (* if a TClosure is being call immediately, there's no need to convert it to a TClosure *)
         (* if a TClosure is being call immediately, there's no need to convert it to a TClosure *)
@@ -2878,7 +2878,8 @@ struct
   						check_params v.v_type);
   						check_params v.v_type);
 					Hashtbl.add ignored v.v_id v;
 					Hashtbl.add ignored v.v_id v;
 					ignore(Option.map traverse opt)
 					ignore(Option.map traverse opt)
-        | TLocal { v_extra = Some(_ :: _,_) } -> ()
+        | TLocal { v_extra = Some( (_ :: _ as tparams),_) } ->
+          ()
         | TLocal(( { v_capture = true } ) as v) ->
         | TLocal(( { v_capture = true } ) as v) ->
           (if not (Hashtbl.mem ignored v.v_id || Hashtbl.mem ret v.v_id) then begin check_params v.v_type; Hashtbl.replace ret v.v_id expr end);
           (if not (Hashtbl.mem ignored v.v_id || Hashtbl.mem ret v.v_id) then begin check_params v.v_type; Hashtbl.replace ret v.v_id expr end);
         | _ -> Type.iter traverse expr
         | _ -> Type.iter traverse expr
@@ -3074,6 +3075,8 @@ struct
 				let original = apply_params types monos vt in
 				let original = apply_params types monos vt in
 				unify et original;
 				unify et original;
 
 
+        let monos = List.map (fun t -> apply_params types (List.map (fun _ -> t_dynamic) types) t) monos in
+
 				let same_cl t1 t2 = match follow t1, follow t2 with
 				let same_cl t1 t2 = match follow t1, follow t2 with
 					| TInst(c,_), TInst(c2,_) -> c == c2
 					| TInst(c,_), TInst(c2,_) -> c == c2
 					| _ -> false
 					| _ -> false
@@ -6578,6 +6581,11 @@ struct
 
 
         let res2 = alloc_var "res2" basic.tint in
         let res2 = alloc_var "res2" basic.tint in
         let res2_local = mk_local res2 pos in
         let res2_local = mk_local res2 pos in
+        let gte2 = {
+          eexpr = TBinop(Ast.OpGte, res2_local, { eexpr = TConst(TInt(Int32.zero)); etype = basic.tint; epos = pos });
+          etype = basic.tbool;
+          epos = pos;
+        } in
 
 
         let block =
         let block =
         [
         [
@@ -6588,7 +6596,7 @@ struct
               Some({ eexpr = TBlock([
               Some({ eexpr = TBlock([
                 { eexpr = TVar( res2, Some(ctx.rcf_hash_function hash_local snd_hash)); etype = basic.tvoid; epos = pos };
                 { eexpr = TVar( res2, Some(ctx.rcf_hash_function hash_local snd_hash)); etype = basic.tvoid; epos = pos };
                 {
                 {
-                  eexpr = TIf(gte, { eexpr = TBlock([
+                  eexpr = TIf(gte2, { eexpr = TBlock([
                     mk_splice snd_hash res2_local;
                     mk_splice snd_hash res2_local;
                     mk_splice snd_dynamics res2_local
                     mk_splice snd_dynamics res2_local
                   ]); etype = t_dynamic; epos = pos }, None);
                   ]); etype = t_dynamic; epos = pos }, None);

+ 28 - 8
gencpp.ml

@@ -287,7 +287,7 @@ let keyword_remap name =
 	| "BIG_ENDIAN" | "LITTLE_ENDIAN" | "assert" | "NULL" | "wchar_t" | "EOF"
 	| "BIG_ENDIAN" | "LITTLE_ENDIAN" | "assert" | "NULL" | "wchar_t" | "EOF"
 	| "bool" | "const_cast" | "dynamic_cast" | "explicit" | "export" | "mutable" | "namespace"
 	| "bool" | "const_cast" | "dynamic_cast" | "explicit" | "export" | "mutable" | "namespace"
 	| "reinterpret_cast" | "static_cast" | "typeid" | "typename" | "virtual"
 	| "reinterpret_cast" | "static_cast" | "typeid" | "typename" | "virtual"
-	| "_Complex"
+	| "_Complex" | "INFINITY"
 	| "struct" -> "_" ^ name
 	| "struct" -> "_" ^ name
 	| "asm" -> "_asm_"
 	| "asm" -> "_asm_"
 	| x -> x
 	| x -> x
@@ -1446,8 +1446,22 @@ and gen_expression ctx retval expression =
 		if ( cast <> "") then output ")";
 		if ( cast <> "") then output ")";
 		if (op <> "=") then output ")";
 		if (op <> "=") then output ")";
 	in
 	in
+	let rec is_const_string_term expr =
+		match expr.eexpr with
+		| TConst( TString _ ) -> true
+		| TBinop (OpAdd,e1,e2) -> (is_const_string_term e1) && (is_const_string_term e2 )
+		| _ -> false
+	in
+	let rec combine_string_terms expr =
+		match expr.eexpr with
+		| TConst( TString s ) -> s
+		| TBinop (OpAdd,e1,e2) -> (combine_string_terms e1) ^ (combine_string_terms e2 )
+		| _ -> ""
+	in
 	let rec gen_bin_op op expr1 expr2 =
 	let rec gen_bin_op op expr1 expr2 =
 		match op with
 		match op with
+		| Ast.OpAdd when (is_const_string_term expr1) && (is_const_string_term expr2) ->
+			output (str ((combine_string_terms expr1) ^ (combine_string_terms expr2)) )
 		| Ast.OpAssign -> ctx.ctx_assigning <- true;
 		| Ast.OpAssign -> ctx.ctx_assigning <- true;
 								gen_bin_op_string expr1 "=" expr2
 								gen_bin_op_string expr1 "=" expr2
 		| Ast.OpUShr ->
 		| Ast.OpUShr ->
@@ -3033,16 +3047,20 @@ let generate_class_files common_ctx member_types super_deps constructor_deps cla
 			| Some { eexpr = TFunction function_def } -> is_dynamic_haxe_method field
 			| Some { eexpr = TFunction function_def } -> is_dynamic_haxe_method field
 			| _ -> true)
 			| _ -> true)
 		in
 		in
-      let is_readable field =
-			(match field.cf_kind with | Var { v_read = AccNever } | Var { v_read = AccInline } -> false
+		let is_readable field =
+			(match field.cf_kind with
+			| Var { v_read = AccNever } when (is_extern_field field) -> false
+			| Var { v_read = AccInline } -> false
 			| Var _ when is_abstract_impl -> false
 			| Var _ when is_abstract_impl -> false
 			| _ -> true) in
 			| _ -> true) in
-      let is_writable field =
-			(match field.cf_kind with | Var { v_write = AccNever } | Var { v_read = AccInline } -> false
+		let is_writable field =
+			(match field.cf_kind with
+			| Var { v_write = AccNever } when (is_extern_field field) -> false
+			| Var { v_read = AccInline } -> false
 			| Var _ when is_abstract_impl -> false
 			| Var _ when is_abstract_impl -> false
 			| _ -> true) in
 			| _ -> true) in
 
 
-      let reflective field = not (Meta.has Meta.Unreflective field.cf_meta) in
+		let reflective field = not (Meta.has Meta.Unreflective field.cf_meta) in
 		let reflect_fields = List.filter reflective (statics_except_meta @ class_def.cl_ordered_fields) in
 		let reflect_fields = List.filter reflective (statics_except_meta @ class_def.cl_ordered_fields) in
 		let reflect_writable = List.filter is_writable reflect_fields in
 		let reflect_writable = List.filter is_writable reflect_fields in
 		let reflect_readable = List.filter is_readable reflect_fields in
 		let reflect_readable = List.filter is_readable reflect_fields in
@@ -3527,12 +3545,13 @@ let write_resources common_ctx =
 	let idx = ref 0 in
 	let idx = ref 0 in
 	Hashtbl.iter (fun _ data ->
 	Hashtbl.iter (fun _ data ->
 		resource_file#write_i ("static unsigned char __res_" ^ (string_of_int !idx) ^ "[] = {\n");
 		resource_file#write_i ("static unsigned char __res_" ^ (string_of_int !idx) ^ "[] = {\n");
+		resource_file#write_i "0xff, 0xff, 0xff, 0xff,\n";
 		for i = 0 to String.length data - 1 do
 		for i = 0 to String.length data - 1 do
 		let code = Char.code (String.unsafe_get data i) in
 		let code = Char.code (String.unsafe_get data i) in
 			resource_file#write  (Printf.sprintf "0x%.2x, " code);
 			resource_file#write  (Printf.sprintf "0x%.2x, " code);
 			if ( (i mod 10) = 9) then resource_file#write "\n";
 			if ( (i mod 10) = 9) then resource_file#write "\n";
 		done;
 		done;
-		resource_file#write ("};\n");
+		resource_file#write ("0x00 };\n");
 		incr idx;
 		incr idx;
 	) common_ctx.resources;
 	) common_ctx.resources;
 
 
@@ -3542,7 +3561,7 @@ let write_resources common_ctx =
 	Hashtbl.iter (fun name data ->
 	Hashtbl.iter (fun name data ->
 		resource_file#write_i
 		resource_file#write_i
 			("{ " ^ (str name) ^ "," ^ (string_of_int (String.length data)) ^ "," ^
 			("{ " ^ (str name) ^ "," ^ (string_of_int (String.length data)) ^ "," ^
-				"__res_" ^ (string_of_int !idx) ^ " },\n");
+				"__res_" ^ (string_of_int !idx) ^ " + 4 },\n");
 		incr idx;
 		incr idx;
 	) common_ctx.resources;
 	) common_ctx.resources;
 
 
@@ -3572,6 +3591,7 @@ let write_build_data common_ctx filename classes main_deps build_extra exe_name
 	in
 	in
 
 
 	output_string buildfile "<xml>\n";
 	output_string buildfile "<xml>\n";
+	output_string buildfile "<set name=\"HXCPP_API_LEVEL\" value=\"1\" />\n";
 	output_string buildfile "<files id=\"haxe\">\n";
 	output_string buildfile "<files id=\"haxe\">\n";
 	output_string buildfile "<compilerflag value=\"-Iinclude\"/>\n";
 	output_string buildfile "<compilerflag value=\"-Iinclude\"/>\n";
 	List.iter add_class_to_buildfile classes;
 	List.iter add_class_to_buildfile classes;

+ 13 - 1
gencs.ml

@@ -402,6 +402,8 @@ struct
         | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substring" as field) })) }, args )
         | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substring" as field) })) }, args )
         | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substr" as field) })) }, args ) ->
         | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substr" as field) })) }, args ) ->
           { e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) }
           { e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) }
+        | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("toString" as field) })) }, [] ) ->
+          run ef
         | TNew( { cl_path = ([], "String") }, [], [p] ) -> run p (* new String(myString) -> myString *)
         | TNew( { cl_path = ([], "String") }, [], [p] ) -> run p (* new String(myString) -> myString *)
 
 
         | TCast(expr, _) when is_int_float e.etype && not (is_int_float expr.etype) && not (is_null e.etype) ->
         | TCast(expr, _) when is_int_float e.etype && not (is_int_float expr.etype) && not (is_null e.etype) ->
@@ -2293,7 +2295,17 @@ let configure gen =
   DynamicOperators.configure gen
   DynamicOperators.configure gen
     (DynamicOperators.abstract_implementation gen (fun e -> match e.eexpr with
     (DynamicOperators.abstract_implementation gen (fun e -> match e.eexpr with
       | TBinop (Ast.OpEq, e1, e2)
       | TBinop (Ast.OpEq, e1, e2)
-      | TBinop (Ast.OpNotEq, e1, e2) -> should_handle_opeq e1.etype or should_handle_opeq e2.etype
+      | TBinop (Ast.OpNotEq, e1, e2) ->
+        (
+          (* dont touch (v == null) and (null == v) comparisons because they are handled by HardNullableSynf later *)
+          match e1.eexpr, e2.eexpr with
+          | TConst(TNull), _ when is_null_expr e2 ->
+            false
+          | _, TConst(TNull) when is_null_expr e1 ->
+            false
+          | _ ->
+            should_handle_opeq e1.etype or should_handle_opeq e2.etype
+        )
       | TBinop (Ast.OpAssignOp Ast.OpAdd, e1, e2) ->
       | TBinop (Ast.OpAssignOp Ast.OpAdd, e1, e2) ->
         is_dynamic_expr e1 || is_null_expr e1 || is_string e.etype
         is_dynamic_expr e1 || is_null_expr e1 || is_string e.etype
       | TBinop (Ast.OpAdd, e1, e2) -> is_dynamic e1.etype or is_dynamic e2.etype or is_type_param e1.etype or is_type_param e2.etype or is_string e1.etype or is_string e2.etype or is_string e.etype
       | TBinop (Ast.OpAdd, e1, e2) -> is_dynamic e1.etype or is_dynamic e2.etype or is_type_param e1.etype or is_type_param e2.etype or is_string e1.etype or is_string e2.etype or is_string e.etype

+ 4 - 0
genjava.ml

@@ -562,6 +562,8 @@ struct
             | _ ->
             | _ ->
               { e with eexpr = TCall(run efield, List.map run args) }
               { e with eexpr = TCall(run efield, List.map run args) }
           )
           )
+        | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("toString" as field) })) }, [] ) ->
+          run ef
 
 
         | TCast(expr, m) when is_boxed_type e.etype ->
         | TCast(expr, m) when is_boxed_type e.etype ->
           (* let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with *)
           (* let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with *)
@@ -1899,6 +1901,8 @@ let configure gen =
   TArrayTransform.configure gen (TArrayTransform.default_implementation gen (
   TArrayTransform.configure gen (TArrayTransform.default_implementation gen (
   fun e ->
   fun e ->
     match e.eexpr with
     match e.eexpr with
+      | TArray ({ eexpr = TLocal { v_extra = Some( _ :: _, _) } }, _) -> (* captured transformation *)
+        false
       | TArray(e1, e2) ->
       | TArray(e1, e2) ->
         ( match run_follow gen e1.etype with
         ( match run_follow gen e1.etype with
           | TInst({ cl_path = (["java"], "NativeArray") }, _) -> false
           | TInst({ cl_path = (["java"], "NativeArray") }, _) -> false

+ 31 - 11
genjs.ml

@@ -404,6 +404,24 @@ let rec gen_call ctx e el in_value =
 		print ctx " instanceof ";
 		print ctx " instanceof ";
 		gen_value ctx t;
 		gen_value ctx t;
 		spr ctx ")";
 		spr ctx ")";
+	| TLocal { v_name = "__typeof__" },  [o] ->
+		spr ctx "typeof(";
+		gen_value ctx o;
+		spr ctx ")";
+	| TLocal { v_name = "__strict_eq__" } , [x;y] ->
+		(* add extra parenthesis here because of operator precedence *)
+		spr ctx "((";
+		gen_value ctx x;
+		spr ctx ") === ";
+		gen_value ctx y;
+		spr ctx ")";
+	| TLocal { v_name = "__strict_neq__" } , [x;y] ->
+		(* add extra parenthesis here because of operator precedence *)
+		spr ctx "((";
+		gen_value ctx x;
+		spr ctx ") !== ";
+		gen_value ctx y;
+		spr ctx ")";
 	| TLocal ({v_name = "__define_feature__"}), [_;e] ->
 	| TLocal ({v_name = "__define_feature__"}), [_;e] ->
 		gen_expr ctx e
 		gen_expr ctx e
 	| TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse ->
 	| TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse ->
@@ -517,7 +535,7 @@ and gen_expr ctx e =
 	| TBlock el ->
 	| TBlock el ->
 		print ctx "{";
 		print ctx "{";
 		let bend = open_block ctx in
 		let bend = open_block ctx in
-		List.iter (gen_block ctx) el;
+		List.iter (gen_block_element ctx) el;
 		bend();
 		bend();
 		newline ctx;
 		newline ctx;
 		print ctx "}";
 		print ctx "}";
@@ -611,7 +629,7 @@ and gen_expr ctx e =
 		let bend = open_block ctx in
 		let bend = open_block ctx in
 		newline ctx;
 		newline ctx;
 		print ctx "var %s = %s.next()" (ident v.v_name) it;
 		print ctx "var %s = %s.next()" (ident v.v_name) it;
-		gen_block ctx e;
+		gen_block_element ctx e;
 		bend();
 		bend();
 		newline ctx;
 		newline ctx;
 		spr ctx "}";
 		spr ctx "}";
@@ -651,7 +669,7 @@ and gen_expr ctx e =
 					newline ctx;
 					newline ctx;
 					print ctx "var %s = %s" v.v_name vname;
 					print ctx "var %s = %s" v.v_name vname;
 				end;
 				end;
-				gen_block ctx e;
+				gen_block_element ctx e;
 				if !else_block then begin
 				if !else_block then begin
 					newline ctx;
 					newline ctx;
 					print ctx "}";
 					print ctx "}";
@@ -666,7 +684,7 @@ and gen_expr ctx e =
 					newline ctx;
 					newline ctx;
 					print ctx "var %s = %s" v.v_name vname;
 					print ctx "var %s = %s" v.v_name vname;
 				end;
 				end;
-				gen_block ctx e;
+				gen_block_element ctx e;
 				bend();
 				bend();
 				newline ctx;
 				newline ctx;
 				spr ctx "} else ";
 				spr ctx "} else ";
@@ -693,7 +711,7 @@ and gen_expr ctx e =
 					spr ctx ":"
 					spr ctx ":"
 			) el;
 			) el;
 			let bend = open_block ctx in
 			let bend = open_block ctx in
-			gen_block ctx e2;
+			gen_block_element ctx e2;
 			if not (has_return e2) then begin
 			if not (has_return e2) then begin
 				newline ctx;
 				newline ctx;
 				print ctx "break";
 				print ctx "break";
@@ -706,7 +724,7 @@ and gen_expr ctx e =
 		| Some e ->
 		| Some e ->
 			spr ctx "default:";
 			spr ctx "default:";
 			let bend = open_block ctx in
 			let bend = open_block ctx in
-			gen_block ctx e;
+			gen_block_element ctx e;
 			bend();
 			bend();
 			newline ctx;
 			newline ctx;
 		);
 		);
@@ -721,17 +739,19 @@ and gen_expr ctx e =
 		spr ctx ")"
 		spr ctx ")"
 
 
 
 
-and gen_block ?(after=false) ctx e =
+and gen_block_element ?(after=false) ctx e =
 	match e.eexpr with
 	match e.eexpr with
 	| TBlock el ->
 	| TBlock el ->
-		List.iter (gen_block ~after ctx) el
+		List.iter (gen_block_element ~after ctx) el
 	| TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) ->
 	| TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) ->
 		if has_feature ctx f then
 		if has_feature ctx f then
-			gen_block ~after ctx eif
+			gen_block_element ~after ctx eif
 		else (match eelse with
 		else (match eelse with
 			| [] -> ()
 			| [] -> ()
-			| [e] -> gen_block ~after ctx e
+			| [e] -> gen_block_element ~after ctx e
 			| _ -> assert false)
 			| _ -> assert false)
+	| TFunction _ ->
+		gen_block_element ~after ctx (mk (TParenthesis e) e.etype e.epos)
 	| _ ->
 	| _ ->
 		if not after then newline ctx;
 		if not after then newline ctx;
 		gen_expr ctx e;
 		gen_expr ctx e;
@@ -1250,7 +1270,7 @@ let generate com =
 		print ctx "function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }";
 		print ctx "function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }";
 		newline ctx;
 		newline ctx;
 	end;
 	end;
-	List.iter (gen_block ~after:true ctx) (List.rev ctx.inits);
+	List.iter (gen_block_element ~after:true ctx) (List.rev ctx.inits);
 	List.iter (generate_static ctx) (List.rev ctx.statics);
 	List.iter (generate_static ctx) (List.rev ctx.statics);
 	(match com.main with
 	(match com.main with
 	| None -> ()
 	| None -> ()

+ 31 - 28
genswf.ml

@@ -525,26 +525,6 @@ let tag ?(ext=false) d = {
 	tdata = d;
 	tdata = d;
 }
 }
 
 
-let swf_ver = function
-	| 6. -> 6
-	| 7. -> 7
-	| 8. -> 8
-	| 9. -> 9
-	| 10. | 10.1 -> 10
-	| 10.2 -> 11
-	| 10.3 -> 12
-	| 11. -> 13
-	| 11.1 -> 14
-	| 11.2 -> 15
-	| 11.3 -> 16
-	| 11.4 -> 17
-	| 11.5 -> 18
-	| 11.6 -> 19
-	| 11.7 -> 20
-	| 11.8 -> 21
-	| 11.9 -> 22
-	| v -> failwith ("Invalid SWF version " ^ float_repres v)
-
 let convert_header com (w,h,fps,bg) =
 let convert_header com (w,h,fps,bg) =
 	let high = (max w h) * 20 in
 	let high = (max w h) * 20 in
 	let rec loop b =
 	let rec loop b =
@@ -552,7 +532,7 @@ let convert_header com (w,h,fps,bg) =
 	in
 	in
 	let bits = loop 0 in
 	let bits = loop 0 in
 	{
 	{
-		h_version = swf_ver com.flash_version;
+		h_version = Common.flash_version_tag com.flash_version;
 		h_size = {
 		h_size = {
 			rect_nbits = bits + 1;
 			rect_nbits = bits + 1;
 			left = 0;
 			left = 0;
@@ -588,7 +568,8 @@ let build_dependencies t =
 			(match c.cl_kind with KTypeParameter _ -> () | _ -> add_path c.cl_path DKType);
 			(match c.cl_kind with KTypeParameter _ -> () | _ -> add_path c.cl_path DKType);
 			List.iter (add_type_rec (t::l)) pl;
 			List.iter (add_type_rec (t::l)) pl;
 		| TAbstract (a,pl) ->
 		| TAbstract (a,pl) ->
-			add_path a.a_path DKType;
+			if Meta.has Meta.CoreType a.a_meta then
+				add_path a.a_path DKType;
 			List.iter (add_type_rec (t::l)) pl;
 			List.iter (add_type_rec (t::l)) pl;
 		| TFun (pl,t2) ->
 		| TFun (pl,t2) ->
 			List.iter (fun (_,_,t2) -> add_type_rec (t::l) t2) pl;
 			List.iter (fun (_,_,t2) -> add_type_rec (t::l) t2) pl;
@@ -796,6 +777,8 @@ let detect_format data p =
 	| _ ->
 	| _ ->
 		error "Unknown file format" p
 		error "Unknown file format" p
 
 
+open TTFData
+
 let build_swf9 com file swc =
 let build_swf9 com file swc =
 	let boot_name = if swc <> None || Common.defined com Define.HaxeBoot then "haxe" else "boot_" ^ (String.sub (Digest.to_hex (Digest.string (Filename.basename file))) 0 4) in
 	let boot_name = if swc <> None || Common.defined com Define.HaxeBoot then "haxe" else "boot_" ^ (String.sub (Digest.to_hex (Digest.string (Filename.basename file))) 0 4) in
 	let code = Genswf9.generate com boot_name in
 	let code = Genswf9.generate com boot_name in
@@ -820,7 +803,7 @@ let build_swf9 com file swc =
 				hls_fields = [|f|];
 				hls_fields = [|f|];
 			}
 			}
 		) code in
 		) code in
-		[tag (TActionScript3 (None,As3hlparse.flatten inits))]
+		[tag (TActionScript3 ((if Common.defined com Define.SwfUseDoAbc then Some(1,boot_name) else None), As3hlparse.flatten inits))]
 	) in
 	) in
 	let cid = ref 0 in
 	let cid = ref 0 in
 	let classes = ref [{ f9_cid = None; f9_classname = boot_name }] in
 	let classes = ref [{ f9_cid = None; f9_classname = boot_name }] in
@@ -846,11 +829,31 @@ let build_swf9 com file swc =
 					let ch = try open_in_bin file with _ -> error "File not found" p in
 					let ch = try open_in_bin file with _ -> error "File not found" p in
 					let ttf = try TTFParser.parse ch with e -> error ("Error while parsing font " ^ file ^ " : " ^ Printexc.to_string e) p in
 					let ttf = try TTFParser.parse ch with e -> error ("Error while parsing font " ^ file ^ " : " ^ Printexc.to_string e) p in
 					close_in ch;
 					close_in ch;
-					let range_str = match args with
-						| [EConst (String str),_] -> str
-						| _ -> ""
+					let get_string e = match fst e with
+						| EConst (String s) -> Some s
+						| _ -> raise Not_found
 					in
 					in
-					let ttf_swf = TTFSwfWriter.to_swf ttf range_str in
+					let ttf_config = {
+						ttfc_range_str = "";
+						ttfc_font_name = None;
+					} in
+					begin match args with
+						| (EConst (String str),_) :: _ -> ttf_config.ttfc_range_str <- str;
+						| _ -> ()
+					end;
+					begin match args with
+						| _ :: [e] ->
+							begin match fst e with
+								| EObjectDecl fl ->
+									begin try ttf_config.ttfc_font_name <- get_string (List.assoc "fontName" fl)
+									with Not_found -> () end
+								| _ ->
+									()
+							end
+						| _ ->
+							()
+					end;
+					let ttf_swf = TTFSwfWriter.to_swf ttf ttf_config in
 					let ch = IO.output_string () in
 					let ch = IO.output_string () in
 					let b = IO.output_bits ch in
 					let b = IO.output_bits ch in
 					TTFSwfWriter.write_font2 ch b ttf_swf;
 					TTFSwfWriter.write_font2 ch b ttf_swf;
@@ -1031,7 +1034,7 @@ let build_swf9 com file swc =
 
 
 let merge com file priority (h1,tags1) (h2,tags2) =
 let merge com file priority (h1,tags1) (h2,tags2) =
   (* prioritize header+bgcolor for first swf *)
   (* prioritize header+bgcolor for first swf *)
-	let header = if priority then { h2 with h_version = max h2.h_version (swf_ver com.flash_version) } else h1 in
+	let header = if priority then { h2 with h_version = max h2.h_version (Common.flash_version_tag com.flash_version) } else h1 in
 	let tags1 = if priority then List.filter (function { tdata = TSetBgColor _ } -> false | _ -> true) tags1 else tags1 in
 	let tags1 = if priority then List.filter (function { tdata = TSetBgColor _ } -> false | _ -> true) tags1 else tags1 in
   (* remove unused tags *)
   (* remove unused tags *)
 	let use_stage = priority && Common.defined com Define.FlashUseStage in
 	let use_stage = priority && Common.defined com Define.FlashUseStage in

+ 24 - 3
genswf9.ml

@@ -205,7 +205,7 @@ let rec follow_basic t =
 		t
 		t
 	| TType (t,tl) ->
 	| TType (t,tl) ->
 		follow_basic (apply_params t.t_types tl t.t_type)
 		follow_basic (apply_params t.t_types tl t.t_type)
-	| TAbstract (a,pl) when a.a_impl <> None ->
+	| TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) ->
 		follow_basic (apply_params a.a_types pl a.a_this)
 		follow_basic (apply_params a.a_types pl a.a_this)
 	| _ -> t
 	| _ -> t
 
 
@@ -1626,7 +1626,10 @@ and gen_binop ctx retval op e1 e2 t p =
 			let k1 = classify ctx e1.etype in
 			let k1 = classify ctx e1.etype in
 			let k2 = classify ctx e2.etype in
 			let k2 = classify ctx e2.etype in
 			(match k1, k2 with
 			(match k1, k2 with
-			| KInt, KInt | KUInt, KUInt | KInt, KUInt | KUInt, KInt -> write ctx (HOp iop)
+			| KInt, KInt | KUInt, KUInt | KInt, KUInt | KUInt, KInt ->
+				write ctx (HOp iop);
+				let ret = classify ctx t in
+				if ret <> KInt then coerce ctx ret
 			| _ ->
 			| _ ->
 				write ctx (HOp op);
 				write ctx (HOp op);
 				(* add is a generic operation, so let's make sure we don't loose our type in the process *)
 				(* add is a generic operation, so let's make sure we don't loose our type in the process *)
@@ -2031,7 +2034,24 @@ let generate_field_kind ctx f c stat =
 			hlv_value = HVNone;
 			hlv_value = HVNone;
 			hlv_const = false;
 			hlv_const = false;
 		})
 		})
-
+		
+let check_constructor ctx c f =
+	(*
+		check that we don't assign a super Float var before we call super() : will result in NaN
+	*)
+	let rec loop e =
+		Type.iter loop e;
+		match e.eexpr with
+		| TCall ({ eexpr = TConst TSuper },_) -> raise Exit
+		| TBinop (OpAssign,{ eexpr = TField({ eexpr = TConst TThis },FInstance (cc,cf)) },_) when c != cc && (match classify ctx cf.cf_type with KFloat | KDynamic -> true | _ -> false) ->
+			error "You cannot assign some super class vars before calling super() in flash, this will reset them to default value" e.epos
+		| _ -> ()
+	in
+	try
+		loop f.tf_expr
+	with Exit ->
+		()
+		
 let generate_class ctx c =
 let generate_class ctx c =
 	let name = type_path ctx c.cl_path in
 	let name = type_path ctx c.cl_path in
 	ctx.cur_class <- c;
 	ctx.cur_class <- c;
@@ -2054,6 +2074,7 @@ let generate_class ctx c =
 			| Some { eexpr = TFunction fdata } ->
 			| Some { eexpr = TFunction fdata } ->
 				let old = do_debug ctx f.cf_meta in
 				let old = do_debug ctx f.cf_meta in
 				let m = generate_construct ctx fdata c in
 				let m = generate_construct ctx fdata c in
+				check_constructor ctx c fdata;
 				old();
 				old();
 				m
 				m
 			| _ -> assert false
 			| _ -> assert false

+ 2 - 2
genxml.ml

@@ -339,7 +339,7 @@ let generate_type com t =
 		| None ->
 		| None ->
 			n ^ " : " ^ stype t
 			n ^ " : " ^ stype t
 		| Some (Ident "null") ->
 		| Some (Ident "null") ->
-			if is_null t then
+			if is_nullable (notnull t) then
 				"?" ^ n ^ " : " ^ stype (notnull t)
 				"?" ^ n ^ " : " ^ stype (notnull t)
 			else
 			else
 				(* we have not found a default value stored in metadata, let's generate it *)
 				(* we have not found a default value stored in metadata, let's generate it *)
@@ -353,7 +353,7 @@ let generate_type com t =
 	let print_meta ml =
 	let print_meta ml =
 		List.iter (fun (m,pl,_) ->
 		List.iter (fun (m,pl,_) ->
 			match m with
 			match m with
-			| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed -> ()
+			| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed | Meta.FlatEnum -> ()
 			| _ ->
 			| _ ->
 			match pl with
 			match pl with
 			| [] -> p "@%s " (fst (MetaInfo.to_string m))
 			| [] -> p "@%s " (fst (MetaInfo.to_string m))

+ 2 - 0
haxe.hxproj

@@ -134,6 +134,8 @@
     <hidden path="haxe.exe.manifest" />
     <hidden path="haxe.exe.manifest" />
     <hidden path="obj" />
     <hidden path="obj" />
     <hidden path="filters.obj" />
     <hidden path="filters.obj" />
+    <hidden path="filters.cmi" />
+    <hidden path="filters.cmx" />
   </hiddenPaths>
   </hiddenPaths>
   <!-- Executed before build -->
   <!-- Executed before build -->
   <preBuildCommand>make -j4 MSVC=1 FD_OUTPUT=1 -f Makefile.win kill haxe</preBuildCommand>
   <preBuildCommand>make -j4 MSVC=1 FD_OUTPUT=1 -f Makefile.win kill haxe</preBuildCommand>

+ 40 - 9
interp.ml

@@ -110,6 +110,7 @@ type extern_api = {
 	meta_patch : string -> string -> string option -> bool -> unit;
 	meta_patch : string -> string -> string option -> bool -> unit;
 	set_js_generator : (value -> unit) -> unit;
 	set_js_generator : (value -> unit) -> unit;
 	get_local_type : unit -> t option;
 	get_local_type : unit -> t option;
+	get_expected_type : unit -> t option;
 	get_local_method : unit -> string;
 	get_local_method : unit -> string;
 	get_local_using : unit -> tclass list;
 	get_local_using : unit -> tclass list;
 	get_local_vars : unit -> (string, Type.tvar) PMap.t;
 	get_local_vars : unit -> (string, Type.tvar) PMap.t;
@@ -182,6 +183,7 @@ exception Continue
 exception Break of value
 exception Break of value
 exception Return of value
 exception Return of value
 exception Invalid_expr
 exception Invalid_expr
+exception Sys_exit of int
 
 
 (* ---------------------------------------------------------------------- *)
 (* ---------------------------------------------------------------------- *)
 (* UTILS *)
 (* UTILS *)
@@ -263,7 +265,7 @@ let constants =
 	"constructs";"names";"superClass";"interfaces";"fields";"statics";"constructor";"init";"t";
 	"constructs";"names";"superClass";"interfaces";"fields";"statics";"constructor";"init";"t";
 	"gid";"uid";"atime";"mtime";"ctime";"dev";"ino";"nlink";"rdev";"size";"mode";"pos";"len";
 	"gid";"uid";"atime";"mtime";"ctime";"dev";"ino";"nlink";"rdev";"size";"mode";"pos";"len";
 	"binops";"unops";"from";"to";"array";"op";"isPostfix";"impl";
 	"binops";"unops";"from";"to";"array";"op";"isPostfix";"impl";
-	"id";"capture";"extra";"v";"ids";"vars";"en";"overrides"];
+	"id";"capture";"extra";"v";"ids";"vars";"en";"overrides";"status"];
 	h
 	h
 
 
 let h_get = hash "__get" and h_set = hash "__set"
 let h_get = hash "__get" and h_set = hash "__set"
@@ -326,7 +328,7 @@ let parse_float s =
 		if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else
 		if i = String.length s then (if sp = 0 then s else String.sub s sp (i - sp)) else
 		match String.unsafe_get s i with
 		match String.unsafe_get s i with
 		| ' ' when sp = i -> loop (sp + 1) (i + 1)
 		| ' ' when sp = i -> loop (sp + 1) (i + 1)
-		| '0'..'9' | '-' | 'e' | 'E' | '.' -> loop sp (i + 1)
+		| '0'..'9' | '-' | '+' | 'e' | 'E' | '.' -> loop sp (i + 1)
 		| _ -> String.sub s sp (i - sp)
 		| _ -> String.sub s sp (i - sp)
 	in
 	in
 	float_of_string (loop 0 0)
 	float_of_string (loop 0 0)
@@ -1648,7 +1650,7 @@ let std_lib =
 		);
 		);
 		"sys_exit", Fun1 (fun code ->
 		"sys_exit", Fun1 (fun code ->
 			if (get_ctx()).curapi.use_cache() then raise (Typecore.Fatal_error ("",Ast.null_pos));
 			if (get_ctx()).curapi.use_cache() then raise (Typecore.Fatal_error ("",Ast.null_pos));
-			exit (vint code);
+			raise (Sys_exit(vint code));
 		);
 		);
 		"sys_exists", Fun1 (fun file ->
 		"sys_exists", Fun1 (fun file ->
 			VBool (Sys.file_exists (vstring file))
 			VBool (Sys.file_exists (vstring file))
@@ -1774,7 +1776,6 @@ let std_lib =
 				incr pos;
 				incr pos;
 				if !pos >= p && !pos < p + l then UTF8.Buf.add_char buf c;
 				if !pos >= p && !pos < p + l then UTF8.Buf.add_char buf c;
 			) (vstring s);
 			) (vstring s);
-			if !pos < p + l then error();
 			VString (UTF8.Buf.contents buf)
 			VString (UTF8.Buf.contents buf)
 		);
 		);
 		"utf8_get", Fun2 (fun s p ->
 		"utf8_get", Fun2 (fun s p ->
@@ -2400,6 +2401,12 @@ let macro_lib =
 				VNull
 				VNull
 			| _ -> error()
 			| _ -> error()
 		);
 		);
+        "get_resources", Fun0 (fun() ->
+			let res = (ccom()).resources in
+			let h = Hashtbl.create 0 in
+			Hashtbl.iter (fun n v -> Hashtbl.replace h (VString n) (VString v)) res;
+			enc_hash h
+		);
 		"local_module", Fun0 (fun() ->
 		"local_module", Fun0 (fun() ->
 			let m = (get_ctx()).curapi.current_module() in
 			let m = (get_ctx()).curapi.current_module() in
 			VString (Ast.s_type_path m.m_path);
 			VString (Ast.s_type_path m.m_path);
@@ -2409,6 +2416,11 @@ let macro_lib =
 			| None -> VNull
 			| None -> VNull
 			| Some t -> encode_type t
 			| Some t -> encode_type t
 		);
 		);
+		"expected_type", Fun0 (fun() ->
+			match (get_ctx()).curapi.get_expected_type() with
+			| None -> VNull
+			| Some t -> encode_type t
+		);
 		"local_method", Fun0 (fun() ->
 		"local_method", Fun0 (fun() ->
 			VString ((get_ctx()).curapi.get_local_method())
 			VString ((get_ctx()).curapi.get_local_method())
 		);
 		);
@@ -3248,7 +3260,7 @@ and call ctx vthis vfun pl p =
 	ctx.vthis <- vthis;
 	ctx.vthis <- vthis;
 	ctx.callstack <- { cpos = p; cthis = oldthis; cstack = stackpos; cenv = oldenv } :: ctx.callstack;
 	ctx.callstack <- { cpos = p; cthis = oldthis; cstack = stackpos; cenv = oldenv } :: ctx.callstack;
 	ctx.callsize <- oldsize + 1;
 	ctx.callsize <- oldsize + 1;
-	if oldsize > 400 then exc (VString "Stack overflow");
+	if oldsize > 600 then exc (VString "Stack overflow");
 	let ret = (try
 	let ret = (try
 		(match vfun with
 		(match vfun with
 		| VClosure (vl,f) ->
 		| VClosure (vl,f) ->
@@ -3521,6 +3533,7 @@ type enum_index =
 	| ITConstant
 	| ITConstant
 	| IModuleType
 	| IModuleType
 	| IFieldAccess
 	| IFieldAccess
+	| IAnonStatus
 
 
 let enum_name = function
 let enum_name = function
 	| IExpr -> "ExprDef"
 	| IExpr -> "ExprDef"
@@ -3540,9 +3553,10 @@ let enum_name = function
 	| ITConstant -> "TConstant"
 	| ITConstant -> "TConstant"
 	| IModuleType -> "ModuleType"
 	| IModuleType -> "ModuleType"
 	| IFieldAccess -> "FieldAccess"
 	| IFieldAccess -> "FieldAccess"
+	| IAnonStatus -> "AnonStatus"
 
 
 let init ctx =
 let init ctx =
-	let enums = [IExpr;IBinop;IUnop;IConst;ITParam;ICType;IField;IType;IFieldKind;IMethodKind;IVarAccess;IAccess;IClassKind;ITypedExpr;ITConstant;IModuleType;IFieldAccess] in
+	let enums = [IExpr;IBinop;IUnop;IConst;ITParam;ICType;IField;IType;IFieldKind;IMethodKind;IVarAccess;IAccess;IClassKind;ITypedExpr;ITConstant;IModuleType;IFieldAccess;IAnonStatus] in
 	let get_enum_proto e =
 	let get_enum_proto e =
 		match get_path ctx ["haxe";"macro";enum_name e] null_pos with
 		match get_path ctx ["haxe";"macro";enum_name e] null_pos with
 		| VObject e ->
 		| VObject e ->
@@ -4278,7 +4292,8 @@ and encode_class_kind k =
 		| KGeneric -> 4, []
 		| KGeneric -> 4, []
 		| KGenericInstance (cl, params) -> 5, [encode_clref cl; encode_tparams params]
 		| KGenericInstance (cl, params) -> 5, [encode_clref cl; encode_tparams params]
 		| KMacroType -> 6, []
 		| KMacroType -> 6, []
-		| KAbstractImpl a -> 7, [encode_ref a encode_tabstract (fun() -> s_type_path a.a_path)]
+		| KAbstractImpl a -> 7, [encode_abref a]
+		| KGenericBuild cfl -> 8, []
 	) in
 	) in
 	enc_enum IClassKind tag pl
 	enc_enum IClassKind tag pl
 
 
@@ -4311,8 +4326,21 @@ and encode_ttype t =
 and encode_tanon a =
 and encode_tanon a =
 	enc_obj [
 	enc_obj [
 		"fields", encode_pmap_array encode_cfield a.a_fields;
 		"fields", encode_pmap_array encode_cfield a.a_fields;
+		"status", encode_anon_status !(a.a_status);
 	]
 	]
 
 
+and encode_anon_status s =
+	let tag, pl = (match s with
+		| Closed -> 0, []
+		| Opened -> 1, []
+		| Type.Const -> 2, []
+		| Statics cl -> 3, [encode_clref cl]
+		| EnumStatics en -> 4, [encode_enref en]
+		| AbstractStatics ab -> 5, [encode_abref ab]
+	)
+	in
+	enc_enum IAnonStatus tag pl
+
 and encode_tparams pl =
 and encode_tparams pl =
 	enc_array (List.map encode_type pl)
 	enc_array (List.map encode_type pl)
 
 
@@ -4325,6 +4353,9 @@ and encode_enref en =
 and encode_cfref cf =
 and encode_cfref cf =
 	encode_ref cf encode_cfield (fun() -> cf.cf_name)
 	encode_ref cf encode_cfield (fun() -> cf.cf_name)
 
 
+and encode_abref ab =
+	encode_ref ab encode_tabstract (fun() -> s_type_path ab.a_path)
+
 and encode_type t =
 and encode_type t =
 	let rec loop = function
 	let rec loop = function
 		| TMono r ->
 		| TMono r ->
@@ -4356,7 +4387,7 @@ and encode_type t =
 		| TLazy f ->
 		| TLazy f ->
 			loop (!f())
 			loop (!f())
 		| TAbstract (a, pl) ->
 		| TAbstract (a, pl) ->
-			8, [encode_ref a encode_tabstract (fun() -> s_type_path a.a_path); encode_tparams pl]
+			8, [encode_abref a; encode_tparams pl]
 	in
 	in
 	let tag, pl = loop t in
 	let tag, pl = loop t in
 	enc_enum IType tag pl
 	enc_enum IType tag pl
@@ -4436,7 +4467,7 @@ and encode_module_type mt =
 		| TClassDecl c -> 0,[encode_clref c]
 		| TClassDecl c -> 0,[encode_clref c]
 		| TEnumDecl e -> 1,[encode_enref e]
 		| TEnumDecl e -> 1,[encode_enref e]
 		| TTypeDecl t -> 2,[encode_ref t encode_ttype (fun () -> s_type_path t.t_path)]
 		| TTypeDecl t -> 2,[encode_ref t encode_ttype (fun () -> s_type_path t.t_path)]
-		| TAbstractDecl a -> 3,[encode_ref a encode_tabstract (fun () -> s_type_path a.a_path)]
+		| TAbstractDecl a -> 3,[encode_abref a]
 	in
 	in
 	enc_enum IModuleType tag pl
 	enc_enum IModuleType tag pl
 
 

+ 1 - 1
libs

@@ -1 +1 @@
-Subproject commit 87a41172b0afb34df37adfee2c07c1b561e4de63
+Subproject commit 296f0edfa9a73c37b1ddfaec878985cf0a22ba56

+ 10 - 1
main.ml

@@ -927,6 +927,7 @@ try
 	let force_typing = ref false in
 	let force_typing = ref false in
 	let pre_compilation = ref [] in
 	let pre_compilation = ref [] in
 	let interp = ref false in
 	let interp = ref false in
+	let swf_version = ref false in
 	Common.define_value com Define.HaxeVer (float_repres (float_of_int version /. 10000.));
 	Common.define_value com Define.HaxeVer (float_repres (float_of_int version /. 10000.));
 	Common.raw_define com "haxe3";
 	Common.raw_define com "haxe3";
 	Common.define_value com Define.Dce "std";
 	Common.define_value com Define.Dce "std";
@@ -1037,7 +1038,8 @@ try
 			Common.define_value com Define.Dce mode
 			Common.define_value com Define.Dce mode
 		),"[std|full|no] : set the dead code elimination mode");
 		),"[std|full|no] : set the dead code elimination mode");
 		("-swf-version",Arg.Float (fun v ->
 		("-swf-version",Arg.Float (fun v ->
-			com.flash_version <- v;
+			if not !swf_version || com.flash_version < v then com.flash_version <- v;
+			swf_version := true;
 		),"<version> : change the SWF version (6 to 10)");
 		),"<version> : change the SWF version (6 to 10)");
 		("-swf-header",Arg.String (fun h ->
 		("-swf-header",Arg.String (fun h ->
 			try
 			try
@@ -1270,6 +1272,10 @@ try
 		com.error <- error ctx;
 		com.error <- error ctx;
 		com.main_class <- None;
 		com.main_class <- None;
 		let real = get_real_path (!Parser.resume_display).Ast.pfile in
 		let real = get_real_path (!Parser.resume_display).Ast.pfile in
+		(* try to fix issue on windows when get_real_path fails (8.3 DOS names disabled) *)
+		let real = (match List.rev (ExtString.String.nsplit real "\\") with
+		| file :: path when String.length file > 0 && file.[0] >= 'a' && file.[1] <= 'z' -> file.[0] <- char_of_int (int_of_char file.[0] - int_of_char 'a' + int_of_char 'A'); String.concat "\\" (List.rev (file :: path))
+		| _ -> real) in
 		classes := lookup_classes com real;
 		classes := lookup_classes com real;
 		if !classes = [] then begin
 		if !classes = [] then begin
 			if not (Sys.file_exists real) then failwith "Display file does not exist";
 			if not (Sys.file_exists real) then failwith "Display file does not exist";
@@ -1535,6 +1541,9 @@ with
 				raise (Completion c)
 				raise (Completion c)
 			| _ ->
 			| _ ->
 				error ctx ("Could not load module " ^ (Ast.s_type_path (p,c))) Ast.null_pos)
 				error ctx ("Could not load module " ^ (Ast.s_type_path (p,c))) Ast.null_pos)
+	| Interp.Sys_exit i ->
+		ctx.flush();
+		exit i
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" || !global_cache <> None with _ -> true) && not (is_debug_run()) ->
 	| e when (try Sys.getenv "OCAMLRUNPARAM" <> "b" || !global_cache <> None with _ -> true) && not (is_debug_run()) ->
 		error ctx (Printexc.to_string e) Ast.null_pos
 		error ctx (Printexc.to_string e) Ast.null_pos
 
 

+ 88 - 64
matcher.ml

@@ -79,9 +79,10 @@ and pat = {
 }
 }
 
 
 type out = {
 type out = {
-	o_pos : pos;
+	mutable o_pos : pos;
 	o_id : int;
 	o_id : int;
-	o_default : bool;
+	o_catch_all : bool;
+	mutable o_num_paths : int;
 }
 }
 
 
 type pat_vec = pat array * out
 type pat_vec = pat array * out
@@ -102,9 +103,8 @@ type matcher = {
 	dt_lut : dt DynArray.t;
 	dt_lut : dt DynArray.t;
 	dt_cache : (dt,int) Hashtbl.t;
 	dt_cache : (dt,int) Hashtbl.t;
 	mutable dt_count : int;
 	mutable dt_count : int;
-	mutable outcomes : (pat list,out) PMap.t;
+	mutable outcomes : out list;
 	mutable toplevel_or : bool;
 	mutable toplevel_or : bool;
-	mutable used_paths : (int,bool) Hashtbl.t;
 	mutable has_extractor : bool;
 	mutable has_extractor : bool;
 	mutable expr_map : (int,texpr * texpr option) PMap.t;
 	mutable expr_map : (int,texpr * texpr option) PMap.t;
 }
 }
@@ -128,18 +128,20 @@ let mk_st def t p = {
 	st_pos = p;
 	st_pos = p;
 }
 }
 
 
-let mk_out mctx id e eg pl is_default p =
+let mk_out mctx id e eg is_catch_all p =
 	let out = {
 	let out = {
 		o_pos = p;
 		o_pos = p;
 		o_id = id;
 		o_id = id;
-		o_default = is_default;
+		o_catch_all = is_catch_all;
+		o_num_paths = 0;
 	} in
 	} in
-	mctx.outcomes <- PMap.add pl out mctx.outcomes;
+	mctx.outcomes <- out :: mctx.outcomes;
 	mctx.expr_map <- PMap.add id (e,eg) mctx.expr_map;
 	mctx.expr_map <- PMap.add id (e,eg) mctx.expr_map;
 	out
 	out
 
 
-let clone_out mctx out pl p =
-	let out = {out with o_pos = p; } in
+let clone_out mctx out p =
+ 	let out = {out with o_pos = p; } in
+ 	mctx.outcomes <- out :: mctx.outcomes;
 	out
 	out
 
 
 let get_guard mctx id =
 let get_guard mctx id =
@@ -160,17 +162,9 @@ let mk_con cdef t p = {
 	c_pos = p;
 	c_pos = p;
 }
 }
 
 
-let mk_con_pat cdef pl t p = {
-	p_def = PCon(mk_con cdef t p,pl);
-	p_type = t;
-	p_pos = p;
-}
+let mk_con_pat cdef pl t p = mk_pat (PCon(mk_con cdef t p,pl)) t p
 
 
-let mk_any t p = {
-	p_def = PAny;
-	p_type = t;
-	p_pos = p;
-}
+let mk_any t p = mk_pat PAny t p
 
 
 let any = mk_any t_dynamic Ast.null_pos
 let any = mk_any t_dynamic Ast.null_pos
 
 
@@ -384,11 +378,7 @@ let to_pattern ctx e t =
 			begin match get_tuple_types t with
 			begin match get_tuple_types t with
 			| Some tl ->
 			| Some tl ->
 				let pl = List.map (fun (_,_,t) -> mk_any t p) tl in
 				let pl = List.map (fun (_,_,t) -> mk_any t p) tl in
-				{
-					p_def = PTuple (Array.of_list pl);
-					p_pos = p;
-					p_type = t_dynamic;
-				}
+				mk_pat (PTuple (Array.of_list pl)) t_dynamic p
 			| None ->
 			| None ->
 				mk_any t p
 				mk_any t p
 			end
 			end
@@ -519,11 +509,7 @@ let to_pattern ctx e t =
 					with Invalid_argument _ ->
 					with Invalid_argument _ ->
 						error ("Invalid number of arguments: expected " ^ (string_of_int (List.length tl)) ^ ", found " ^ (string_of_int (List.length el))) p
 						error ("Invalid number of arguments: expected " ^ (string_of_int (List.length tl)) ^ ", found " ^ (string_of_int (List.length el))) p
 					in
 					in
-					{
-						p_def = PTuple (Array.of_list pl);
-						p_pos = p;
-						p_type = t_dynamic;
-					}
+					mk_pat (PTuple (Array.of_list pl)) t_dynamic p
 				| _ ->
 				| _ ->
 					error ((s_type t) ^ " should be Array") p
 					error ((s_type t) ^ " should be Array") p
 			end
 			end
@@ -535,12 +521,6 @@ let to_pattern ctx e t =
 			loop pctx (EBinop(OpOr,e1,(EBinop(OpOr,e2,e3),p2)),p) t
 			loop pctx (EBinop(OpOr,e1,(EBinop(OpOr,e2,e3),p2)),p) t
 		| EBinop(OpOr,e1,e2) ->
 		| EBinop(OpOr,e1,e2) ->
 			let old = pctx.pc_locals in
 			let old = pctx.pc_locals in
-			let rec dup t = match t with
-				| TMono r -> (match !r with
-					| None -> mk_mono()
-					| Some t -> Type.map dup t)
-				| _ -> Type.map dup t
-			in
 			let pat1 = loop pctx e1 t in
 			let pat1 = loop pctx e1 t in
 			begin match pat1.p_def with
 			begin match pat1.p_def with
 				| PAny | PVar _ ->
 				| PAny | PVar _ ->
@@ -579,9 +559,17 @@ let get_pattern_locals ctx e t =
 
 
 (* Match compilation *)
 (* Match compilation *)
 
 
+let expr_eq e1 e2 = e1 == e2 || match e1.eexpr,e2.eexpr with
+	| TConst ct1,TConst ct2 ->
+		ct1 = ct2
+	| TField(_,FStatic(c1,cf1)),TField(_,FStatic(c2,cf2)) ->
+		c1 == c2 && cf1.cf_name = cf2.cf_name
+	| _ ->
+		false
+
 let unify_con con1 con2 = match con1.c_def,con2.c_def with
 let unify_con con1 con2 = match con1.c_def,con2.c_def with
 	| CExpr e1, CExpr e2 ->
 	| CExpr e1, CExpr e2 ->
-		e1 == e2
+		expr_eq e1 e2
 	| CConst c1,CConst c2 ->
 	| CConst c1,CConst c2 ->
 		c1 = c2
 		c1 = c2
 	| CEnum(e1,ef1),CEnum(e2,ef2) ->
 	| CEnum(e1,ef1),CEnum(e2,ef2) ->
@@ -616,15 +604,12 @@ let spec mctx con pmat =
 			()
 			()
 		| PAny | PVar _->
 		| PAny | PVar _->
 			add (Array.append (Array.make a (mk_any (pv.(0).p_type) (pv.(0).p_pos))) (array_tl pv)) out
 			add (Array.append (Array.make a (mk_any (pv.(0).p_type) (pv.(0).p_pos))) (array_tl pv)) out
- 		| POr(pat1,pat2) ->
-			let tl = array_tl pv in
-			let out2 = clone_out mctx out [pat2] pat2.p_pos in
-			loop2 (Array.append [|pat1|] tl) out;
-			loop2 (Array.append [|pat2|] tl) out2;
 		| PBind(_,pat) ->
 		| PBind(_,pat) ->
 			loop2 (Array.append [|pat|] (array_tl pv)) out
 			loop2 (Array.append [|pat|] (array_tl pv)) out
 		| PTuple tl ->
 		| PTuple tl ->
 			loop2 tl out
 			loop2 tl out
+ 		| POr _ ->
+			assert false
 	in
 	in
 	let rec loop pmat = match pmat with
 	let rec loop pmat = match pmat with
 		| (pv,out) :: pl ->
 		| (pv,out) :: pl ->
@@ -646,15 +631,12 @@ let default mctx pmat =
 			()
 			()
 		| PAny | PVar _->
 		| PAny | PVar _->
 			add (array_tl pv) out
 			add (array_tl pv) out
- 		| POr(pat1,pat2) ->
-			let tl = array_tl pv in
-			let out2 = clone_out mctx out [pat2] pat2.p_pos in
-			loop2 (Array.append [|pat1|] tl) out;
-			loop2 (Array.append [|pat2|] tl) out2;
 		| PBind(_,pat) ->
 		| PBind(_,pat) ->
 			loop2 (Array.append [|pat|] (array_tl pv)) out
 			loop2 (Array.append [|pat|] (array_tl pv)) out
 		| PTuple tl ->
 		| PTuple tl ->
 			loop2 tl out
 			loop2 tl out
+ 		| POr _ ->
+			assert false
 	in
 	in
  	let rec loop pmat = match pmat with
  	let rec loop pmat = match pmat with
 		| (pv,out) :: pl ->
 		| (pv,out) :: pl ->
@@ -700,6 +682,48 @@ let swap_columns i (row : 'a list) : 'a list =
 	| _ ->
 	| _ ->
 		[]
 		[]
 
 
+let expand_or mctx pmat =
+	let rec loop pmat = match pmat with
+		| (pv,out) :: pmat ->
+			let acc = ref [] in
+			let rec loop2 pv out = match pv.(0) with
+				| {p_def = POr(pat1,pat2)} ->
+					out.o_pos <- pat1.p_pos;
+					let out2 = clone_out mctx out pat2.p_pos in
+					let tl = array_tl pv in
+					loop2 (Array.append [|pat2|] tl) out2;
+					loop2 (Array.append [|pat1|] tl) out;
+				| {p_def = PBind(v,{p_def = POr(pat1,pat2)})} as pat ->
+					out.o_pos <- pat1.p_pos;
+					let out2 = clone_out mctx out pat2.p_pos in
+					let tl = array_tl pv in
+					loop2 (Array.append [|{pat with p_def = PBind(v,pat2)}|] tl) out2;
+					loop2 (Array.append [|{pat with p_def = PBind(v,pat1)}|] tl) out;
+				| {p_def = PTuple tl} as pat ->
+					begin match tl.(0).p_def with
+					 	| POr(pat1,pat2) ->
+							let out2 = clone_out mctx out pat2.p_pos in
+							let a1 = Array.copy tl in
+							a1.(0) <- pat1;
+							let a2 = Array.copy tl in
+							a2.(0) <- pat2;
+							let tl = array_tl pv in
+							loop2 (Array.append [|{pat with p_def = PTuple a2}|] tl) out2;
+							loop2 (Array.append [|{pat with p_def = PTuple a1}|] tl) out;
+					 	| _ ->
+					 		acc := (pv,out) :: !acc
+					 end
+				| _ ->
+					acc := (pv,out) :: !acc
+			in
+			let r = loop pmat in
+			loop2 pv out;
+			!acc @ r
+		| [] ->
+			[]
+	in
+	loop pmat
+
 let column_sigma mctx st pmat =
 let column_sigma mctx st pmat =
 	let acc = ref [] in
 	let acc = ref [] in
 	let bindings = ref [] in
 	let bindings = ref [] in
@@ -716,10 +740,6 @@ let column_sigma mctx st pmat =
 			let rec loop2 out = function
 			let rec loop2 out = function
 				| PCon (c,_) ->
 				| PCon (c,_) ->
 					add c ((get_guard mctx out.o_id) <> None);
 					add c ((get_guard mctx out.o_id) <> None);
-				| POr(pat1,pat2) ->
-					let out2 = clone_out mctx out [pat2] pat2.p_pos in
-					loop2 out pat1.p_def;
-					loop2 out2 pat2.p_def;
 				| PVar v ->
 				| PVar v ->
 					bind_st out st v;
 					bind_st out st v;
 				| PBind(v,pat) ->
 				| PBind(v,pat) ->
@@ -729,6 +749,8 @@ let column_sigma mctx st pmat =
 					()
 					()
 				| PTuple tl ->
 				| PTuple tl ->
 					loop2 out tl.(0).p_def
 					loop2 out tl.(0).p_def
+				| POr _ ->
+					assert false
 			in
 			in
 			loop2 out pv.(0).p_def;
 			loop2 out pv.(0).p_def;
 			loop pr
 			loop pr
@@ -767,7 +789,7 @@ let rec all_ctors mctx t =
 				| _ -> ()
 				| _ -> ()
 		) c.cl_ordered_statics;
 		) c.cl_ordered_statics;
 		h,false
 		h,false
-	| TAbstract(a,pl) -> all_ctors mctx (Codegen.Abstract.get_underlying_type a pl)
+	| TAbstract(a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> all_ctors mctx (Codegen.Abstract.get_underlying_type a pl)
 	| TInst({cl_path=[],"String"},_)
 	| TInst({cl_path=[],"String"},_)
 	| TInst({cl_path=[],"Array"},_) ->
 	| TInst({cl_path=[],"Array"},_) ->
 		h,true
 		h,true
@@ -792,11 +814,7 @@ let rec collapse_pattern pl = match pl with
 		pat
 		pat
 	| pat :: pl ->
 	| pat :: pl ->
 		let pat2 = collapse_pattern pl in
 		let pat2 = collapse_pattern pl in
-		{
-			p_def = POr(pat,pat2);
-			p_pos = punion pat.p_pos pat2.p_pos;
-			p_type = pat.p_type
-		}
+		mk_pat (POr(pat,pat2)) pat.p_type (punion pat.p_pos pat2.p_pos)
 	| [] ->
 	| [] ->
 		assert false
 		assert false
 
 
@@ -854,7 +872,7 @@ let rec compile mctx stl pmat toplevel =
 	| (pv,out) :: pl ->
 	| (pv,out) :: pl ->
 		let i = pick_column pmat in
 		let i = pick_column pmat in
 		if i = -1 then begin
 		if i = -1 then begin
-			Hashtbl.replace mctx.used_paths out.o_id true;
+			out.o_num_paths <- out.o_num_paths + 1;
 			let bl = bind_remaining out pv stl in
 			let bl = bind_remaining out pv stl in
 			let dt = match (get_guard mctx out.o_id) with
 			let dt = match (get_guard mctx out.o_id) with
 				| None -> expr out.o_id
 				| None -> expr out.o_id
@@ -867,6 +885,7 @@ let rec compile mctx stl pmat toplevel =
 			compile mctx stls pmat toplevel
 			compile mctx stls pmat toplevel
 		end else begin
 		end else begin
 			let st_head,st_tail = match stl with st :: stl -> st,stl | _ -> assert false in
 			let st_head,st_tail = match stl with st :: stl -> st,stl | _ -> assert false in
+			let pmat = expand_or mctx pmat in
 			let sigma,bl = column_sigma mctx st_head pmat in
 			let sigma,bl = column_sigma mctx st_head pmat in
 			let all,inf = all_ctors mctx st_head.st_type in
 			let all,inf = all_ctors mctx st_head.st_type in
 			let cases = List.map (fun (c,g) ->
 			let cases = List.map (fun (c,g) ->
@@ -1095,9 +1114,8 @@ let match_expr ctx e cases def with_type p =
 	let mctx = {
 	let mctx = {
 		ctx = ctx;
 		ctx = ctx;
 		need_val = need_val;
 		need_val = need_val;
-		outcomes = PMap.empty;
+		outcomes = [];
 		toplevel_or = false;
 		toplevel_or = false;
-		used_paths = Hashtbl.create 0;
 		dt_lut = DynArray.create ();
 		dt_lut = DynArray.create ();
 		dt_cache = Hashtbl.create 0;
 		dt_cache = Hashtbl.create 0;
 		dt_count = 0;
 		dt_count = 0;
@@ -1152,6 +1170,10 @@ let match_expr ctx e cases def with_type p =
 			with Unrecognized_pattern (e,p) ->
 			with Unrecognized_pattern (e,p) ->
 				error "Case expression must be a constant value or a pattern, not an arbitrary expression" p
 				error "Case expression must be a constant value or a pattern, not an arbitrary expression" p
 		in
 		in
+		let is_catch_all = match pl with
+			| [{p_def = PAny | PVar _}] -> true
+			| _ -> false
+		in
 		(* type case body *)
 		(* type case body *)
 		let e = match e with
 		let e = match e with
 			| None -> mk (TBlock []) ctx.com.basic.tvoid (pos ep)
 			| None -> mk (TBlock []) ctx.com.basic.tvoid (pos ep)
@@ -1176,8 +1198,7 @@ let match_expr ctx e cases def with_type p =
 		in
 		in
 		List.iter (fun f -> f()) restore;
 		List.iter (fun f -> f()) restore;
 		save();
 		save();
-		let is_default = match fst ep with (EConst(Ident "_")) -> true | _ -> false in
-		let out = mk_out mctx i e eg pl is_default (pos ep) in
+		let out = mk_out mctx i e eg is_catch_all (pos ep) in
 		Array.of_list pl,out
 		Array.of_list pl,out
 	) cases in
 	) cases in
 	let check_unused () =
 	let check_unused () =
@@ -1204,8 +1225,11 @@ let match_expr ctx e cases def with_type p =
 			(match cases with (e,_,_) :: cl -> loop e cl | [] -> assert false);
 			(match cases with (e,_,_) :: cl -> loop e cl | [] -> assert false);
 			ctx.on_error <- old_error;
 			ctx.on_error <- old_error;
 		in
 		in
- 		PMap.iter (fun _ out ->
- 			if not (Hashtbl.mem mctx.used_paths out.o_id || out.o_default) then begin
+		let had_catch_all = ref false in
+ 		List.iter (fun out ->
+ 			if out.o_catch_all && not !had_catch_all then
+ 				had_catch_all := true
+ 			else if out.o_num_paths = 0 then begin
 				unused out.o_pos;
 				unused out.o_pos;
 				if mctx.toplevel_or then begin match evals with
 				if mctx.toplevel_or then begin match evals with
 					| [{etype = t}] when (match follow t with TAbstract({a_path=[],"Int"},[]) -> true | _ -> false) ->
 					| [{etype = t}] when (match follow t with TAbstract({a_path=[],"Int"},[]) -> true | _ -> false) ->
@@ -1213,7 +1237,7 @@ let match_expr ctx e cases def with_type p =
 					| _ -> ()
 					| _ -> ()
 				end;
 				end;
 			end
 			end
-		) mctx.outcomes;
+		) (List.rev mctx.outcomes);
 	in
 	in
 	let dt = try
 	let dt = try
 		(* compile decision tree *)
 		(* compile decision tree *)

+ 53 - 7
optimizer.ml

@@ -79,6 +79,45 @@ let api_inline ctx c field params p =
 			Some stringv
 			Some stringv
 		| _ ->
 		| _ ->
 			None)
 			None)
+	| ([],"Std"),"is",[o;t] | (["js"],"Boot"),"__instanceof",[o;t] when ctx.com.platform = Js ->
+		let mk_local ctx n t pos = mk (TLocal (try PMap.find n ctx.locals with _ -> add_local ctx n t)) t pos in
+
+		let tstring = ctx.com.basic.tstring in
+		let tbool = ctx.com.basic.tbool in
+		let tint = ctx.com.basic.tint in
+
+		let is_trivial e =
+			match e.eexpr with
+			| TConst _ | TLocal _ -> true
+			| _ -> false
+		in
+
+		let typeof t =
+			let tof = mk_local ctx "__typeof__" (tfun [o.etype] tstring) p in
+			let tof = mk (TCall (tof, [o])) tstring p in
+			mk (TBinop (Ast.OpEq, tof, (mk (TConst (TString t)) tstring p))) tbool p
+		in
+
+		(match t.eexpr with
+		(* generate simple typeof checks for basic types *)
+		| TTypeExpr (TClassDecl ({ cl_path = [],"String" })) -> Some (typeof "string")
+		| TTypeExpr (TAbstractDecl ({ a_path = [],"Bool" })) -> Some (typeof "boolean")
+		| TTypeExpr (TAbstractDecl ({ a_path = [],"Float" })) -> Some (typeof "number")
+		| TTypeExpr (TAbstractDecl ({ a_path = [],"Int" })) when is_trivial o ->
+			(* generate (o|0) === o check *)
+			let teq = mk_local ctx "__strict_eq__" (tfun [tint; tint] tbool) p in
+			let lhs = mk (TBinop (Ast.OpOr, o, mk (TConst (TInt Int32.zero)) tint p)) tint p in
+			Some (mk (TCall (teq, [lhs; o])) tbool p)
+		| TTypeExpr (TClassDecl ({ cl_path = [],"Array" })) ->
+			(* generate (o instanceof Array) && o.__enum__ == null check *)
+			let iof = mk_local ctx "__instanceof__" (tfun [o.etype;t.etype] tbool) p in
+			let iof = mk (TCall (iof, [o; t])) tbool p in
+			let enum = mk (TField (o, FDynamic "__enum__")) (mk_mono()) p in
+			let null = mk (TConst TNull) (mk_mono()) p in
+			let not_enum = mk (TBinop (Ast.OpEq, enum, null)) tbool p in
+			Some (mk (TBinop (Ast.OpBoolAnd, iof, not_enum)) tbool p)
+		| _ ->
+			None)
 	| ([],"Std"),"int",[{ eexpr = TConst (TFloat f) }] ->
 	| ([],"Std"),"int",[{ eexpr = TConst (TFloat f) }] ->
 		let f = float_of_string f in
 		let f = float_of_string f in
 		(match classify_float f with
 		(match classify_float f with
@@ -125,7 +164,7 @@ let inline_default_config cf t =
 	let tparams = fst tparams @ cf.cf_params in
 	let tparams = fst tparams @ cf.cf_params in
 	tparams <> [], apply_params tparams tmonos
 	tparams <> [], apply_params tparams tmonos
 
 
-let rec type_inline ctx cf f ethis params tret config p force =
+let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=false) force =
 	(* perform some specific optimization before we inline the call since it's not possible to detect at final optimization time *)
 	(* perform some specific optimization before we inline the call since it's not possible to detect at final optimization time *)
 	try
 	try
 		let cl = (match follow ethis.etype with
 		let cl = (match follow ethis.etype with
@@ -206,6 +245,7 @@ let rec type_inline ctx cf f ethis params tret config p force =
 		if has_side_effect e then l.i_force_temp <- true; (* force tmp var *)
 		if has_side_effect e then l.i_force_temp <- true; (* force tmp var *)
 		l, e
 		l, e
 	) (ethis :: loop params f.tf_args true) ((vthis,None) :: f.tf_args) in
 	) (ethis :: loop params f.tf_args true) ((vthis,None) :: f.tf_args) in
+	let inlined_vars = List.rev inlined_vars in
 	(*
 	(*
 		here, we try to eliminate final returns from the expression tree.
 		here, we try to eliminate final returns from the expression tree.
 		However, this is not entirely correct since we don't yet correctly propagate
 		However, this is not entirely correct since we don't yet correctly propagate
@@ -223,9 +263,10 @@ let rec type_inline ctx cf f ethis params tret config p force =
 	let cancel_inlining = ref false in
 	let cancel_inlining = ref false in
 	let has_return_value = ref false in
 	let has_return_value = ref false in
 	let ret_val = (match follow f.tf_type with TAbstract ({ a_path = ([],"Void") },[]) -> false | _ -> true) in
 	let ret_val = (match follow f.tf_type with TAbstract ({ a_path = ([],"Void") },[]) -> false | _ -> true) in
+	let map_pos = if self_calling_closure then (fun e -> e) else (fun e -> { e with epos = p }) in
 	let rec map term e =
 	let rec map term e =
 		let po = e.epos in
 		let po = e.epos in
-		let e = { e with epos = p } in
+		let e = map_pos e in
 		match e.eexpr with
 		match e.eexpr with
 		| TLocal v ->
 		| TLocal v ->
 			let l = read_local v in
 			let l = read_local v in
@@ -406,7 +447,7 @@ let rec type_inline ctx cf f ethis params tret config p force =
 
 
 		This could be fixed with better post process code cleanup (planed)
 		This could be fixed with better post process code cleanup (planed)
 	*)
 	*)
-	if !cancel_inlining then
+	if !cancel_inlining || (Common.platform ctx.com Js && not !force && (init <> None || !has_vars)) then
 		None
 		None
 	else
 	else
 		let wrap e =
 		let wrap e =
@@ -963,7 +1004,7 @@ let rec reduce_loop ctx e =
 		let cf = mk_field "" ef.etype e.epos in
 		let cf = mk_field "" ef.etype e.epos in
 		let ethis = mk (TConst TThis) t_dynamic e.epos in
 		let ethis = mk (TConst TThis) t_dynamic e.epos in
 		let rt = (match follow ef.etype with TFun (_,rt) -> rt | _ -> assert false) in
 		let rt = (match follow ef.etype with TFun (_,rt) -> rt | _ -> assert false) in
-		let inl = (try type_inline ctx cf func ethis el rt None e.epos false with Error (Custom _,_) -> None) in
+		let inl = (try type_inline ctx cf func ethis el rt None e.epos ~self_calling_closure:true false with Error (Custom _,_) -> None) in
 		(match inl with
 		(match inl with
 		| None -> reduce_expr ctx e
 		| None -> reduce_expr ctx e
 		| Some e -> reduce_loop ctx e)
 		| Some e -> reduce_loop ctx e)
@@ -1184,14 +1225,19 @@ let inline_constructors ctx e =
 				in
 				in
 				List.iter (fun (v,e) -> el_b := (mk (TVar(v,Some (subst e))) ctx.t.tvoid e.epos) :: !el_b) (List.rev vars);
 				List.iter (fun (v,e) -> el_b := (mk (TVar(v,Some (subst e))) ctx.t.tvoid e.epos) :: !el_b) (List.rev vars);
 				mk (TVar (v_first, Some (subst e_first))) ctx.t.tvoid e.epos
 				mk (TVar (v_first, Some (subst e_first))) ctx.t.tvoid e.epos
-			| TField ({ eexpr = TLocal v },FInstance (_,cf)) when v.v_id < 0 ->
+			| TField ({ eexpr = TLocal v },FInstance (c,cf)) when v.v_id < 0 ->
 				let (_, vars),el_init = PMap.find (-v.v_id) vfields in
 				let (_, vars),el_init = PMap.find (-v.v_id) vfields in
 				(try
 				(try
 					let v = PMap.find cf.cf_name vars in
 					let v = PMap.find cf.cf_name vars in
 					mk (TLocal v) v.v_type e.epos
 					mk (TLocal v) v.v_type e.epos
 				with Not_found ->
 				with Not_found ->
-					(* the variable was not set in the constructor, assume null *)
-					mk (TConst TNull) e.etype e.epos)
+					if (c.cl_path = ([],"Array") && cf.cf_name = "length") then begin
+						(* this can only occur for inlined array declarations, so we can use the statically known length here (issue #2568)*)
+						let l = PMap.fold (fun _ i -> i + 1) vars 0 in
+						mk (TConst (TInt (Int32.of_int l))) ctx.t.tint e.epos
+					end else
+						(* the variable was not set in the constructor, assume null *)
+						mk (TConst TNull) e.etype e.epos)
 			| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 ->
 			| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 ->
 				let (_, vars),_ = PMap.find (-v.v_id) vfields in
 				let (_, vars),_ = PMap.find (-v.v_id) vfields in
 				(try
 				(try

+ 24 - 11
parser.ml

@@ -62,6 +62,11 @@ let quote_ident s =
 	with Exit ->
 	with Exit ->
 		quoted_ident_prefix ^ s
 		quoted_ident_prefix ^ s
 
 
+let unquote_ident f =
+	let pf = quoted_ident_prefix in
+	let pflen = String.length pf in
+	if String.length f >= pflen && String.sub f 0 pflen = pf then String.sub f pflen (String.length f - pflen), false else f, true
+
 let cache = ref (DynArray.create())
 let cache = ref (DynArray.create())
 let last_doc = ref None
 let last_doc = ref None
 let use_doc = ref false
 let use_doc = ref false
@@ -215,12 +220,17 @@ let reify in_macro =
 		) in
 		) in
 		mk_enum "TypeParam" n [v] p
 		mk_enum "TypeParam" n [v] p
 	and to_tpath t p =
 	and to_tpath t p =
-		let fields = [
-			("pack", to_array to_string t.tpackage p);
-			("name", to_string t.tname p);
-			("params", to_array to_tparam t.tparams p);
-		] in
-		to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
+		let len = String.length t.tname in
+		if t.tpackage = [] && len > 1 && t.tname.[0] = '$' then
+			(EConst (Ident (String.sub t.tname 1 (len - 1))),p)
+		else begin
+			let fields = [
+				("pack", to_array to_string t.tpackage p);
+				("name", to_string t.tname p);
+				("params", to_array to_tparam t.tparams p);
+			] in
+			to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
+		end
 	and to_ctype t p =
 	and to_ctype t p =
 		let ct n vl = mk_enum "ComplexType" n vl p in
 		let ct n vl = mk_enum "ComplexType" n vl p in
 		match t with
 		match t with
@@ -530,7 +540,11 @@ let semicolon s =
 let rec	parse_file s =
 let rec	parse_file s =
 	last_doc := None;
 	last_doc := None;
 	match s with parser
 	match s with parser
-	| [< '(Kwd Package,_); p = parse_package; _ = semicolon; l = parse_type_decls p []; '(Eof,_) >] -> p , l
+	| [< '(Kwd Package,_); pack = parse_package; s >] ->
+		begin match s with parser
+		| [< '(Const(Ident _),p) when pack = [] >] -> error (Custom "Package name must start with a lowercase character") p
+		| [< _ = semicolon; l = parse_type_decls pack []; '(Eof,_) >] -> pack , l
+		end
 	| [< l = parse_type_decls [] []; '(Eof,_) >] -> [] , l
 	| [< l = parse_type_decls [] []; '(Eof,_) >] -> [] , l
 
 
 and parse_type_decls pack acc s =
 and parse_type_decls pack acc s =
@@ -704,6 +718,9 @@ and parse_class_field_resume tdecl s =
 		in
 		in
 		let rec loop k =
 		let rec loop k =
 			match List.rev_map fst (Stream.npeek k s) with
 			match List.rev_map fst (Stream.npeek k s) with
+			(* metadata *)
+			| Kwd _ :: At :: _ | Kwd _ :: DblDot :: At :: _ ->
+				loop (k + 1)
 			(* field declaration *)
 			(* field declaration *)
 			| Const _ :: Kwd Function :: _
 			| Const _ :: Kwd Function :: _
 			| Kwd New :: Kwd Function :: _ ->
 			| Kwd New :: Kwd Function :: _ ->
@@ -854,10 +871,6 @@ and parse_type_anonymous opt = parser
 	| [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s
 	| [< '(Question,_) when not opt; s >] -> parse_type_anonymous true s
 	| [< name, p1 = ident; '(DblDot,_); t = parse_complex_type; s >] ->
 	| [< name, p1 = ident; '(DblDot,_); t = parse_complex_type; s >] ->
 		let next p2 acc =
 		let next p2 acc =
-			let t = if not opt then t else (match t with
-				| CTPath { tpackage = []; tname = "Null" } -> t
-				| _ -> CTPath { tpackage = []; tname = "Null"; tsub = None; tparams = [TPType t] }
-			) in
 			{
 			{
 				cff_name = name;
 				cff_name = name;
 				cff_meta = if opt then [Meta.Optional,[],p1] else [];
 				cff_meta = if opt then [Meta.Optional,[],p1] else [];

+ 2 - 2
std/Lambda.hx

@@ -227,8 +227,8 @@ class Lambda {
 	/**
 	/**
 		Returns the first element of `it` for which `f` is true.
 		Returns the first element of `it` for which `f` is true.
 
 
-		This function returns true as soon as an element is found for which a
-		call to `f` returns true.
+		This function returns as soon as an element is found for which a call to
+		`f` returns true.
 
 
 		If no such element is found, the result is null.
 		If no such element is found, the result is null.
 
 

+ 2 - 2
std/Map.hx

@@ -41,7 +41,7 @@ import haxe.ds.EnumValueMap;
 	
 	
 	Map is an abstract type, it is not available at runtime.
 	Map is an abstract type, it is not available at runtime.
 **/
 **/
-@:multiType
+@:multiType(K)
 abstract Map<K,V>(IMap<K,V> ) {
 abstract Map<K,V>(IMap<K,V> ) {
 	
 	
 	/**
 	/**
@@ -79,7 +79,7 @@ abstract Map<K,V>(IMap<K,V> ) {
 		1. the map has no mapping for `key`
 		1. the map has no mapping for `key`
 		2. the map has a mapping with a value of `null`
 		2. the map has a mapping with a value of `null`
 		
 		
-		If it is important to distinguish these cases, `exists()` should be 
+		If it is important to distinguish these cases, `exists()` should be
 		used.
 		used.
 		
 		
 		If `key` is null, the result is unspecified.
 		If `key` is null, the result is unspecified.

+ 15 - 4
std/Std.hx

@@ -34,11 +34,22 @@ extern class Std {
 	public static function is( v : Dynamic, t : Dynamic ) : Bool;
 	public static function is( v : Dynamic, t : Dynamic ) : Bool;
 	
 	
 	/**
 	/**
-		Check if an object is an instance of the given class, then cast it.
-		Returns null if the object is not an instance of the class.
-		Is not guaranteed to work with interfaces or core types such as String, Array and Date.
+		Checks if object `value` is an instance of class `c`.
+		
+		Compiles only if the class specified by `c` can be assigned to the type
+		of `value`.
+		
+		This method checks if a downcast is possible. That is, if the runtime
+		type of `value` is assignable to the class specified by `c`, `value` is
+		returned. Otherwise null is returned.
+		
+		This method is not guaranteed to work with interfaces or core types such
+		as String, Array and Date.
+		
+		If `value` is null, the result is null. If `c` is null, the result is
+		unspecified.
 	**/
 	**/
-	public static function instance<T>( v : {}, c : Class<T> ) : T;
+	public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S;
 
 
 	/**
 	/**
 		Converts any value to a String.
 		Converts any value to a String.

+ 70 - 69
std/UInt.hx

@@ -20,7 +20,7 @@
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  */
  */
 
 
-#if (flash9 || flash9doc || cs)
+#if ((flash9 || flash9doc || cs) && !doc_gen)
 /**
 /**
 	The unsigned Int type is only defined for Flash9 and C#. It's currently
 	The unsigned Int type is only defined for Flash9 and C#. It's currently
 	handled the same as a normal Int.
 	handled the same as a normal Int.
@@ -33,73 +33,7 @@
 **/
 **/
 abstract UInt(Int) from Int {
 abstract UInt(Int) from Int {
 
 
-	@:commutative @:op(A + B) private static inline function addWithFloat(a:UInt, b:Float):Float {
-		return a.toFloat() + b;
-	}
-
-	@:commutative @:op(A * B) private static inline function mulWithFloat(a:UInt, b:Float):Float {
-		return a.toFloat() * b;
-	}
-
-	@:op(A / B) private static inline function divFloat(a:UInt, b:Float):Float {
-		return a.toFloat() / b;
-	}
-
-	@:op(A / B) private static inline function floatDiv(a:Float, b:UInt):Float {
-		return a / b.toFloat();
-	}
-
-	@:op(A - B) private static inline function subFloat(a:UInt, b:Float):Float {
-		return a.toFloat() - b;
-	}
-
-	@:op(A - B) private static inline function floatSub(a:Float, b:UInt):Float {
-		return a - b.toFloat();
-	}
-
-	@:op(A > B) private static inline function gtFloat(a:UInt, b:Float):Bool {
-		return a.toFloat() > b;
-	}
-
-	@:op(A >= B) private static inline function gteFloat(a:UInt, b:Float):Bool {
-		return a.toFloat() >= b;
-	}
-
-
-	@:op(A > B) private static inline function floatGt(a:Float, b:UInt):Bool {
-		return a > b.toFloat();
-	}
-
-	@:op(A >= B) private static inline function floatGte(a:Float, b:UInt):Bool {
-		return a >= b.toFloat();
-	}
-
-	@:op(A < B) private static inline function ltFloat(a:UInt, b:Float):Bool {
-		return a.toFloat() < b;
-	}
-
-	@:op(A <= B) private static inline function lteFloat(a:UInt, b:Float):Bool {
-		return a.toFloat() <= b;
-	}
-
-
-	@:op(A < B) private static inline function floatLt(a:Float, b:UInt):Bool {
-		return a < b.toFloat();
-	}
-
-	@:op(A <= B) private static inline function floatLte(a:Float, b:UInt):Bool {
-		return a <= b.toFloat();
-	}
-
-	@:op(A % B) private static inline function modFloat(a:UInt, b:Float):Float {
-		return a.toFloat() % b;
-	}
-
-	@:op(A % B) private static inline function floatMod(a:Float, b:UInt):Float {
-		return a % b.toFloat();
-	}
-
-	@:op(A + B) private static inline function add(a:UInt, b:UInt):UInt {
+		@:op(A + B) private static inline function add(a:UInt, b:UInt):UInt {
 		return a.toInt() + b.toInt();
 		return a.toInt() + b.toInt();
 	}
 	}
 
 
@@ -188,6 +122,72 @@ abstract UInt(Int) from Int {
 	@:op(A % B) private static inline function mod(a:UInt, b:UInt):UInt {
 	@:op(A % B) private static inline function mod(a:UInt, b:UInt):UInt {
 		return a.toInt() % b.toInt();
 		return a.toInt() % b.toInt();
 	}
 	}
+	
+	@:commutative @:op(A + B) private static inline function addWithFloat(a:UInt, b:Float):Float {
+		return a.toFloat() + b;
+	}
+
+	@:commutative @:op(A * B) private static inline function mulWithFloat(a:UInt, b:Float):Float {
+		return a.toFloat() * b;
+	}
+
+	@:op(A / B) private static inline function divFloat(a:UInt, b:Float):Float {
+		return a.toFloat() / b;
+	}
+
+	@:op(A / B) private static inline function floatDiv(a:Float, b:UInt):Float {
+		return a / b.toFloat();
+	}
+
+	@:op(A - B) private static inline function subFloat(a:UInt, b:Float):Float {
+		return a.toFloat() - b;
+	}
+
+	@:op(A - B) private static inline function floatSub(a:Float, b:UInt):Float {
+		return a - b.toFloat();
+	}
+
+	@:op(A > B) private static inline function gtFloat(a:UInt, b:Float):Bool {
+		return a.toFloat() > b;
+	}
+
+	@:op(A >= B) private static inline function gteFloat(a:UInt, b:Float):Bool {
+		return a.toFloat() >= b;
+	}
+
+
+	@:op(A > B) private static inline function floatGt(a:Float, b:UInt):Bool {
+		return a > b.toFloat();
+	}
+
+	@:op(A >= B) private static inline function floatGte(a:Float, b:UInt):Bool {
+		return a >= b.toFloat();
+	}
+
+	@:op(A < B) private static inline function ltFloat(a:UInt, b:Float):Bool {
+		return a.toFloat() < b;
+	}
+
+	@:op(A <= B) private static inline function lteFloat(a:UInt, b:Float):Bool {
+		return a.toFloat() <= b;
+	}
+
+
+	@:op(A < B) private static inline function floatLt(a:Float, b:UInt):Bool {
+		return a < b.toFloat();
+	}
+
+	@:op(A <= B) private static inline function floatLte(a:Float, b:UInt):Bool {
+		return a <= b.toFloat();
+	}
+
+	@:op(A % B) private static inline function modFloat(a:UInt, b:Float):Float {
+		return a.toFloat() % b;
+	}
+
+	@:op(A % B) private static inline function floatMod(a:Float, b:UInt):Float {
+		return a % b.toFloat();
+	}
 
 
 	@:op(~A) private inline function negBits():UInt {
 	@:op(~A) private inline function negBits():UInt {
 		return ~this;
 		return ~this;
@@ -209,7 +209,8 @@ abstract UInt(Int) from Int {
 		return this--;
 		return this--;
 	}
 	}
 
 
-	private inline function toString():String {
+	// TODO: radix is just defined to deal with doc_gen issues
+	private inline function toString(?radix:Int):String {
 		return Std.string(toFloat());
 		return Std.string(toFloat());
 	}
 	}
 
 

+ 3 - 0
std/cpp/_std/Date.hx

@@ -50,6 +50,9 @@
 	public static function now() : Date {
 	public static function now() : Date {
 		return fromTime( untyped __global__.__hxcpp_date_now()*1000.0);
 		return fromTime( untyped __global__.__hxcpp_date_now()*1000.0);
 	}
 	}
+  	private static function new1(t : Dynamic) : Date {
+		return  new Date(2005,1,1,0,0,0);
+	}
 
 
 	public static function fromTime( t : Float ) : Date {
 	public static function fromTime( t : Float ) : Date {
 		var result = new Date(0,0,0,0,0,0);
 		var result = new Date(0,0,0,0,0,0);

+ 2 - 2
std/cpp/_std/Std.hx

@@ -24,8 +24,8 @@
 		return untyped __global__.__instanceof(v,t);
 		return untyped __global__.__instanceof(v,t);
 	}
 	}
 
 
-	@:keep public static function instance<T>( v : { }, c : Class<T> ) : T {
-		return Std.is(v, c) ? cast v : null;
+	@:keep public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return Std.is(value, c) ? cast value : null;
 	}
 	}
 
 
 	@:keep public static function string( s : Dynamic ) : String {
 	@:keep public static function string( s : Dynamic ) : String {

+ 3 - 1
std/cpp/_std/haxe/Utf8.hx

@@ -90,7 +90,9 @@ class Utf8
 
 
 	public static function sub( s : String, pos : Int, len : Int ) : String {
 	public static function sub( s : String, pos : Int, len : Int ) : String {
       var array:Array<Int> = untyped __global__.__hxcpp_utf8_string_to_char_array(s);
       var array:Array<Int> = untyped __global__.__hxcpp_utf8_string_to_char_array(s);
-      var sub = array.slice(pos,len);
+      var last = len < 0 ? array.length : pos+len;
+      if (last>array.length) last = array.length;
+      var sub = array.slice(pos,last);
 		return untyped __global__.__hxcpp_char_array_to_utf8_string(sub);
 		return untyped __global__.__hxcpp_char_array_to_utf8_string(sub);
 	}
 	}
 
 

+ 2 - 2
std/cpp/_std/sys/FileSystem.hx

@@ -31,7 +31,7 @@ private enum FileKind {
 class FileSystem {
 class FileSystem {
 
 
 	public static inline function exists( path : String ) : Bool {
 	public static inline function exists( path : String ) : Bool {
-		return sys_exists(path);
+		return sys_exists(haxe.io.Path.removeTrailingSlashes(path));
 	}
 	}
 
 
 	public static function rename( path : String, newPath : String ) : Void {
 	public static function rename( path : String, newPath : String ) : Void {
@@ -54,7 +54,7 @@ class FileSystem {
 	}
 	}
 
 
 	static function kind( path : String ) : FileKind {
 	static function kind( path : String ) : FileKind {
-		var k:String = sys_file_type(path);
+		var k:String = sys_file_type(haxe.io.Path.removeTrailingSlashes(path));
 		return switch(k) {
 		return switch(k) {
 		case "file": kfile;
 		case "file": kfile;
 		case "dir": kdir;
 		case "dir": kdir;

+ 202 - 0
std/cpp/_std/sys/db/Mysql.hx

@@ -0,0 +1,202 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.db;
+
+private class D {
+
+	static function load(fun,args) : Dynamic {
+		return cpp.Lib.load(lib,fun,args);
+	}
+
+	static var lib = "mysql5";
+	public static var connect = load("mysql_connect",1);
+	public static var select_db = load("select_db",2);
+	public static var request = load("request",2);
+	public static var close = load("close",1);
+	public static var escape = load("escape", 2);
+	public static var set_conv_funs = load("set_conv_funs", 4);
+	public static var result_get_length = load("result_get_length",1);
+	public static var result_get_nfields = load("result_get_nfields",1);
+	public static var result_next = load("result_next",1);
+	public static var result_get = load("result_get",2);
+	public static var result_get_int = load("result_get_int",2);
+	public static var result_get_float = load("result_get_float",2);
+	public static var result_fields_names = cpp.Lib.loadLazy(lib,"result_get_fields_names",1);
+
+}
+
+private class MysqlResultSet implements sys.db.ResultSet {
+
+	public var length(get,null) : Int;
+	public var nfields(get,null) : Int;
+	private var __r : Dynamic;
+	private var cache : Dynamic;
+
+	public function new(r) {
+		__r = r;
+	}
+
+	private function get_length() {
+		return D.result_get_length(__r);
+	}
+
+	private function get_nfields() {
+		return D.result_get_nfields(__r);
+	}
+
+	public function hasNext() {
+		if( cache == null )
+			cache = next();
+		return (cache != null);
+	}
+
+	public function next() : Dynamic {
+		var c = cache;
+		if( c != null ) {
+			cache = null;
+			return c;
+		}
+		c = D.result_next(__r);
+		return c;
+	}
+
+	public function results() : List<Dynamic> {
+		var l = new List();
+		while( hasNext() )
+			l.add(next());
+		return l;
+	}
+
+	public function getResult( n : Int ) {
+		return new String(D.result_get(__r,n));
+	}
+
+	public function getIntResult( n : Int ) : Int {
+		return D.result_get_int(__r,n);
+	}
+
+	public function getFloatResult( n : Int ) : Float {
+		return D.result_get_float(__r,n);
+	}
+
+	public function getFieldsNames() : Array<String> {
+		var a = D.result_fields_names(__r);
+		return a;
+	}
+
+}
+
+private class MysqlConnection implements sys.db.Connection {
+
+	private var __c : Dynamic;
+
+	public function new(c) {
+		__c = c;
+		D.set_conv_funs(c, function(s) return new String(s), function(d) return untyped Date.new1(d), function(b) return haxe.io.Bytes.ofData(b));
+	}
+
+	public function request( s : String ) : sys.db.ResultSet {
+			var r = D.request(this.__c, s);
+			return new MysqlResultSet(r);
+	}
+
+	public function close() {
+		D.close(__c);
+	}
+
+	public function escape( s : String ) {
+		return new String(D.escape(__c,s));
+	}
+
+	public function quote( s : String ) {
+		return "'"+escape(s)+"'";
+	}
+
+	public function addValue( s : StringBuf, v : Dynamic ) {
+		if (v == null) {
+			s.add(v);
+      }
+      else {
+			var t:Int = untyped v.__GetType();
+			if( t == 0xff )
+				s.add(v);
+			else if( t == 2 )
+				s.add( untyped v.__GetInt() ? "1".code : "0".code );
+			else {
+				s.addChar("'".code);
+				s.add(escape(Std.string(v)));
+				s.addChar("'".code);
+			}
+		}
+	}
+
+	public function lastInsertId() {
+		return request("SELECT LAST_INSERT_ID()").getIntResult(0);
+	}
+
+	public function dbName() {
+		return "MySQL";
+	}
+
+	public function startTransaction() {
+		request("START TRANSACTION");
+	}
+
+	public function commit() {
+		request("COMMIT");
+	}
+
+	public function rollback() {
+		request("ROLLBACK");
+	}
+
+	private static var __use_date = Date;
+}
+
+@:coreApi class Mysql {
+
+	public static function connect( params : {
+		host : String,
+		?port : Int,
+		user : String,
+		pass : String,
+		?socket : String,
+		database : String
+	} ) : sys.db.Connection {
+		var o = {
+			host : params.host,
+			port : if( params.port == null ) 3306 else params.port,
+			user : params.user,
+			pass : params.pass,
+			socket : if( params.socket == null ) null else params.socket
+		};
+		var c = D.connect(o);
+		try {
+			D.select_db(c,params.database);
+		} catch( e : Dynamic ) {
+			D.close(c);
+			cpp.Lib.rethrow(e);
+		}
+		return new MysqlConnection(c);
+	}
+
+}

+ 186 - 0
std/cpp/_std/sys/db/Sqlite.hx

@@ -0,0 +1,186 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.db;
+
+private class SqliteConnection implements Connection {
+
+	var c : Dynamic;
+
+	public function new( file : String ) {
+		c = _connect(file);
+	}
+
+	public function close() {
+		_close(c);
+	}
+
+	public function request( s : String ) : ResultSet {
+		try {
+			return new SqliteResultSet(_request(c,s));
+		} catch( e : String ) {
+			throw "Error while executing "+s+" ("+e+")";
+		}
+	}
+
+	public function escape( s : String ) {
+		return s.split("'").join("''");
+	}
+
+	public function quote( s : String ) {
+		if( s.indexOf("\000") >= 0 )
+			return "x'"+new String(_encode(s,"0123456789ABCDEF"))+"'";
+		return "'"+s.split("'").join("''")+"'";
+	}
+
+	public function addValue( s : StringBuf, v : Dynamic ) {
+		if (v == null) {
+			s.add(v);
+      }
+      else {
+			var t:Int = untyped v.__GetType();
+			if( t == 0xff )
+				s.add(v);
+			else if( t == 2 )
+				s.add( untyped v.__GetInt() );
+			else
+				s.add(quote(Std.string(v)));
+		}
+	}
+
+	public function lastInsertId() {
+		return _last_id(c);
+	}
+
+	public function dbName() {
+		return "SQLite";
+	}
+
+	public function startTransaction() {
+		request("BEGIN TRANSACTION");
+	}
+
+	public function commit() {
+		request("COMMIT");
+		startTransaction(); // match mysql usage
+	}
+
+	public function rollback() {
+		request("ROLLBACK");
+		startTransaction(); // match mysql usage
+	}
+
+	static var _encode = cpp.Lib.load("std","base_encode",2);
+	static var _connect = cpp.Lib.load("sqlite","sqlite_connect",1);
+	static var _close = cpp.Lib.load("sqlite","close",1);
+	static var _request = cpp.Lib.load("sqlite","request",2);
+	static var _last_id = cpp.Lib.load("sqlite","last_insert_id",1);
+}
+
+
+private class SqliteResultSet implements ResultSet {
+
+	public var length(get,null) : Int;
+	public var nfields(get,null) : Int;
+	var r : Dynamic;
+	var cache : List<Dynamic>;
+
+	public function new( r ) {
+		cache = new List();
+		this.r = r;
+		hasNext(); // execute the request
+	}
+
+	function get_length() {
+		if( nfields != 0 ) {
+			while( true ) {
+				var c = result_next(r);
+				if( c == null )
+					break;
+				cache.add(c);
+			}
+			return cache.length;
+		}
+		return result_get_length(r);
+	}
+
+	function get_nfields() {
+		return result_get_nfields(r);
+	}
+
+	public function hasNext() {
+		var c = next();
+		if( c == null )
+			return false;
+		cache.push(c);
+		return true;
+	}
+
+	public function next() : Dynamic {
+		var c = cache.pop();
+		if( c != null )
+			return c;
+		return result_next(r);
+	}
+
+	public function results() : List<Dynamic> {
+		var l = new List();
+		while( true ) {
+			var c = next();
+			if( c == null )
+				break;
+			l.add(c);
+		}
+		return l;
+	}
+
+	public function getResult( n : Int ) {
+		return new String(result_get(r,n));
+	}
+
+	public function getIntResult( n : Int ) : Int {
+		return result_get_int(r,n);
+	}
+
+	public function getFloatResult( n : Int ) : Float {
+		return result_get_float(r,n);
+	}
+
+	public function getFieldsNames() : Array<String> {
+		return null;
+	}
+
+	static var result_next = cpp.Lib.load("sqlite","result_next",1);
+	static var result_get_length = cpp.Lib.load("sqlite","result_get_length",1);
+	static var result_get_nfields = cpp.Lib.load("sqlite","result_get_nfields",1);
+	static var result_get = cpp.Lib.load("sqlite","result_get",2);
+	static var result_get_int = cpp.Lib.load("sqlite","result_get_int",2);
+	static var result_get_float = cpp.Lib.load("sqlite","result_get_float",2);
+
+}
+
+@:coreApi class Sqlite {
+
+	public static function open( file : String ) : Connection {
+		return new SqliteConnection(file);
+	}
+
+}

+ 15 - 0
std/cpp/vm/Debugger.hx

@@ -188,6 +188,21 @@ class Debugger
         return untyped __global__.__hxcpp_dbg_getFiles();
         return untyped __global__.__hxcpp_dbg_getFiles();
    }
    }
 
 
+
+    /**
+     * Returns the full paths of the set of source files known to the debugger.
+     * This is a copy of the original array and could be quite large.
+     * It is possible that this set will be empty, in which case the full paths are not known.
+     * The index of these files matches the index from "getFiles", so the full path for
+     * a given short path can be calculated.
+     *
+     * @return the known full paths of the set of source files
+     **/
+   public static function getFilesFullPath() : Array<String>
+   {
+        return untyped __global__.__hxcpp_dbg_getFilesFullPath();
+   }
+
     /**
     /**
      * Returns the set of class names of all classes known to the debugger.
      * Returns the set of class names of all classes known to the debugger.
      * This is a copy of the original array and could be quite large.  The
      * This is a copy of the original array and could be quite large.  The

+ 20 - 8
std/cs/_std/Array.hx

@@ -408,15 +408,9 @@ import cs.NativeArray;
 		return ofNative(newarr);
 		return ofNative(newarr);
 	}
 	}
 
 
-	public function iterator() : Iterator<T>
+	public inline function iterator() : Iterator<T>
 	{
 	{
-		var i = 0;
-		var len = length;
-		return
-		{
-			hasNext:function() return i < len,
-			next:function() return __a[i++]
-		};
+		return new ArrayIterator<T>(this);
 	}
 	}
 
 
 	private function __get(idx:Int):T
 	private function __get(idx:Int):T
@@ -459,3 +453,21 @@ import cs.NativeArray;
 		return __a[idx] = val;
 		return __a[idx] = val;
 	}
 	}
 }
 }
+
+@:final
+private class ArrayIterator<T>
+{
+	var arr:Array<T>;
+	var len:Int;
+	var i:Int;
+
+	public inline function new(a:Array<T>)
+	{
+		arr = a;
+		len = a.length;
+		i = 0;
+	}
+
+	public inline function hasNext():Bool return i < len;
+	public inline function next():T return arr[i++];
+}

+ 2 - 2
std/cs/_std/Std.hx

@@ -234,8 +234,8 @@ import cs.internal.Exceptions;
 		}
 		}
 	}
 	}
 
 
-	public static function instance<T>( v : { }, c : Class<T> ) : T {
-		return Std.is(v, c) ? cast v : null;
+	public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return Std.is(value, c) ? cast value : null;
 	}
 	}
 
 
 	public static function random( x : Int ) : Int {
 	public static function random( x : Int ) : Int {

+ 5 - 0
std/cs/internal/StringExt.hx

@@ -176,6 +176,11 @@ private typedef NativeString = String;
 		return null;
 		return null;
 	}
 	}
 
 
+	public static function toString(me:NativeString):NativeString
+	{
+		return me;
+	}
+
 	@:functionCode('
 	@:functionCode('
 			return me.ToLower();
 			return me.ToLower();
 	')
 	')

+ 2 - 2
std/flash/_std/Std.hx

@@ -27,8 +27,8 @@ import flash.Boot;
 		return untyped flash.Boot.__instanceof(v,t);
 		return untyped flash.Boot.__instanceof(v,t);
 	}
 	}
 
 
-	public inline static function instance<T>( v : { }, c : Class<T> ) : T {
-		return flash.Lib.as(v, c);
+	public static inline function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return flash.Lib.as(value, c);
 	}
 	}
 
 
 	public static function string( s : Dynamic ) : String {
 	public static function string( s : Dynamic ) : String {

+ 16 - 6
std/js/html/DOMStringMap.hx → std/flash/_std/haxe/Json.hx

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C)2005-2013 Haxe Foundation
+ * Copyright (C)2005-2012 Haxe Foundation
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,21 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  */
  */
+package haxe;
 
 
-// This file is generated, do not edit!
-package js.html;
+@:coreApi
+#if (!haxeJSON && flash11)
+@:native("JSON") extern
+#end
+class Json {
 
 
-@:native("DOMStringMap")
-extern class DOMStringMap
-{
+	#if (haxeJSON || !flash11) inline #end
+	public static function parse( text : String ) : Dynamic {
+		return haxe.format.JsonParser.parse(text);
+	}
+
+	#if (haxeJSON || !flash11) inline #end
+	public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic ) : String {
+		return haxe.format.JsonPrinter.print(value, replacer);
+	}
 }
 }

+ 1 - 0
std/flash/display/DisplayObjectContainer.hx

@@ -18,6 +18,7 @@ extern class DisplayObjectContainer extends InteractiveObject {
 	function removeChildAt(index : Int) : DisplayObject;
 	function removeChildAt(index : Int) : DisplayObject;
 	@:require(flash11) function removeChildren(beginIndex : Int = 0, endIndex : Int = 2147483647) : Void;
 	@:require(flash11) function removeChildren(beginIndex : Int = 0, endIndex : Int = 2147483647) : Void;
 	function setChildIndex(child : DisplayObject, index : Int) : Void;
 	function setChildIndex(child : DisplayObject, index : Int) : Void;
+	@:require(flash11_8) function stopAllMovieClips() : Void;
 	function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : Void;
 	function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : Void;
 	function swapChildrenAt(index1 : Int, index2 : Int) : Void;
 	function swapChildrenAt(index1 : Int, index2 : Int) : Void;
 }
 }

+ 1 - 0
std/flash/display/Stage3D.hx

@@ -6,4 +6,5 @@ package flash.display;
 	var x : Float;
 	var x : Float;
 	var y : Float;
 	var y : Float;
 	function requestContext3D(?context3DRenderMode : String, ?profile : flash.display3D.Context3DProfile) : Void;
 	function requestContext3D(?context3DRenderMode : String, ?profile : flash.display3D.Context3DProfile) : Void;
+	@:require(flash12) function requestContext3DMatchingProfiles(profiles:Vector<String>) : Void;
 }
 }

+ 2 - 0
std/flash/display3D/Context3D.hx

@@ -3,11 +3,13 @@ package flash.display3D;
 @:final extern class Context3D extends flash.events.EventDispatcher {
 @:final extern class Context3D extends flash.events.EventDispatcher {
 	var driverInfo(default,null) : String;
 	var driverInfo(default,null) : String;
 	var enableErrorChecking : Bool;
 	var enableErrorChecking : Bool;
+	@:require(flash12) var profile : String;
 	function clear(red : Float = 0, green : Float = 0, blue : Float = 0, alpha : Float = 1, depth : Float = 1, stencil : UInt = 0, mask : UInt = 0xFFFFFFFF) : Void;
 	function clear(red : Float = 0, green : Float = 0, blue : Float = 0, alpha : Float = 1, depth : Float = 1, stencil : UInt = 0, mask : UInt = 0xFFFFFFFF) : Void;
 	function configureBackBuffer(width : Int, height : Int, antiAlias : Int, enableDepthAndStencil : Bool = true, wantsBestResolution : Bool = false) : Void;
 	function configureBackBuffer(width : Int, height : Int, antiAlias : Int, enableDepthAndStencil : Bool = true, wantsBestResolution : Bool = false) : Void;
 	function createCubeTexture(size : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.CubeTexture;
 	function createCubeTexture(size : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.CubeTexture;
 	function createIndexBuffer(numIndices : Int) : IndexBuffer3D;
 	function createIndexBuffer(numIndices : Int) : IndexBuffer3D;
 	function createProgram() : Program3D;
 	function createProgram() : Program3D;
+	@:require(flash11_8) function createRectangleTexture(width : Int, height : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool) : flash.display3D.textures.RectangleTexture;
 	function createTexture(width : Int, height : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.Texture;
 	function createTexture(width : Int, height : Int, format : Context3DTextureFormat, optimizeForRenderToTexture : Bool, streamingLevels : Int = 0) : flash.display3D.textures.Texture;
 	function createVertexBuffer(numVertices : Int, data32PerVertex : Int) : VertexBuffer3D;
 	function createVertexBuffer(numVertices : Int, data32PerVertex : Int) : VertexBuffer3D;
 	function dispose(recreate : Bool = true) : Void;
 	function dispose(recreate : Bool = true) : Void;

+ 1 - 0
std/flash/display3D/Context3DProfile.hx

@@ -3,4 +3,5 @@ package flash.display3D;
 @:fakeEnum(String) extern enum Context3DProfile {
 @:fakeEnum(String) extern enum Context3DProfile {
 	BASELINE;
 	BASELINE;
 	BASELINE_CONSTRAINED;
 	BASELINE_CONSTRAINED;
+	BASELINE_EXTENDED;
 }
 }

+ 1 - 0
std/flash/events/AVStatusEvent.hx

@@ -18,5 +18,6 @@ extern class AVStatusEvent extends Event {
 	static var SEEK_COMPLETE : String;
 	static var SEEK_COMPLETE : String;
 	static var STEP_COMPLETE : String;
 	static var STEP_COMPLETE : String;
 	static var STREAM_SWITCH : String;
 	static var STREAM_SWITCH : String;
+	static var TRICKPLAY_ENDED : String;
 	static var WARNING : String;
 	static var WARNING : String;
 }
 }

+ 10 - 0
std/flash/events/DRMReturnVoucherCompleteEvent.hx

@@ -0,0 +1,10 @@
+package flash.events;
+
+extern class DRMReturnVoucherCompleteEvent extends Event {
+	var licenseID : String;
+	var numberOfVouchersReturned : Int;
+	var policyID : String;
+	var serverURL : String;
+	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inServerURL : String, ?inLicenseID : String, ?inPolicyID : String, inNumberOfVouchersReturned : Int = 0) : Void;
+	static var RETURN_VOUCHER_COMPLETE : String;
+}

+ 10 - 0
std/flash/events/DRMReturnVoucherErrorEvent.hx

@@ -0,0 +1,10 @@
+package flash.events;
+
+extern class DRMReturnVoucherErrorEvent extends ErrorEvent {
+	var licenseID : String;
+	var policyID : String;
+	var serverURL : String;
+	var subErrorID : Int;
+	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?inDetail : String, inErrorID : Int = 0, inSubErrorID : Int = 0, ?inServerURL : String, ?inLicenseID : String, ?inPolicyID : String) : Void;
+	static var RETURN_VOUCHER_ERROR : String;
+}

+ 1 - 0
std/flash/events/GameInputEvent.hx

@@ -5,4 +5,5 @@ package flash.events;
 	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?device : flash.ui.GameInputDevice) : Void;
 	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?device : flash.ui.GameInputDevice) : Void;
 	static var DEVICE_ADDED : String;
 	static var DEVICE_ADDED : String;
 	static var DEVICE_REMOVED : String;
 	static var DEVICE_REMOVED : String;
+	static var DEVICE_UNUSABLE : String;
 }
 }

+ 2 - 1
std/flash/events/HTTPStatusEvent.hx

@@ -1,10 +1,11 @@
 package flash.events;
 package flash.events;
 
 
 extern class HTTPStatusEvent extends Event {
 extern class HTTPStatusEvent extends Event {
+	var redirected : Bool;
 	@:require(flash10_1) var responseHeaders : Array<Dynamic>;
 	@:require(flash10_1) var responseHeaders : Array<Dynamic>;
 	@:require(flash10_1) var responseURL : String;
 	@:require(flash10_1) var responseURL : String;
 	var status(default,null) : Int;
 	var status(default,null) : Int;
-	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, status : Int = 0) : Void;
+	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, status : Int = 0, redirected : Bool = false) : Void;
 	@:require(flash10_1) static var HTTP_RESPONSE_STATUS : String;
 	@:require(flash10_1) static var HTTP_RESPONSE_STATUS : String;
 	static var HTTP_STATUS : String;
 	static var HTTP_STATUS : String;
 }
 }

+ 1 - 0
std/flash/events/StageVideoAvailabilityEvent.hx

@@ -2,6 +2,7 @@ package flash.events;
 
 
 extern class StageVideoAvailabilityEvent extends Event {
 extern class StageVideoAvailabilityEvent extends Event {
 	var availability(default,null) : String;
 	var availability(default,null) : String;
+	var reason : String;
 	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?availability : String) : Void;
 	function new(type : String, bubbles : Bool = false, cancelable : Bool = false, ?availability : String) : Void;
 	static var STAGE_VIDEO_AVAILABILITY : String;
 	static var STAGE_VIDEO_AVAILABILITY : String;
 }
 }

+ 2 - 1
std/flash/media/AVPeriodInfo.hx

@@ -5,7 +5,8 @@ extern class AVPeriodInfo {
 	var firstCuePointIndex(default,null) : Int;
 	var firstCuePointIndex(default,null) : Int;
 	var lastCuePointIndex(default,null) : Int;
 	var lastCuePointIndex(default,null) : Int;
 	var localStartTime(default,null) : Float;
 	var localStartTime(default,null) : Float;
+	var supportsTrickPlay(default,null) : Bool;
 	var userData(default,null) : Int;
 	var userData(default,null) : Int;
 	var virtualStartTime(default,null) : Float;
 	var virtualStartTime(default,null) : Float;
-	function new(init_localStartTime : Float, init_virtualStartTime : Float, init_duration : Float, init_firstCuePointIndex : Int, init_lastCuePointIndex : Int, init_userData : Int) : Void;
+	function new(init_localStartTime : Float, init_virtualStartTime : Float, init_duration : Float, init_firstCuePointIndex : Int, init_lastCuePointIndex : Int, init_userData : Int, init_supportsTrickPlay : Bool) : Void;
 }
 }

+ 1 - 0
std/flash/media/AVPlayState.hx

@@ -9,6 +9,7 @@ extern class AVPlayState {
 	static var PLAYING : Int;
 	static var PLAYING : Int;
 	static var READY : Int;
 	static var READY : Int;
 	static var SUSPENDED : Int;
 	static var SUSPENDED : Int;
+	static var TRICK_PLAY : Int;
 	static var UNINITIALIZED : Int;
 	static var UNINITIALIZED : Int;
 	static var UNRECOVERABLE_ERROR : Int;
 	static var UNRECOVERABLE_ERROR : Int;
 }
 }

+ 24 - 0
std/flash/media/AVResult.hx

@@ -4,11 +4,15 @@ extern class AVResult {
 	var result(default,null) : Int;
 	var result(default,null) : Int;
 	function new(inResult : Int) : Void;
 	function new(inResult : Int) : Void;
 	static var ASYNC_OPERATION_IN_PROGRESS : Int;
 	static var ASYNC_OPERATION_IN_PROGRESS : Int;
+	static var AUDIO_START_ERROR : Int;
 	static var BAD_MANIFEST_SIGNATURE : Int;
 	static var BAD_MANIFEST_SIGNATURE : Int;
+	static var BAD_MEDIASAMPLE_FOUND : Int;
 	static var BAD_MEDIA_INTERLEAVING : Int;
 	static var BAD_MEDIA_INTERLEAVING : Int;
 	static var CALLED_FROM_WRONG_THREAD : Int;
 	static var CALLED_FROM_WRONG_THREAD : Int;
+	static var CANNOT_ERASE_TIMELINE : Int;
 	static var CANNOT_FAIL_OVER : Int;
 	static var CANNOT_FAIL_OVER : Int;
 	static var CANNOT_LOAD_PLAY_LIST : Int;
 	static var CANNOT_LOAD_PLAY_LIST : Int;
+	static var CANNOT_SPLIT_TIMELINE : Int;
 	static var CODEC_NOT_SUPPORTED : Int;
 	static var CODEC_NOT_SUPPORTED : Int;
 	static var COMPONENT_CREATION_FAILURE : Int;
 	static var COMPONENT_CREATION_FAILURE : Int;
 	static var CONTAINER_NOT_SUPPORTED : Int;
 	static var CONTAINER_NOT_SUPPORTED : Int;
@@ -16,43 +20,63 @@ extern class AVResult {
 	static var CURRENT_PERIOD_EXPIRED : Int;
 	static var CURRENT_PERIOD_EXPIRED : Int;
 	static var DECODER_FAILED : Int;
 	static var DECODER_FAILED : Int;
 	static var DEVICE_OPEN_ERROR : Int;
 	static var DEVICE_OPEN_ERROR : Int;
+	static var DID_NOT_GET_NEXT_FRAGMENT : Int;
 	static var DRM_INIT_ERROR : Int;
 	static var DRM_INIT_ERROR : Int;
 	static var DRM_NOT_AVAILABLE : Int;
 	static var DRM_NOT_AVAILABLE : Int;
+	static var END_OF_PERIOD : Int;
 	static var EOF : Int;
 	static var EOF : Int;
 	static var FILE_NOT_FOUND : Int;
 	static var FILE_NOT_FOUND : Int;
+	static var FILE_OPEN_ERROR : Int;
+	static var FILE_READ_ERROR : Int;
 	static var FILE_STRUCTURE_INVALID : Int;
 	static var FILE_STRUCTURE_INVALID : Int;
+	static var FILE_WRITE_ERROR : Int;
 	static var FRAGMENT_READ_ERROR : Int;
 	static var FRAGMENT_READ_ERROR : Int;
 	static var GENERIC_ERROR : Int;
 	static var GENERIC_ERROR : Int;
 	static var HTTP_TIME_OUT : Int;
 	static var HTTP_TIME_OUT : Int;
+	static var INCOMPATIBLE_RENDER_MODE : Int;
+	static var INCOMPATIBLE_VERSION : Int;
+	static var INTERNAL_ERROR : Int;
 	static var INVALID_OPERATION : Int;
 	static var INVALID_OPERATION : Int;
 	static var INVALID_PARAMETER : Int;
 	static var INVALID_PARAMETER : Int;
 	static var INVALID_REPLACE_DURATION : Int;
 	static var INVALID_REPLACE_DURATION : Int;
 	static var INVALID_SEEK_TIME : Int;
 	static var INVALID_SEEK_TIME : Int;
 	static var INVALID_WITH_AUDIO_ONLY_FILE : Int;
 	static var INVALID_WITH_AUDIO_ONLY_FILE : Int;
 	static var IRRECOVERABLE_ERROR : Int;
 	static var IRRECOVERABLE_ERROR : Int;
+	static var LISTENER_NOT_FOUND : Int;
 	static var LIVE_HOLD : Int;
 	static var LIVE_HOLD : Int;
 	static var LIVE_WINDOW_MOVED_BACKWARD : Int;
 	static var LIVE_WINDOW_MOVED_BACKWARD : Int;
 	static var LOST_CONNECTION_RECOVERABLE : Int;
 	static var LOST_CONNECTION_RECOVERABLE : Int;
+	static var MANIFEST_FILE_UNEXPECTEDLY_CHANGED : Int;
 	static var NETWORK_DOWN : Int;
 	static var NETWORK_DOWN : Int;
 	static var NETWORK_ERROR : Int;
 	static var NETWORK_ERROR : Int;
 	static var NETWORK_UNAVAILABLE : Int;
 	static var NETWORK_UNAVAILABLE : Int;
 	static var NOT_IMPLEMENTED : Int;
 	static var NOT_IMPLEMENTED : Int;
+	static var NO_AUDIO_SINK : Int;
 	static var NO_FIXED_SIZE : Int;
 	static var NO_FIXED_SIZE : Int;
+	static var NO_TIMELINE : Int;
 	static var NO_USEABLE_BITRATE_PROFILE : Int;
 	static var NO_USEABLE_BITRATE_PROFILE : Int;
+	static var NULL_OPERATION : Int;
 	static var ONLY_ALLOWED_IN_PAUSED_STATE : Int;
 	static var ONLY_ALLOWED_IN_PAUSED_STATE : Int;
 	static var OPERATION_ABORTED : Int;
 	static var OPERATION_ABORTED : Int;
 	static var OUT_OF_MEMORY : Int;
 	static var OUT_OF_MEMORY : Int;
 	static var OVERFLOW : Int;
 	static var OVERFLOW : Int;
 	static var PARSE_ERROR : Int;
 	static var PARSE_ERROR : Int;
+	static var PARTIAL_REPLACEMENT : Int;
 	static var PERIOD_HOLD : Int;
 	static var PERIOD_HOLD : Int;
 	static var PERIOD_NOT_LOADED : Int;
 	static var PERIOD_NOT_LOADED : Int;
 	static var PLAYBACK_NOT_ENABLED : Int;
 	static var PLAYBACK_NOT_ENABLED : Int;
+	static var POSTROLL_WITH_LIVE_NOT_ALLOWED : Int;
 	static var PREVIOUS_STEP_SEEK_IN_PROGRESS : Int;
 	static var PREVIOUS_STEP_SEEK_IN_PROGRESS : Int;
+	static var PROTOCOL_NOT_SUPPORTED : Int;
 	static var RANGE_ERROR : Int;
 	static var RANGE_ERROR : Int;
+	static var RANGE_SPANS_READHEAD : Int;
+	static var RENDITION_M3U8_ERROR : Int;
 	static var REPLACEMENT_FAILED : Int;
 	static var REPLACEMENT_FAILED : Int;
 	static var RESOURCE_NOT_SPECIFIED : Int;
 	static var RESOURCE_NOT_SPECIFIED : Int;
 	static var SEEK_FAILED : Int;
 	static var SEEK_FAILED : Int;
+	static var SEGMENT_SKIPPED_ON_FAILURE : Int;
 	static var SIZE_UNKNOWN : Int;
 	static var SIZE_UNKNOWN : Int;
+	static var SPS_PPS_FOUND_OUTSIDE_AVCC : Int;
 	static var SUCCESS : Int;
 	static var SUCCESS : Int;
 	static var SWITCH_TO_ASYMMETRIC_PROFILE : Int;
 	static var SWITCH_TO_ASYMMETRIC_PROFILE : Int;
 	static var UNDERFLOW : Int;
 	static var UNDERFLOW : Int;

+ 3 - 0
std/flash/media/AVStream.hx

@@ -19,12 +19,15 @@ extern class AVStream extends flash.events.EventDispatcher {
 	var volume : Float;
 	var volume : Float;
 	function new(source : AVSource) : Void;
 	function new(source : AVSource) : Void;
 	function dispose() : Void;
 	function dispose() : Void;
+	function fastForward(rate : Float) : AVResult;
 	function pause() : AVResult;
 	function pause() : AVResult;
 	function play() : AVResult;
 	function play() : AVResult;
 	function resume() : Bool;
 	function resume() : Bool;
+	function rewind(rate : Float) : AVResult;
 	function seek(offset : Float, inBufferSeek : Bool = true) : AVResult;
 	function seek(offset : Float, inBufferSeek : Bool = true) : AVResult;
 	function seekToLivePoint() : AVResult;
 	function seekToLivePoint() : AVResult;
 	function seekToLocalTime(periodIndex : Int, time : Float) : AVResult;
 	function seekToLocalTime(periodIndex : Int, time : Float) : AVResult;
+	function setPlaySpeed(speed : Float, reserved : Float) : Void;
 	function step(frames : Int) : AVResult;
 	function step(frames : Int) : AVResult;
 	static var HARDWARE : String;
 	static var HARDWARE : String;
 	static var SOFTWARE : String;
 	static var SOFTWARE : String;

+ 10 - 0
std/flash/media/StageVideoAvailabilityReason.hx

@@ -0,0 +1,10 @@
+package flash.media;
+
+extern class StageVideoAvailabilityReason {
+	function new() : Void;
+	static var DRIVER_TOO_OLD : String;
+	static var NO_ERROR : String;
+	static var UNAVAILABLE : String;
+	static var USER_DISABLED : String;
+	static var WMODE_INCOMPATIBLE : String;
+}

+ 1 - 0
std/flash/net/NetStream.hx

@@ -63,4 +63,5 @@ extern class NetStream extends flash.events.EventDispatcher {
 	function togglePause() : Void;
 	function togglePause() : Void;
 	@:require(flash10) static var CONNECT_TO_FMS : String;
 	@:require(flash10) static var CONNECT_TO_FMS : String;
 	@:require(flash10) static var DIRECT_CONNECTIONS : String;
 	@:require(flash10) static var DIRECT_CONNECTIONS : String;
+	static function resetDRMVouchers() : Void;
 }
 }

+ 1 - 0
std/flash/net/URLRequest.hx

@@ -8,4 +8,5 @@ package flash.net;
 	var requestHeaders : Array<URLRequestHeader>;
 	var requestHeaders : Array<URLRequestHeader>;
 	var url : String;
 	var url : String;
 	function new(?url : String) : Void;
 	function new(?url : String) : Void;
+	function useRedirectedURL(sourceRequest : URLRequest, wholeURL : Bool = false, ?pattern : Dynamic, ?replace : String) : Void;
 }
 }

+ 3 - 0
std/flash/net/drm/DRMManager.hx

@@ -5,8 +5,11 @@ extern class DRMManager extends flash.events.EventDispatcher {
 	function authenticate(serverURL : String, domain : String, username : String, password : String) : Void;
 	function authenticate(serverURL : String, domain : String, username : String, password : String) : Void;
 	function loadPreviewVoucher(contentData : DRMContentData) : Void;
 	function loadPreviewVoucher(contentData : DRMContentData) : Void;
 	function loadVoucher(contentData : DRMContentData, setting : String) : Void;
 	function loadVoucher(contentData : DRMContentData, setting : String) : Void;
+	function resetDRMVouchers() : Void;
+	function returnVoucher(inServerURL : String, immediateCommit : Bool, licenseID : String, policyID : String) : Void;
 	function setAuthenticationToken(serverUrl : String, domain : String, token : flash.utils.ByteArray) : Void;
 	function setAuthenticationToken(serverUrl : String, domain : String, token : flash.utils.ByteArray) : Void;
 	function storeVoucher(voucher : flash.utils.ByteArray) : Void;
 	function storeVoucher(voucher : flash.utils.ByteArray) : Void;
 	static var isSupported(default,null) : Bool;
 	static var isSupported(default,null) : Bool;
+	static var networkIdleTimeout : Float;
 	static function getDRMManager() : DRMManager;
 	static function getDRMManager() : DRMManager;
 }
 }

+ 6 - 0
std/flash/net/drm/DRMReturnVoucherContext.hx

@@ -0,0 +1,6 @@
+package flash.net.drm;
+
+extern class DRMReturnVoucherContext extends DRMManagerSession {
+	function new() : Void;
+	function returnVoucher(inServerURL : String, immediateCommit : Bool, licenseID : String, policyID : String) : Void;
+}

+ 3 - 0
std/flash/net/drm/DRMVoucher.hx

@@ -1,10 +1,13 @@
 package flash.net.drm;
 package flash.net.drm;
 
 
 extern class DRMVoucher {
 extern class DRMVoucher {
+	var licenseID(default,null) : String;
 	var offlineLeaseEndDate(default,null) : Date;
 	var offlineLeaseEndDate(default,null) : Date;
 	var offlineLeaseStartDate(default,null) : Date;
 	var offlineLeaseStartDate(default,null) : Date;
 	var playbackTimeWindow(default,null) : DRMPlaybackTimeWindow;
 	var playbackTimeWindow(default,null) : DRMPlaybackTimeWindow;
 	var policies(default,null) : Dynamic;
 	var policies(default,null) : Dynamic;
+	var policyID(default,null) : String;
+	var serverURL(default,null) : String;
 	var voucherEndDate(default,null) : Date;
 	var voucherEndDate(default,null) : Date;
 	var voucherStartDate(default,null) : Date;
 	var voucherStartDate(default,null) : Date;
 	function new() : Void;
 	function new() : Void;

+ 1 - 0
std/flash/net/drm/VoucherAccessInfo.hx

@@ -4,5 +4,6 @@ package flash.net.drm;
 	var authenticationMethod(default,null) : String;
 	var authenticationMethod(default,null) : String;
 	var displayName(default,null) : String;
 	var displayName(default,null) : String;
 	var domain(default,null) : String;
 	var domain(default,null) : String;
+	var policyID(default,null) : String;
 	function new() : Void;
 	function new() : Void;
 }
 }

+ 10 - 0
std/flash/system/ConnexionsClient.hx

@@ -0,0 +1,10 @@
+package flash.system;
+
+@:final extern class ConnexionsClient {
+	var enabled(default,null) : Bool;
+	function new() : Void;
+	function Connexions() : Dynamic;
+	function _init(port : Int, secret : String, topLocation : String, documentReferrer : String, windowLocation : String, movie : String, userAgent : String) : Void;
+	function autoAdd() : Dynamic;
+	function manualAdd() : Dynamic;
+}

+ 2 - 2
std/flash8/_std/Std.hx

@@ -26,8 +26,8 @@
 		return untyped flash.Boot.__instanceof(v,t);
 		return untyped flash.Boot.__instanceof(v,t);
 	}
 	}
 
 
-	public static function instance<T>( v : { }, c : Class<T> ) : T {
-		return Std.is(v, c) ? cast v : null;
+	public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return Std.is(value, c) ? cast value : null;
 	}
 	}
 	
 	
 	public static function string( s : Dynamic ) : String {
 	public static function string( s : Dynamic ) : String {

+ 0 - 4
std/flash8/display/BitmapData.hx

@@ -1,9 +1,5 @@
 package flash.display;
 package flash.display;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 import flash.geom.Rectangle;
 import flash.geom.Rectangle;
 import flash.geom.Point;
 import flash.geom.Point;
 
 

+ 0 - 4
std/flash8/filters/BitmapFilter.hx

@@ -1,9 +1,5 @@
 package flash.filters;
 package flash.filters;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class BitmapFilter {
 extern class BitmapFilter {
 
 
 }
 }

+ 0 - 4
std/flash8/geom/ColorTransform.hx

@@ -1,9 +1,5 @@
 package flash.geom;
 package flash.geom;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class ColorTransform {
 extern class ColorTransform {
 
 
 	var rgb : Float;
 	var rgb : Float;

+ 0 - 4
std/flash8/geom/Matrix.hx

@@ -1,9 +1,5 @@
 package flash.geom;
 package flash.geom;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class Matrix {
 extern class Matrix {
 
 
 	// 3x2 affine 2D matrix
 	// 3x2 affine 2D matrix

+ 0 - 4
std/flash8/geom/Point.hx

@@ -1,9 +1,5 @@
 package flash.geom;
 package flash.geom;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class Point<T> {
 extern class Point<T> {
 
 
 	var x : T;
 	var x : T;

+ 0 - 4
std/flash8/geom/Rectangle.hx

@@ -1,9 +1,5 @@
 package flash.geom;
 package flash.geom;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class Rectangle<T> {
 extern class Rectangle<T> {
 
 
 	var left : T;
 	var left : T;

+ 0 - 4
std/flash8/geom/Transform.hx

@@ -1,9 +1,5 @@
 package flash.geom;
 package flash.geom;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class Transform {
 extern class Transform {
 
 
 	var matrix : Matrix;
 	var matrix : Matrix;

+ 0 - 4
std/flash8/net/FileReference.hx

@@ -1,9 +1,5 @@
 package flash.net;
 package flash.net;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class FileReference {
 extern class FileReference {
 
 
 	var creator : String;
 	var creator : String;

+ 0 - 4
std/flash8/net/FileReferenceList.hx

@@ -1,9 +1,5 @@
 package flash.net;
 package flash.net;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class FileReferenceList {
 extern class FileReferenceList {
 
 
 	var fileList : Array<Dynamic>;
 	var fileList : Array<Dynamic>;

+ 0 - 4
std/flash8/text/TextRenderer.hx

@@ -1,9 +1,5 @@
 package flash.text;
 package flash.text;
 
 
-#if !flash8
-"This class is only accesible in Flash8"
-#end
-
 extern class TextRenderer {
 extern class TextRenderer {
 
 
 	static var maxLevel : Float;
 	static var maxLevel : Float;

+ 42 - 5
std/haxe/Http.hx

@@ -153,6 +153,30 @@ class Http {
 	}
 	}
 	#end
 	#end
 
 
+	#if (js || flash9)
+
+	#if js
+	var req:js.html.XMLHttpRequest;
+	#elseif flash9
+	var req:flash.net.URLLoader;
+	#end
+	
+	/**
+		Cancels `this` Http request if `request` has been called and a response 
+		has not yet been received.
+	**/
+	public function cancel()
+	{
+		if (req == null) return;
+		#if js
+		req.abort();
+		#elseif flash9
+		req.close();
+		#end
+		req = null;
+	}
+	#end
+
 	/**
 	/**
 		Sends `this` Http request to the Url specified by `this.url`.
 		Sends `this` Http request to the Url specified by `this.url`.
 
 
@@ -174,7 +198,7 @@ class Http {
 		var me = this;
 		var me = this;
 	#if js
 	#if js
 		me.responseData = null;
 		me.responseData = null;
-		var r = js.Browser.createXMLHttpRequest();
+		var r = req = js.Browser.createXMLHttpRequest();
 		var onreadystatechange = function(_) {
 		var onreadystatechange = function(_) {
 			if( r.readyState != 4 )
 			if( r.readyState != 4 )
 				return;
 				return;
@@ -183,16 +207,23 @@ class Http {
 				s = null;
 				s = null;
 			if( s != null )
 			if( s != null )
 				me.onStatus(s);
 				me.onStatus(s);
-			if( s != null && s >= 200 && s < 400 )
+			if( s != null && s >= 200 && s < 400 ) {
+				me.req = null;
 				me.onData(me.responseData = r.responseText);
 				me.onData(me.responseData = r.responseText);
-			else if ( s == null )
-				me.onError("Failed to connect or resolve host")
+			}
+			else if ( s == null ) {
+				me.req = null;
+				me.onError("Failed to connect or resolve host");
+			}
 			else switch( s ) {
 			else switch( s ) {
 			case 12029:
 			case 12029:
+				me.req = null;
 				me.onError("Failed to connect to host");
 				me.onError("Failed to connect to host");
 			case 12007:
 			case 12007:
+				me.req = null;
 				me.onError("Unknown host");
 				me.onError("Unknown host");
 			default:
 			default:
+				me.req = null;
 				me.responseData = r.responseText;
 				me.responseData = r.responseText;
 				me.onError("Http Error #"+r.status);
 				me.onError("Http Error #"+r.status);
 			}
 			}
@@ -219,6 +250,7 @@ class Http {
 			} else
 			} else
 				r.open("GET",url,async);
 				r.open("GET",url,async);
 		} catch( e : Dynamic ) {
 		} catch( e : Dynamic ) {
+			me.req = null;
 			onError(e.toString());
 			onError(e.toString());
 			return;
 			return;
 		}
 		}
@@ -232,8 +264,9 @@ class Http {
 			onreadystatechange(null);
 			onreadystatechange(null);
 	#elseif flash9
 	#elseif flash9
 		me.responseData = null;
 		me.responseData = null;
-		var loader = new flash.net.URLLoader();
+		var loader = req = new flash.net.URLLoader();
 		loader.addEventListener( "complete", function(e) {
 		loader.addEventListener( "complete", function(e) {
+			me.req = null;
 			me.responseData = loader.data;
 			me.responseData = loader.data;
 			me.onData( loader.data );
 			me.onData( loader.data );
 		});
 		});
@@ -243,10 +276,12 @@ class Http {
 				me.onStatus( e.status );
 				me.onStatus( e.status );
 		});
 		});
 		loader.addEventListener( "ioError", function(e:flash.events.IOErrorEvent){
 		loader.addEventListener( "ioError", function(e:flash.events.IOErrorEvent){
+			me.req = null;
 			me.responseData = loader.data;
 			me.responseData = loader.data;
 			me.onError(e.text);
 			me.onError(e.text);
 		});
 		});
 		loader.addEventListener( "securityError", function(e:flash.events.SecurityErrorEvent){
 		loader.addEventListener( "securityError", function(e:flash.events.SecurityErrorEvent){
+			me.req = null;
 			me.onError(e.text);
 			me.onError(e.text);
 		});
 		});
 
 
@@ -283,6 +318,7 @@ class Http {
 		try {
 		try {
 			loader.load( request );
 			loader.load( request );
 		}catch( e : Dynamic ){
 		}catch( e : Dynamic ){
+			me.req = null;
 			onError("Exception: "+Std.string(e));
 			onError("Exception: "+Std.string(e));
 		}
 		}
 	#elseif flash
 	#elseif flash
@@ -602,6 +638,7 @@ class Http {
 			var a = hline.split(": ");
 			var a = hline.split(": ");
 			var hname = a.shift();
 			var hname = a.shift();
 			var hval = if( a.length == 1 ) a[0] else a.join(": ");
 			var hval = if( a.length == 1 ) a[0] else a.join(": ");
+			hval = StringTools.ltrim( StringTools.rtrim( hval ) );
 			responseHeaders.set(hname, hval);
 			responseHeaders.set(hname, hval);
 			switch(hname.toLowerCase())
 			switch(hname.toLowerCase())
 			{
 			{

+ 17 - 453
std/haxe/Json.hx

@@ -24,467 +24,31 @@ package haxe;
 /**
 /**
 	Crossplatform JSON API : it will automatically use the optimized native API if available.
 	Crossplatform JSON API : it will automatically use the optimized native API if available.
 	Use -D haxeJSON to force usage of the Haxe implementation even if a native API is found : this will provide
 	Use -D haxeJSON to force usage of the Haxe implementation even if a native API is found : this will provide
-	extra encoding features such as enums (replaced by their index), Hashs and Iterable.
+	extra encoding features such as enums (replaced by their index) and StringMaps.
 **/
 **/
-#if ((flash11 || (js && !old_browser)) && !haxeJSON)
-@:native('JSON') extern
-#end
 class Json {
 class Json {
 
 
-#if (haxeJSON || !(flash11 || (js && !old_browser)))
-	var buf : #if flash9 flash.utils.ByteArray #else StringBuf #end;
-	var str : String;
-	var pos : Int;
+	/**
+		Parses given JSON-encoded `text` and returns the resulting object.
 
 
-	function new() {
-	}
-
-	@:extern inline function addChar(c:Int) {
-		#if flash9
-		buf.writeByte(c);
-		#else
-		buf.addChar(c);
-		#end
-	}
-
-	@:extern inline function add(v:String) {
-		#if flash9
-		// argument is not always a string but will be automatically casted
-		buf.writeUTFBytes(v);
-		#else
-		buf.add(v);
-		#end
-	}
-
-	var replacer:Dynamic -> Dynamic -> Dynamic;
-
-	function toString(v:Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic) {
-		#if flash9
-		buf = new flash.utils.ByteArray();
-		buf.endian = flash.utils.Endian.BIG_ENDIAN;
-		buf.position = 0;
-		#else
-		buf = new StringBuf();
-		#end
-		this.replacer = replacer;
-		toStringRec("", v);
-		return buf.toString();
-	}
-
-	function fieldsString( v : Dynamic, fields : Array<String> )
-	{
-		var first = true;
-		addChar('{'.code);
-		for( f in fields ) {
-			var value = Reflect.field(v,f);
-			if( Reflect.isFunction(value) ) continue;
-			if( first ) first = false else addChar(','.code);
-			quote(f);
-			addChar(':'.code);
-			toStringRec(f, value);
-		}
-		addChar('}'.code);
-	}
-
-	#if flash9
-	function classString ( v : Dynamic ) {
-		fieldsString(v,Type.getInstanceFields(Type.getClass(v)));
-	}
-	#end
-
-	function objString( v : Dynamic ) {
-		fieldsString(v,Reflect.fields(v));
-	}
-
-	function toStringRec(k:Dynamic, v:Dynamic) {
-		if (replacer != null) v = replacer(k, v);
-		switch( Type.typeof(v) ) {
-		case TUnknown:
-			add('"???"');
-		case TObject:
-			objString(v);
-		case TInt:
-			add(v);
-		case TFloat:
-			add(Math.isFinite(v) ? v : 'null');
-		case TFunction:
-			add('"<fun>"');
-		case TClass(c):
-			if( c == String )
-				quote(v);
-			else if( c == Array ) {
-				var v : Array<Dynamic> = v;
-				addChar('['.code);
-				var len = v.length;
-				if( len > 0 ) {
-					toStringRec(0, v[0]);
-					var i = 1;
-					while( i < len ) {
-						addChar(','.code);
-						toStringRec(i, v[i++]);
-					}
-				}
-				addChar(']'.code);
-			} else if( c == haxe.ds.StringMap ) {
-				var v : haxe.ds.StringMap<Dynamic> = v;
-				var o = {};
-				for( k in v.keys() )
-					Reflect.setField(o,k,v.get(k));
-				objString(o);
-			} else
-				#if flash9
-				classString(v);
-				#else
-				objString(v);
-				#end
-		case TEnum(_):
-			var i : Dynamic = Type.enumIndex(v);
-			add(i);
-		case TBool:
-			add(#if php (v ? 'true' : 'false') #else v #end);
-		case TNull:
-			add('null');
-		}
-	}
-
-	function quote( s : String ) {
-		#if (neko || php || cpp)
-		if( s.length != haxe.Utf8.length(s) ) {
-			quoteUtf8(s);
-			return;
-		}
-		#end
-		addChar('"'.code);
-		var i = 0;
-		while( true ) {
-			var c = StringTools.fastCodeAt(s, i++);
-			if( StringTools.isEof(c) ) break;
-			switch( c ) {
-			case '"'.code: add('\\"');
-			case '\\'.code: add('\\\\');
-			case '\n'.code: add('\\n');
-			case '\r'.code: add('\\r');
-			case '\t'.code: add('\\t');
-			case 8: add('\\b');
-			case 12: add('\\f');
-			default:
-				#if flash9
-				if( c >= 128 ) add(String.fromCharCode(c)) else addChar(c);
-				#else
-				addChar(c);
-				#end
-			}
-		}
-		addChar('"'.code);
-	}
-
-	#if (neko || php || cpp)
-	function quoteUtf8( s : String ) {
-		var u = new haxe.Utf8();
-		haxe.Utf8.iter(s,function(c) {
-			switch( c ) {
-			case '\\'.code, '"'.code: u.addChar('\\'.code); u.addChar(c);
-			case '\n'.code: u.addChar('\\'.code); u.addChar('n'.code);
-			case '\r'.code: u.addChar('\\'.code); u.addChar('r'.code);
-			case '\t'.code: u.addChar('\\'.code); u.addChar('t'.code);
-			case 8: u.addChar('\\'.code); u.addChar('b'.code);
-			case 12: u.addChar('\\'.code); u.addChar('f'.code);
-			default: u.addChar(c);
-			}
-		});
-		buf.add('"');
-		buf.add(u.toString());
-		buf.add('"');
-	}
-	#end
-
-	function doParse( str : String ) {
-		this.str = str;
-		this.pos = 0;
-		return parseRec();
-	}
-
-	function invalidChar() {
-		pos--; // rewind
-		throw "Invalid char "+StringTools.fastCodeAt(str,pos)+" at position "+pos;
-	}
-
-	inline function nextChar() {
-		return StringTools.fastCodeAt(str,pos++);
-	}
-
-	function parseRec() : Dynamic {
-		while( true ) {
-			var c = nextChar();
-			switch( c ) {
-			case ' '.code, '\r'.code, '\n'.code, '\t'.code:
-				// loop
-			case '{'.code:
-				var obj = {}, field = null, comma : Null<Bool> = null;
-				while( true ) {
-					var c = nextChar();
-					switch( c ) {
-					case ' '.code, '\r'.code, '\n'.code, '\t'.code:
-						// loop
-					case '}'.code:
-						if( field != null || comma == false )
-							invalidChar();
-						return obj;
-					case ':'.code:
-						if( field == null )
-							invalidChar();
-						Reflect.setField(obj,field,parseRec());
-						field = null;
-						comma = true;
-					case ','.code:
-						if( comma ) comma = false else invalidChar();
-					case '"'.code:
-						if( comma ) invalidChar();
-						field = parseString();
-					default:
-						invalidChar();
-					}
-				}
-			case '['.code:
-				var arr = [], comma : Null<Bool> = null;
-				while( true ) {
-					var c = nextChar();
-					switch( c ) {
-					case ' '.code, '\r'.code, '\n'.code, '\t'.code:
-						// loop
-					case ']'.code:
-						if( comma == false ) invalidChar();
-						return arr;
-					case ','.code:
-						if( comma ) comma = false else invalidChar();
-					default:
-						if( comma ) invalidChar();
-						pos--;
-						arr.push(parseRec());
-						comma = true;
-					}
-				}
-			case 't'.code:
-				var save = pos;
-				if( nextChar() != 'r'.code || nextChar() != 'u'.code || nextChar() != 'e'.code ) {
-					pos = save;
-					invalidChar();
-				}
-				return true;
-			case 'f'.code:
-				var save = pos;
-				if( nextChar() != 'a'.code || nextChar() != 'l'.code || nextChar() != 's'.code || nextChar() != 'e'.code ) {
-					pos = save;
-					invalidChar();
-				}
-				return false;
-			case 'n'.code:
-				var save = pos;
-				if( nextChar() != 'u'.code || nextChar() != 'l'.code || nextChar() != 'l'.code ) {
-					pos = save;
-					invalidChar();
-				}
-				return null;
-			case '"'.code:
-				return parseString();
-			case '0'.code, '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code,'-'.code:
-				return parseNumber(c);
-			default:
-				invalidChar();
-			}
-		}
-	}
-
-	function parseString() {
-		var start = pos;
-		var buf = new StringBuf();
-		while( true ) {
-			var c = nextChar();
-			if( c == '"'.code )
-				break;
-			if( c == '\\'.code ) {
-				buf.addSub(str,start, pos - start - 1);
-				c = nextChar();
-				switch( c ) {
-				case "r".code: buf.addChar("\r".code);
-				case "n".code: buf.addChar("\n".code);
-				case "t".code: buf.addChar("\t".code);
-				case "b".code: buf.addChar(8);
-				case "f".code: buf.addChar(12);
-				case "/".code, '\\'.code, '"'.code: buf.addChar(c);
-				case 'u'.code:
-					var uc = Std.parseInt("0x" + str.substr(pos, 4));
-					pos += 4;
-					#if (neko || php || cpp)
-					if( uc <= 0x7F )
-						buf.addChar(uc);
-					else if( uc <= 0x7FF ) {
-						buf.addChar(0xC0 | (uc >> 6));
-						buf.addChar(0x80 | (uc & 63));
-					} else if( uc <= 0xFFFF ) {
-						buf.addChar(0xE0 | (uc >> 12));
-						buf.addChar(0x80 | ((uc >> 6) & 63));
-						buf.addChar(0x80 | (uc & 63));
-					} else {
-						buf.addChar(0xF0 | (uc >> 18));
-						buf.addChar(0x80 | ((uc >> 12) & 63));
-						buf.addChar(0x80 | ((uc >> 6) & 63));
-						buf.addChar(0x80 | (uc & 63));
-					}
-					#else
-					buf.addChar(uc);
-					#end
-				default:
-					throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1);
-				}
-				start = pos;
-			}
-			#if (neko || php || cpp)
-			// ensure utf8 chars are not cut
-			else if( c >= 0x80 ) {
-				pos++;
-				if( c >= 0xFC ) pos += 4;
-				else if( c >= 0xF8 ) pos += 3;
-				else if( c >= 0xF0 ) pos += 2;
-				else if( c >= 0xE0 ) pos++;
-			}
-			#end
-			else if( StringTools.isEof(c) )
-				throw "Unclosed string";
-		}
-		buf.addSub(str,start, pos - start - 1);
-		return buf.toString();
-	}
-
-	function invalidNumber( start : Int ) {
-		throw "Invalid number at position "+start+": " + str.substr(start, pos - start);
-	}
+		JSON objects are parsed into anonymous structures and JSON arrays
+		are parsed into Array<Dynamic>.
 
 
-	inline function parseNumber( c : Int ) {
-		var start = pos - 1;
-		var minus = c == '-'.code, digit = !minus, zero = c == '0'.code;
-		var point = false, e = false, pm = false, end = false;
-		while( true ) {
-			c = nextChar();
-			switch( c ) {
-				case '0'.code :
-					if (zero && !point) invalidNumber(start);
-					if (minus) {
-						minus = false; zero = true;
-					}
-					digit = true;
-				case '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code :
-					if (zero && !point) invalidNumber(start);
-					if (minus) minus = false;
-					digit = true; zero = false;
-				case '.'.code :
-					if (minus || point) invalidNumber(start);
-					digit = false; point = true;
-				case 'e'.code, 'E'.code :
-					if (minus || zero || e) invalidNumber(start);
-					digit = false; e = true;
-				case '+'.code, '-'.code :
-					if (!e || pm) invalidNumber(start);
-					digit = false; pm = true;
-				default :
-					if (!digit) invalidNumber(start);
-					pos--;
-					end = true;
-			}
-			if (end) break;
-		}
-		var f = Std.parseFloat(str.substr(start, pos - start));
-		var i = Std.int(f);
-		return if( i == f ) i else f;
+		If given `text` is not valid JSON, an exception will be thrown.
+	**/
+	public static inline function parse( text : String ) : Dynamic {
+		return haxe.format.JsonParser.parse(text);
 	}
 	}
 
 
-#end
+	/**
+		Encodes given `value` and returns the resulting JSON string.
 
 
-	public static function parse( text : String ) : Dynamic {
-		#if (php && !haxeJSON)
-		return phpJsonDecode(text);
-		#elseif (flash11 && !haxeJSON)
-		return null;
-		#else
-		return new Json().doParse(text);
-		#end
+		If `replacer` is given and is not null, it is used to retrieve
+		actual object to be encoded. The `replacer` function two parameters,
+		the key and the value being encoded. Initial key value is an empty string.
+	**/
+	public static inline function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic ) : String {
+		return haxe.format.JsonPrinter.print(value, replacer);
 	}
 	}
 
 
-	public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic ) : String {
-		#if (php && !haxeJSON)
-		return phpJsonEncode(value, replacer);
-		#elseif (flash11 && !haxeJSON)
-		return null;
-		#else
-		return new Json().toString(value, replacer);
-		#end
-	}
-
-	#if !haxeJSON
-		#if (js && old_browser)
-		static function __init__() untyped {
-			if( __js__('typeof(JSON)') != 'undefined' )
-				Json = __js__('JSON');
-		}
-		#end
-	#end
-
-	#if php
-	static function phpJsonDecode(json:String):Dynamic {
-		var val = untyped __call__("json_decode", json);
-		return convertAfterDecode(val);
-	}
-
-	static function convertAfterDecode(val:Dynamic):Dynamic {
-		var arr:php.NativeArray;
-		if (untyped __call__("is_object", val)) {
-			arr = phpMapArray(php.Lib.associativeArrayOfObject(val), convertAfterDecode);
-			return untyped __call__("_hx_anonymous", arr);
-		}
-		else if (untyped __call__("is_array", val)) {
-			arr = phpMapArray(val, convertAfterDecode);
-			return php.Lib.toHaxeArray(arr);
-		}
-		else
-			return val;
-	}
-
-	static function phpJsonEncode(val:Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic):String {
-		if(null != replacer)
-			return new Json().toString(val, replacer);
-		var json = untyped __call__("json_encode", convertBeforeEncode(val));
-		if (untyped __physeq__(json, false))
-			return throw "invalid json";
-		else
-			return json;
-	}
-
-	static function convertBeforeEncode(val:Dynamic):Dynamic {
-		var arr:php.NativeArray;
-		if (untyped __call__("is_object", val)) {
-			switch (untyped __call__("get_class", val)) {
-				case "_hx_anonymous", "stdClass" : arr = php.Lib.associativeArrayOfObject(val);
-				case "_hx_array" : arr = php.Lib.toPhpArray(val);
-				case "Date" : return Std.string(val); //.split(" ").join("T"); //better with "T"?
-				case "HList" : arr = php.Lib.toPhpArray(Lambda.array(val)); //convert List to array?
-				case "_hx_enum" : return Type.enumIndex(val);
-				case "StringMap", "IntMap" : arr = php.Lib.associativeArrayOfHash(val);
-				default : arr = php.Lib.associativeArrayOfObject(val);
-			}
-		}
-		else if (untyped __call__("is_array", val)) arr = val;
-		else {
-			if (untyped __call__("is_float",val) && !__call__("is_finite",val)) val = null;
-			return val;
-		}
-		return phpMapArray(arr, convertBeforeEncode);
-	}
-
-	inline static function phpMapArray(arr:php.NativeArray
-	, func:Dynamic->Dynamic):php.NativeArray {
-		return untyped __call__("array_map", func, arr);
-	}
-
-	#end
-
 }
 }

+ 2 - 2
std/haxe/Resource.hx

@@ -99,7 +99,7 @@ class Resource {
 				return new String(x.data);
 				return new String(x.data);
 				#else
 				#else
 				if( x.str != null ) return x.str;
 				if( x.str != null ) return x.str;
-				var b : haxe.io.Bytes = haxe.Unserializer.run(x.data);
+				var b : haxe.io.Bytes = haxe.crypto.Base64.decode(x.data);
 				return b.toString();
 				return b.toString();
 				#end
 				#end
 			}
 			}
@@ -133,7 +133,7 @@ class Resource {
 				return haxe.io.Bytes.ofData(cast x.data);
 				return haxe.io.Bytes.ofData(cast x.data);
 				#else
 				#else
 				if( x.str != null ) return haxe.io.Bytes.ofString(x.str);
 				if( x.str != null ) return haxe.io.Bytes.ofString(x.str);
-				return haxe.Unserializer.run(x.data);
+				return haxe.crypto.Base64.decode(x.data);
 				#end
 				#end
 			}
 			}
 		return null;
 		return null;

+ 1 - 1
std/haxe/Template.hx

@@ -96,7 +96,7 @@ class Template {
 
 
 		If `macros` has a field 'name', all occurrences of $$name(args) are
 		If `macros` has a field 'name', all occurrences of $$name(args) are
 		replaced with the result of calling that field. The first argument is
 		replaced with the result of calling that field. The first argument is
-		always the the resolve() method, followed by the given arguments.
+		always the resolve() method, followed by the given arguments.
 		If `macros` has no such field, the result is unspecified.
 		If `macros` has no such field, the result is unspecified.
 
 
 		If `context` is null, the result is unspecified. If `macros` is null,
 		If `context` is null, the result is unspecified. If `macros` is null,

+ 43 - 12
std/haxe/Timer.hx

@@ -28,15 +28,22 @@ package haxe;
 	The intended usage is to create an instance of the Timer class with a given
 	The intended usage is to create an instance of the Timer class with a given
 	interval, set its run() method to a custom function to be invoked and
 	interval, set its run() method to a custom function to be invoked and
 	eventually call stop() to stop the Timer.
 	eventually call stop() to stop the Timer.
+
+	Note that a running Timer may or may not prevent the program to exit 
+	automatically when main() returns.
 	
 	
 	It is also possible to extend this class and override its run() method in
 	It is also possible to extend this class and override its run() method in
 	the child class.
 	the child class.
 **/
 **/
 class Timer {
 class Timer {
-	#if (neko || php || cpp)
-	#else
+	#if (flash || js || java)
 
 
-	private var id : Null<Int>;
+	#if (flash || js)
+		private var id : Null<Int>;
+	#elseif java
+		private var timer : java.util.Timer;
+		private var task : java.util.TimerTask;
+	#end
 
 
 	/**
 	/**
 		Creates a new timer that will run every `time_ms` milliseconds.
 		Creates a new timer that will run every `time_ms` milliseconds.
@@ -59,6 +66,9 @@ class Timer {
 		#elseif js
 		#elseif js
 			var me = this;
 			var me = this;
 			id = untyped setInterval(function() me.run(),time_ms);
 			id = untyped setInterval(function() me.run(),time_ms);
+		#elseif java
+			timer = new java.util.Timer();
+			timer.scheduleAtFixedRate(task = new TimerTask(this), haxe.Int64.ofInt(time_ms), haxe.Int64.ofInt(time_ms));
 		#end
 		#end
 	}
 	}
 
 
@@ -71,16 +81,22 @@ class Timer {
 		It is not possible to restart `this` Timer once stopped.
 		It is not possible to restart `this` Timer once stopped.
 	**/
 	**/
 	public function stop() {
 	public function stop() {
-		if( id == null )
-			return;
-		#if flash9
-			untyped __global__["flash.utils.clearInterval"](id);
-		#elseif flash
-			untyped _global["clearInterval"](id);
-		#elseif js
-			untyped clearInterval(id);
+		#if (flash || js)
+			if( id == null )
+				return;
+			#if flash9
+				untyped __global__["flash.utils.clearInterval"](id);
+			#elseif flash
+				untyped _global["clearInterval"](id);
+			#elseif js
+				untyped clearInterval(id);
+			#end
+			id = null;
+		#elseif java
+			timer.cancel();
+			timer = null;
+			task = null;
 		#end
 		#end
-		id = null;
 	}
 	}
 
 
 	/**
 	/**
@@ -159,3 +175,18 @@ class Timer {
 	}
 	}
 
 
 }
 }
+
+#if java
+@:nativeGen
+private class TimerTask extends java.util.TimerTask {
+	var timer:Timer;
+	public function new(timer:Timer):Void {
+		super();
+		this.timer = timer;
+	}
+
+	@:overload public function run():Void {
+		timer.run();
+	}
+}
+#end

+ 1 - 1
std/haxe/crypto/Base64.hx

@@ -32,7 +32,7 @@ class Base64 {
 	public static function encode( bytes : haxe.io.Bytes, complement = true ) : String {
 	public static function encode( bytes : haxe.io.Bytes, complement = true ) : String {
 		var str = new BaseCode(BYTES).encodeBytes(bytes).toString();
 		var str = new BaseCode(BYTES).encodeBytes(bytes).toString();
 		if( complement )
 		if( complement )
-			for( i in 0...(bytes.length*4)%3 )
+			for( i in 0...(3-(bytes.length*4)%3)%3 )
 				str += "=";
 				str += "=";
 		return str;
 		return str;
 	}
 	}

+ 1 - 0
std/haxe/ds/Vector.hx

@@ -173,6 +173,7 @@ abstract Vector<T>(VectorData<T>) {
 
 
 		If `array` is null, the result is unspecified.
 		If `array` is null, the result is unspecified.
 	**/
 	**/
+	#if as3 @:extern #end
 	static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
 	static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
 		// TODO: Optimize this for flash (and others?)
 		// TODO: Optimize this for flash (and others?)
 		var vec = new Vector<T>(array.length);
 		var vec = new Vector<T>(array.length);

+ 210 - 0
std/haxe/format/JsonParser.hx

@@ -0,0 +1,210 @@
+package haxe.format;
+
+class JsonParser {
+
+	static public inline function parse(str : String) : Dynamic {
+		return new JsonParser(str).parseRec();
+	}
+
+	var str : String;
+	var pos : Int;
+
+	function new( str : String ) {
+		this.str = str;
+		this.pos = 0;
+	}
+
+	function parseRec() : Dynamic {
+		while( true ) {
+			var c = nextChar();
+			switch( c ) {
+			case ' '.code, '\r'.code, '\n'.code, '\t'.code:
+				// loop
+			case '{'.code:
+				var obj = {}, field = null, comma : Null<Bool> = null;
+				while( true ) {
+					var c = nextChar();
+					switch( c ) {
+					case ' '.code, '\r'.code, '\n'.code, '\t'.code:
+						// loop
+					case '}'.code:
+						if( field != null || comma == false )
+							invalidChar();
+						return obj;
+					case ':'.code:
+						if( field == null )
+							invalidChar();
+						Reflect.setField(obj,field,parseRec());
+						field = null;
+						comma = true;
+					case ','.code:
+						if( comma ) comma = false else invalidChar();
+					case '"'.code:
+						if( comma ) invalidChar();
+						field = parseString();
+					default:
+						invalidChar();
+					}
+				}
+			case '['.code:
+				var arr = [], comma : Null<Bool> = null;
+				while( true ) {
+					var c = nextChar();
+					switch( c ) {
+					case ' '.code, '\r'.code, '\n'.code, '\t'.code:
+						// loop
+					case ']'.code:
+						if( comma == false ) invalidChar();
+						return arr;
+					case ','.code:
+						if( comma ) comma = false else invalidChar();
+					default:
+						if( comma ) invalidChar();
+						pos--;
+						arr.push(parseRec());
+						comma = true;
+					}
+				}
+			case 't'.code:
+				var save = pos;
+				if( nextChar() != 'r'.code || nextChar() != 'u'.code || nextChar() != 'e'.code ) {
+					pos = save;
+					invalidChar();
+				}
+				return true;
+			case 'f'.code:
+				var save = pos;
+				if( nextChar() != 'a'.code || nextChar() != 'l'.code || nextChar() != 's'.code || nextChar() != 'e'.code ) {
+					pos = save;
+					invalidChar();
+				}
+				return false;
+			case 'n'.code:
+				var save = pos;
+				if( nextChar() != 'u'.code || nextChar() != 'l'.code || nextChar() != 'l'.code ) {
+					pos = save;
+					invalidChar();
+				}
+				return null;
+			case '"'.code:
+				return parseString();
+			case '0'.code, '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code,'-'.code:
+				return parseNumber(c);
+			default:
+				invalidChar();
+			}
+		}
+	}
+
+	function parseString() {
+		var start = pos;
+		var buf = new StringBuf();
+		while( true ) {
+			var c = nextChar();
+			if( c == '"'.code )
+				break;
+			if( c == '\\'.code ) {
+				buf.addSub(str,start, pos - start - 1);
+				c = nextChar();
+				switch( c ) {
+				case "r".code: buf.addChar("\r".code);
+				case "n".code: buf.addChar("\n".code);
+				case "t".code: buf.addChar("\t".code);
+				case "b".code: buf.addChar(8);
+				case "f".code: buf.addChar(12);
+				case "/".code, '\\'.code, '"'.code: buf.addChar(c);
+				case 'u'.code:
+					var uc = Std.parseInt("0x" + str.substr(pos, 4));
+					pos += 4;
+					#if (neko || php || cpp)
+					if( uc <= 0x7F )
+						buf.addChar(uc);
+					else if( uc <= 0x7FF ) {
+						buf.addChar(0xC0 | (uc >> 6));
+						buf.addChar(0x80 | (uc & 63));
+					} else if( uc <= 0xFFFF ) {
+						buf.addChar(0xE0 | (uc >> 12));
+						buf.addChar(0x80 | ((uc >> 6) & 63));
+						buf.addChar(0x80 | (uc & 63));
+					} else {
+						buf.addChar(0xF0 | (uc >> 18));
+						buf.addChar(0x80 | ((uc >> 12) & 63));
+						buf.addChar(0x80 | ((uc >> 6) & 63));
+						buf.addChar(0x80 | (uc & 63));
+					}
+					#else
+					buf.addChar(uc);
+					#end
+				default:
+					throw "Invalid escape sequence \\" + String.fromCharCode(c) + " at position " + (pos - 1);
+				}
+				start = pos;
+			}
+			#if (neko || php || cpp)
+			// ensure utf8 chars are not cut
+			else if( c >= 0x80 ) {
+				pos++;
+				if( c >= 0xFC ) pos += 4;
+				else if( c >= 0xF8 ) pos += 3;
+				else if( c >= 0xF0 ) pos += 2;
+				else if( c >= 0xE0 ) pos++;
+			}
+			#end
+			else if( StringTools.isEof(c) )
+				throw "Unclosed string";
+		}
+		buf.addSub(str,start, pos - start - 1);
+		return buf.toString();
+	}
+
+	inline function parseNumber( c : Int ) : Dynamic {
+		var start = pos - 1;
+		var minus = c == '-'.code, digit = !minus, zero = c == '0'.code;
+		var point = false, e = false, pm = false, end = false;
+		while( true ) {
+			c = nextChar();
+			switch( c ) {
+				case '0'.code :
+					if (zero && !point) invalidNumber(start);
+					if (minus) {
+						minus = false; zero = true;
+					}
+					digit = true;
+				case '1'.code,'2'.code,'3'.code,'4'.code,'5'.code,'6'.code,'7'.code,'8'.code,'9'.code :
+					if (zero && !point) invalidNumber(start);
+					if (minus) minus = false;
+					digit = true; zero = false;
+				case '.'.code :
+					if (minus || point) invalidNumber(start);
+					digit = false; point = true;
+				case 'e'.code, 'E'.code :
+					if (minus || zero || e) invalidNumber(start);
+					digit = false; e = true;
+				case '+'.code, '-'.code :
+					if (!e || pm) invalidNumber(start);
+					digit = false; pm = true;
+				default :
+					if (!digit) invalidNumber(start);
+					pos--;
+					end = true;
+			}
+			if (end) break;
+		}
+		var f = Std.parseFloat(str.substr(start, pos - start));
+		var i = Std.int(f);
+		return if( i == f ) i else f;
+	}
+
+	inline function nextChar() {
+		return StringTools.fastCodeAt(str,pos++);
+	}
+
+	function invalidChar() {
+		pos--; // rewind
+		throw "Invalid char "+StringTools.fastCodeAt(str,pos)+" at position "+pos;
+	}
+
+	function invalidNumber( start : Int ) {
+		throw "Invalid number at position "+start+": " + str.substr(start, pos - start);
+	}
+}

+ 168 - 0
std/haxe/format/JsonPrinter.hx

@@ -0,0 +1,168 @@
+package haxe.format;
+
+class JsonPrinter {
+
+	static public function print(o:Dynamic, replacer:Dynamic -> Dynamic -> Dynamic) : String {
+		var printer = new JsonPrinter(replacer);
+		printer.write("", o);
+		return printer.buf.toString();
+	}
+
+	var buf : #if flash9 flash.utils.ByteArray #else StringBuf #end;
+	var replacer : Dynamic -> Dynamic -> Dynamic;
+	
+	function new(replacer:Dynamic -> Dynamic -> Dynamic) {
+		this.replacer = replacer;
+
+		#if flash9
+		buf = new flash.utils.ByteArray();
+		buf.endian = flash.utils.Endian.BIG_ENDIAN;
+		buf.position = 0;
+		#else
+		buf = new StringBuf();
+		#end
+	}
+
+	function write(k:Dynamic, v:Dynamic) {
+		if (replacer != null) v = replacer(k, v);
+		switch( Type.typeof(v) ) {
+		case TUnknown:
+			add('"???"');
+		case TObject:
+			objString(v);
+		case TInt:
+			add(v);
+		case TFloat:
+			add(Math.isFinite(v) ? v : 'null');
+		case TFunction:
+			add('"<fun>"');
+		case TClass(c):
+			if( c == String )
+				quote(v);
+			else if( c == Array ) {
+				var v : Array<Dynamic> = v;
+				addChar('['.code);
+				var len = v.length;
+				if( len > 0 ) {
+					write(0, v[0]);
+					var i = 1;
+					while( i < len ) {
+						addChar(','.code);
+						write(i, v[i++]);
+					}
+				}
+				addChar(']'.code);
+			} else if( c == haxe.ds.StringMap ) {
+				var v : haxe.ds.StringMap<Dynamic> = v;
+				var o = {};
+				for( k in v.keys() )
+					Reflect.setField(o,k,v.get(k));
+				objString(o);
+			} else
+				#if flash9
+				classString(v);
+				#else
+				objString(v);
+				#end
+		case TEnum(_):
+			var i : Dynamic = Type.enumIndex(v);
+			add(i);
+		case TBool:
+			add(#if php (v ? 'true' : 'false') #else v #end);
+		case TNull:
+			add('null');
+		}
+	}
+
+	@:extern inline function addChar(c:Int) {
+		#if flash9
+		buf.writeByte(c);
+		#else
+		buf.addChar(c);
+		#end
+	}
+
+	@:extern inline function add(v:String) {
+		#if flash9
+		// argument is not always a string but will be automatically casted
+		buf.writeUTFBytes(v);
+		#else
+		buf.add(v);
+		#end
+	}
+
+	#if flash9
+	function classString ( v : Dynamic ) {
+		fieldsString(v,Type.getInstanceFields(Type.getClass(v)));
+	}
+	#end
+
+	inline function objString( v : Dynamic ) {
+		fieldsString(v,Reflect.fields(v));
+	}
+
+	function fieldsString( v : Dynamic, fields : Array<String> ) {
+		var first = true;
+		addChar('{'.code);
+		for( f in fields ) {
+			var value = Reflect.field(v,f);
+			if( Reflect.isFunction(value) ) continue;
+			if( first ) first = false else addChar(','.code);
+			quote(f);
+			addChar(':'.code);
+			write(f, value);
+		}
+		addChar('}'.code);
+	}
+
+	function quote( s : String ) {
+		#if (neko || php || cpp)
+		if( s.length != haxe.Utf8.length(s) ) {
+			quoteUtf8(s);
+			return;
+		}
+		#end
+		addChar('"'.code);
+		var i = 0;
+		while( true ) {
+			var c = StringTools.fastCodeAt(s, i++);
+			if( StringTools.isEof(c) ) break;
+			switch( c ) {
+			case '"'.code: add('\\"');
+			case '\\'.code: add('\\\\');
+			case '\n'.code: add('\\n');
+			case '\r'.code: add('\\r');
+			case '\t'.code: add('\\t');
+			case 8: add('\\b');
+			case 12: add('\\f');
+			default:
+				#if flash9
+				if( c >= 128 ) add(String.fromCharCode(c)) else addChar(c);
+				#else
+				addChar(c);
+				#end
+			}
+		}
+		addChar('"'.code);
+	}
+
+	#if (neko || php || cpp)
+	function quoteUtf8( s : String ) {
+		var u = new haxe.Utf8();
+		haxe.Utf8.iter(s,function(c) {
+			switch( c ) {
+			case '\\'.code, '"'.code: u.addChar('\\'.code); u.addChar(c);
+			case '\n'.code: u.addChar('\\'.code); u.addChar('n'.code);
+			case '\r'.code: u.addChar('\\'.code); u.addChar('r'.code);
+			case '\t'.code: u.addChar('\\'.code); u.addChar('t'.code);
+			case 8: u.addChar('\\'.code); u.addChar('b'.code);
+			case 12: u.addChar('\\'.code); u.addChar('f'.code);
+			default: u.addChar(c);
+			}
+		});
+		buf.add('"');
+		buf.add(u.toString());
+		buf.add('"');
+	}
+	#end
+}

+ 10 - 7
std/haxe/io/Path.hx

@@ -199,20 +199,23 @@ class Path {
 	}
 	}
 	
 	
 	/**
 	/**
-		Removes a trailing slash from `path` if it exists.
+		Removes trailing slashes from `path`.
 		
 		
 		If `path` does not end with a `/` or `\`, `path` is returned unchanged.
 		If `path` does not end with a `/` or `\`, `path` is returned unchanged.
 		
 		
-		Otherwise the substring of `path` excluding the trailing slash or
-		backslash is returned.
+		Otherwise the substring of `path` excluding the trailing slashes or
+		backslashes is returned.
 		
 		
 		If `path` is null, the result is unspecified.
 		If `path` is null, the result is unspecified.
 	**/
 	**/
 	@:require(haxe_ver >= 3.01)
 	@:require(haxe_ver >= 3.01)
-	public static function removeTrailingSlash ( path : String ) : String {
-		return switch(path.charCodeAt(path.length - 1)) {
-			case '/'.code | '\\'.code: path.substr(0, -1);
-			case _: path;
+	public static function removeTrailingSlashes ( path : String ) : String {
+		while (true) {
+			switch(path.charCodeAt(path.length - 1)) {
+				case '/'.code | '\\'.code: path = path.substr(0, -1);
+				case _: break;
+			}
 		}
 		}
+		return path;
 	}
 	}
 }
 }

+ 0 - 136
std/haxe/macro/Build.hx

@@ -1,136 +0,0 @@
-/*
- * Copyright (C)2005-2012 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-package haxe.macro;
-
-import haxe.macro.Context;
-import haxe.macro.Expr;
-import haxe.macro.Type;
-
-using haxe.macro.Tools;
-
-class Build {
-	macro static public function buildEnumAbstract():Array<Field> {
-		var fields = Context.getBuildFields();
-		var a = switch(Context.getLocalClass().get().kind) {
-			case KAbstractImpl(a): a;
-			case _: throw "";
-		}
-		var aT = a.get();
-		var tThis = aT.type;
-		var ctA = TAbstract(a, aT.params.map(function(tp) return tp.t));
-		for (field in fields) {
-			// allow extra static fields
-			if( Lambda.has(field.access,AStatic) )
-				continue;
-			switch(field.kind) {
-				case FVar(t, e):
-					field.access = [AStatic,APublic,AInline];
-					if (e == null) Context.error("Value required", field.pos);
-					var monos = aT.params.map(function(_) return Context.typeof(macro null));
-					var tF = ctA.applyTypeParameters(aT.params, monos);
-					if (t != null) {
-						switch(t.toType().follow()) {
-							case t = TAbstract(a2, tl2) if (a.toString() == a2.toString()): tF = t;
-							case _: Context.error("Explicit field type must be " + ctA.toString(), field.pos);
-						}
-					}
-					var tE = Context.typeof(e);
-					if (!Context.unify(tE, tThis)) Context.error('${tE.toString()} should be ${tThis.toString()}', e.pos);
-					field.meta.push({name: ":impl", params: [], pos: field.pos});
-					field.meta.push({name: ":enum", params: [], pos: field.pos});
-					field.kind = FVar(tF.toComplexType(), macro cast $e);
-				case _:
-			}
-		}
-		return fields;
-	}
-
-	macro static public function exposeUnderlyingFields(fieldExprs:Array<Expr>):Array<Field> {
-		var fields = Context.getBuildFields();
-		var a = switch(Context.getLocalClass().get().kind) {
-			case KAbstractImpl(a): a;
-			case _: throw "";
-		}
-		var tThis = a.get().type;
-		var map:Type->Type = function(t) return t;
-		var c = switch(tThis.follow()) {
-			case TInst(c, tl):
-				var c = c.get();
-				if (tl.length > 0) map = function(t) {
-					var t2 = t.applyTypeParameters(c.params, tl);
-					return t2;
-				}
-				c;
-			case _: Context.error("Underlying type of exposing abstract must be a class", Context.currentPos());
-		}
-		function getIdentNames(e) return switch(e.expr) {
-			case EConst(CIdent(s)): { field : s, newField : s };
-			case EBinop(OpArrow, { expr : EConst(CIdent(s1))}, { expr: EConst(CIdent(s2))}): { field: s1, newField : s2 };
-			case _: Context.error("Identifier or (Identifier => Identifier) expected", e.pos);
-		}
-		function toField(cf:ClassField, oldName:String, newName:String) {
-			return {
-				name: newName,
-				doc: cf.doc,
-				access: [AStatic, APublic, AInline],
-				pos: cf.pos,
-				meta: [{name: ":impl", params: [], pos: cf.pos}],
-				kind: switch(cf.type.follow()) {
-					case TFun(args, ret):
-						var args = args.map(function(arg) return {
-							name: arg.name,
-							opt: arg.opt,
-							type: arg.t.toComplexType(),
-							value: null
-						});
-						var expr = macro return this.$oldName($a{args.map(function(arg) return macro $i{arg.name})});
-						args.unshift({name: "this", type: null, opt:false, value: null});
-						FFun({
-							args: args,
-							ret: ret.toComplexType(),
-							expr: expr,
-							params: cf.params.map(function(param) return {
-								name: param.name,
-								constraints: [],
-								params: []
-							})
-						});
-					case _: throw "";
-				}
-			}
-		}
-		for (fieldExpr in fieldExprs) {
-			var fieldNames = getIdentNames(fieldExpr);
-			var fieldName = fieldNames.field;
-			var cField = c.findField(fieldName, false);
-			if (cField == null) Context.error('Underlying type has no field $fieldName', fieldExpr.pos);
-			switch(cField.kind) {
-				case FMethod(_):
-				case _: Context.error("Only function fields can be exposed", fieldExpr.pos);
-			}
-			cField.type = map(cField.type);
-			var field = toField(cField, fieldName, fieldNames.newField);
-			fields.push(field);
-		}
-		return fields;
-	}
-}

+ 31 - 0
std/haxe/macro/Context.hx

@@ -97,6 +97,22 @@ class Context {
 		return load("curpos", 0)();
 		return load("curpos", 0)();
 	}
 	}
 
 
+	/**
+		Returns the type which is expected at the place the macro is called.
+		
+		This affects usages such as `var x:Int = macroCall()`, where the
+		expected type will be reported as Int.
+		
+		Might return null if no specific type is expected or if the calling
+		macro is not an expression-macro.
+	**/
+	@:require(haxe_ver >= 3.01)
+	public static function getExpectedType():Null<Type> {
+		var l : Type = load("expected_type", 0)();
+		if( l == null ) return null;
+		return l;
+	}
+	
 	/**
 	/**
 		Returns the current class in which the macro was called.
 		Returns the current class in which the macro was called.
 		
 		
@@ -348,6 +364,21 @@ class Context {
 		return load("make_pos",3)(inf.min,inf.max,untyped inf.file.__s);
 		return load("make_pos",3)(inf.min,inf.max,untyped inf.file.__s);
 	}
 	}
 
 
+	/**
+		Returns a map of all registered resources for this compilation unit.
+
+		Modifying the returned map has no effect on the compilation, use
+		`haxe.macro.Context.addResource` to add new resources to the compilation unit.
+	**/
+	public static function getResources():haxe.ds.StringMap<haxe.io.Bytes> {
+		var x:haxe.ds.StringMap<neko.NativeString> = load("get_resources",0)();
+		var r = new haxe.ds.StringMap();
+		for (k in x.keys()) {
+			r.set(k, haxe.io.Bytes.ofData(x.get(k)));
+		} 
+		return r;
+	}
+
 	/**
 	/**
 		Makes resource `data` available as `name`.
 		Makes resource `data` available as `name`.
 		
 		

+ 1 - 0
std/haxe/macro/Expr.hx

@@ -132,6 +132,7 @@ enum Binop {
 		`|=`
 		`|=`
 		`&=`
 		`&=`
 		`^=`
 		`^=`
+		`%=`
 	**/
 	**/
 	OpAssignOp( op : Binop );
 	OpAssignOp( op : Binop );
 	/**
 	/**

+ 34 - 19
std/haxe/macro/Printer.hx

@@ -99,7 +99,7 @@ class Printer {
 		case TAnonymous(fields): "{ " + [for (f in fields) printField(f) + "; "].join("") + "}";
 		case TAnonymous(fields): "{ " + [for (f in fields) printField(f) + "; "].join("") + "}";
 		case TParent(ct): "(" + printComplexType(ct) + ")";
 		case TParent(ct): "(" + printComplexType(ct) + ")";
 		case TOptional(ct): "?" + printComplexType(ct);
 		case TOptional(ct): "?" + printComplexType(ct);
-		case TExtend(tpl, fields): '{${tpl.map(printTypePath).join(", ")} >, ${fields.map(printField).join(", ")} }';
+		case TExtend(tpl, fields): '{> ${tpl.map(printTypePath).join(" >, ")}, ${fields.map(printField).join(", ")} }';
 	}
 	}
 
 
 	public function printMetadata(meta:MetadataEntry) return
 	public function printMetadata(meta:MetadataEntry) return
@@ -118,7 +118,7 @@ class Printer {
 	
 	
 	public function printField(field:Field) return
 	public function printField(field:Field) return
 		(field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "")
 		(field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "")
-		+ (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join(" ") + " " : "")
+		+ (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join('\n$tabs') + '\n$tabs' : "")
 		+ (field.access != null && field.access.length > 0 ? field.access.map(printAccess).join(" ") + " " : "")
 		+ (field.access != null && field.access.length > 0 ? field.access.map(printAccess).join(" ") + " " : "")
 		+ switch(field.kind) {
 		+ switch(field.kind) {
 		  case FVar(t, eo): 'var ${field.name}' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = ");
 		  case FVar(t, eo): 'var ${field.name}' + opt(t, printComplexType, " : ") + opt(eo, printExpr, " = ");
@@ -134,18 +134,18 @@ class Printer {
 	public function printFunctionArg(arg:FunctionArg) return
 	public function printFunctionArg(arg:FunctionArg) return
 		(arg.opt ? "?" : "")
 		(arg.opt ? "?" : "")
 		+ arg.name
 		+ arg.name
-		+ opt(arg.type, printComplexType, " : ")
+		+ opt(arg.type, printComplexType, ":")
 		+ opt(arg.value, printExpr, " = ");
 		+ opt(arg.value, printExpr, " = ");
 
 
 	public function printFunction(func:Function) return
 	public function printFunction(func:Function) return
 		(func.params.length > 0 ? "<" + func.params.map(printTypeParamDecl).join(", ") + ">" : "")
 		(func.params.length > 0 ? "<" + func.params.map(printTypeParamDecl).join(", ") + ">" : "")
-		+ "( " + func.args.map(printFunctionArg).join(", ") + " )"
-		+ opt(func.ret, printComplexType, " : ")
+		+ "(" + func.args.map(printFunctionArg).join(", ") + ")"
+		+ opt(func.ret, printComplexType, ":")
 		+ opt(func.expr, printExpr, " ");
 		+ opt(func.expr, printExpr, " ");
 
 
 	public function printVar(v:Var) return
 	public function printVar(v:Var) return
 		v.name
 		v.name
-		+ opt(v.type, printComplexType, " : ")
+		+ opt(v.type, printComplexType, ":")
 		+ opt(v.expr, printExpr, " = ");
 		+ opt(v.expr, printExpr, " = ");
 
 
 
 
@@ -156,43 +156,44 @@ class Printer {
 		case EField(e1, n): '${printExpr(e1)}.$n';
 		case EField(e1, n): '${printExpr(e1)}.$n';
 		case EParenthesis(e1): '(${printExpr(e1)})';
 		case EParenthesis(e1): '(${printExpr(e1)})';
 		case EObjectDecl(fl):
 		case EObjectDecl(fl):
-			"{ " + fl.map(function(fld) return '${fld.field} : ${printExpr(fld.expr)} ').join(",") + "}";
+			"{ " + fl.map(function(fld) return '${fld.field} : ${printExpr(fld.expr)}').join(", ") + " }";
 		case EArrayDecl(el): '[${printExprs(el, ", ")}]';
 		case EArrayDecl(el): '[${printExprs(el, ", ")}]';
 		case ECall(e1, el): '${printExpr(e1)}(${printExprs(el,", ")})';
 		case ECall(e1, el): '${printExpr(e1)}(${printExprs(el,", ")})';
 		case ENew(tp, el): 'new ${printTypePath(tp)}(${printExprs(el,", ")})';
 		case ENew(tp, el): 'new ${printTypePath(tp)}(${printExprs(el,", ")})';
 		case EUnop(op, true, e1): printExpr(e1) + printUnop(op);
 		case EUnop(op, true, e1): printExpr(e1) + printUnop(op);
 		case EUnop(op, false, e1): printUnop(op) + printExpr(e1);
 		case EUnop(op, false, e1): printUnop(op) + printExpr(e1);
 		case EFunction(no, func) if (no != null): 'function $no' + printFunction(func);
 		case EFunction(no, func) if (no != null): 'function $no' + printFunction(func);
-		case EFunction(_, func): "function " +printFunction(func);
+		case EFunction(_, func): "function" +printFunction(func);
 		case EVars(vl): "var " +vl.map(printVar).join(", ");
 		case EVars(vl): "var " +vl.map(printVar).join(", ");
-		case EBlock([]): '{\n$tabs}';
+		case EBlock([]): '{ }';
 		case EBlock(el):
 		case EBlock(el):
 			var old = tabs;
 			var old = tabs;
 			tabs += tabString;
 			tabs += tabString;
 			var s = '{\n$tabs' + printExprs(el, ';\n$tabs');
 			var s = '{\n$tabs' + printExprs(el, ';\n$tabs');
 			tabs = old;
 			tabs = old;
 			s + ';\n$tabs}';
 			s + ';\n$tabs}';
-		case EFor(e1, e2): 'for(${printExpr(e1)}) ${printExpr(e2)}';
+		case EFor(e1, e2): 'for (${printExpr(e1)}) ${printExpr(e2)}';
 		case EIn(e1, e2): '${printExpr(e1)} in ${printExpr(e2)}';
 		case EIn(e1, e2): '${printExpr(e1)} in ${printExpr(e2)}';
-		case EIf(econd, eif, eelse): 'if(${printExpr(econd)}) ${printExpr(eif)} ${opt(eelse,printExpr,"else ")}';
-		case EWhile(econd, e1, true): 'while(${printExpr(econd)}) ${printExpr(e1)}';
-		case EWhile(econd, e1, false): 'do ${printExpr(e1)} while(${printExpr(econd)})';
+		case EIf(econd, eif, null): 'if (${printExpr(econd)}) ${printExpr(eif)}';
+		case EIf(econd, eif, eelse): 'if (${printExpr(econd)}) ${printExpr(eif)} else ${printExpr(eelse)}';
+		case EWhile(econd, e1, true): 'while (${printExpr(econd)}) ${printExpr(e1)}';
+		case EWhile(econd, e1, false): 'do ${printExpr(e1)} while (${printExpr(econd)})';
 		case ESwitch(e1, cl, edef):
 		case ESwitch(e1, cl, edef):
 			var old = tabs;
 			var old = tabs;
 			tabs += tabString;
 			tabs += tabString;
 			var s = 'switch ${printExpr(e1)} {\n$tabs' +
 			var s = 'switch ${printExpr(e1)} {\n$tabs' +
 				cl.map(function(c)
 				cl.map(function(c)
 					return 'case ${printExprs(c.values, ", ")}'
 					return 'case ${printExprs(c.values, ", ")}'
-						+ (c.guard != null ? ' if(${printExpr(c.guard)}): ' : ":")
+						+ (c.guard != null ? ' if (${printExpr(c.guard)}):' : ":")
 						+ (c.expr != null ? (opt(c.expr, printExpr)) + ";" : ""))
 						+ (c.expr != null ? (opt(c.expr, printExpr)) + ";" : ""))
 				.join('\n$tabs');
 				.join('\n$tabs');
 			if (edef != null)
 			if (edef != null)
-				s += '\n${tabs}default: ' + (edef.expr == null ? "" : printExpr(edef) + ";");
+				s += '\n${tabs}default:' + (edef.expr == null ? "" : printExpr(edef) + ";");
 			tabs = old;
 			tabs = old;
 			s + '\n$tabs}';
 			s + '\n$tabs}';
 		case ETry(e1, cl):
 		case ETry(e1, cl):
 			'try ${printExpr(e1)}'
 			'try ${printExpr(e1)}'
-			+ cl.map(function(c) return ' catch(${c.name} : ${printComplexType(c.type)}) ${printExpr(c.expr)}').join("");
+			+ cl.map(function(c) return ' catch(${c.name}:${printComplexType(c.type)}) ${printExpr(c.expr)}').join("");
 		case EReturn(eo): "return" + opt(eo, printExpr, " ");
 		case EReturn(eo): "return" + opt(eo, printExpr, " ");
 		case EBreak: "break";
 		case EBreak: "break";
 		case EContinue: "continue";
 		case EContinue: "continue";
@@ -211,6 +212,16 @@ class Printer {
 		return el.map(printExpr).join(sep);
 		return el.map(printExpr).join(sep);
 	}
 	}
 	
 	
+	function printExtension(tpl:Array<TypePath>, fields: Array<Field>) {
+		return '{\n$tabs>' + tpl.map(printTypePath).join(',\n$tabs>') + ","
+		    + (fields.length > 0 ? ('\n$tabs' + fields.map(printField).join(';\n$tabs') + ";\n}") : ("\n}"));
+	}
+	
+	function printStructure(fields:Array<Field>) {
+		return fields.length == 0 ? "{ }" :
+			'{\n$tabs' + fields.map(printField).join(';\n$tabs') + ";\n}";
+	}
+	
 	public function printTypeDefinition(t:TypeDefinition, printPackage = true):String {
 	public function printTypeDefinition(t:TypeDefinition, printPackage = true):String {
 		var old = tabs;
 		var old = tabs;
 		tabs = tabString;
 		tabs = tabString;
@@ -224,7 +235,7 @@ class Printer {
 						tabs + (field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "")
 						tabs + (field.doc != null && field.doc != "" ? "/**\n" + tabs + tabString + StringTools.replace(field.doc, "\n", "\n" + tabs + tabString) + "\n" + tabs + "**/\n" + tabs : "")
 						+ (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join(" ") + " " : "")
 						+ (field.meta != null && field.meta.length > 0 ? field.meta.map(printMetadata).join(" ") + " " : "")
 						+ (switch(field.kind) {
 						+ (switch(field.kind) {
-							case FVar(_, _): field.name;
+							case FVar(t, _): field.name + opt(t, printComplexType, ":");
 							case FProp(_, _, _, _): throw "FProp is invalid for TDEnum.";
 							case FProp(_, _, _, _): throw "FProp is invalid for TDEnum.";
 							case FFun(func): field.name + printFunction(func);
 							case FFun(func): field.name + printFunction(func);
 						}) + ";"
 						}) + ";"
@@ -252,12 +263,16 @@ class Printer {
 					+ "\n}";
 					+ "\n}";
 				case TDAlias(ct):
 				case TDAlias(ct):
 					"typedef " + t.name + (t.params.length > 0 ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + " = "
 					"typedef " + t.name + (t.params.length > 0 ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "") + " = "
-					+ printComplexType(ct)
+					+ (switch(ct) {
+						case TExtend(tpl, fields): printExtension(tpl, fields);
+						case TAnonymous(fields): printStructure(fields);
+						case _: printComplexType(ct);
+					})
 					+ ";";
 					+ ";";
 				case TDAbstract(tthis, from, to):
 				case TDAbstract(tthis, from, to):
 					"abstract " + t.name
 					"abstract " + t.name
-					+ (tthis == null ? "" : "(" + printComplexType(tthis) + ")")
 					+ (t.params.length > 0 ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "")
 					+ (t.params.length > 0 ? "<" + t.params.map(printTypeParamDecl).join(", ") + ">" : "")
+					+ (tthis == null ? "" : "(" + printComplexType(tthis) + ")")
 					+ (from == null ? "" : [for (f in from) " from " + printComplexType(f)].join(""))
 					+ (from == null ? "" : [for (f in from) " from " + printComplexType(f)].join(""))
 					+ (to == null ? "" : [for (t in to) " to " + printComplexType(t)].join(""))
 					+ (to == null ? "" : [for (t in to) " to " + printComplexType(t)].join(""))
 					+ " {\n"
 					+ " {\n"

+ 11 - 1
std/haxe/macro/Type.hx

@@ -40,7 +40,16 @@ enum Type {
 
 
 typedef AnonType = {
 typedef AnonType = {
 	var fields : Array<ClassField>;
 	var fields : Array<ClassField>;
-	//var status : AnonStatus;
+	var status : AnonStatus;
+}
+
+enum AnonStatus {
+	AClosed;
+	AOpened;
+	AConst;
+	AClassStatics( t : Ref<ClassType> );
+	AEnumStatics( t : Ref<EnumType> );
+	AAbstractStatics( t : Ref<AbstractType> );
 }
 }
 
 
 typedef TypeParameter = {
 typedef TypeParameter = {
@@ -82,6 +91,7 @@ enum ClassKind {
 	KGenericInstance(cl:Ref<ClassType>, params:Array<Type>);
 	KGenericInstance(cl:Ref<ClassType>, params:Array<Type>);
 	KMacroType;
 	KMacroType;
 	KAbstractImpl(a:Ref<AbstractType>);
 	KAbstractImpl(a:Ref<AbstractType>);
+	KGenericBuild;
 }
 }
 
 
 typedef ClassType = {> BaseType,
 typedef ClassType = {> BaseType,

+ 1 - 1
std/haxe/web/Dispatch.hx

@@ -309,7 +309,7 @@ class Dispatch {
 		case TAnonymous(a):
 		case TAnonymous(a):
 			for( f in a.get().fields ) {
 			for( f in a.get().fields ) {
 				var r = getType(f.type, f.pos);
 				var r = getType(f.type, f.pos);
-				var opt = false;
+				var opt = f.meta.has(":optional");
 				switch( f.type ) {
 				switch( f.type ) {
 				case TType(t, _):
 				case TType(t, _):
 					if( t.get().name == "Null" ) opt = true;
 					if( t.get().name == "Null" ) opt = true;

+ 20 - 8
std/java/_std/Array.hx

@@ -402,15 +402,9 @@ import java.NativeArray;
 		return ofNative(newarr);
 		return ofNative(newarr);
 	}
 	}
 
 
-	public function iterator() : Iterator<T>
+	public inline function iterator() : Iterator<T>
 	{
 	{
-		var i = 0;
-		var len = length;
-		return
-		{
-			hasNext:function() return i < len,
-			next:function() return __a[i++]
-		};
+		return new ArrayIterator<T>(this);
 	}
 	}
 
 
 	public function map<S>( f : T -> S ) : Array<S> {
 	public function map<S>( f : T -> S ) : Array<S> {
@@ -467,3 +461,21 @@ import java.NativeArray;
 		return __a[idx] = val;
 		return __a[idx] = val;
 	}
 	}
 }
 }
+
+@:final
+private class ArrayIterator<T>
+{
+	var arr:Array<T>;
+	var len:Int;
+	var i:Int;
+
+	public inline function new(a:Array<T>)
+	{
+		arr = a;
+		len = a.length;
+		i = 0;
+	}
+
+	public inline function hasNext():Bool return i < len;
+	public inline function next():T return arr[i++];
+}

+ 2 - 2
std/java/_std/Std.hx

@@ -240,8 +240,8 @@ import java.internal.Exceptions;
 		return 0.0;
 		return 0.0;
 	}
 	}
 
 
-	public static function instance<T>( v : { }, c : Class<T> ) : T {
-		return Std.is(v, c) ? cast v : null;
+	public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return Std.is(value, c) ? cast value : null;
 	}
 	}
 
 
 	public static function random( x : Int ) : Int {
 	public static function random( x : Int ) : Int {

+ 5 - 0
std/java/internal/StringExt.hx

@@ -169,6 +169,11 @@ private typedef NativeString = String;
 		return null;
 		return null;
 	}
 	}
 
 
+	public static function toString(me:NativeString):NativeString
+	{
+		return me;
+	}
+
 	@:functionCode('
 	@:functionCode('
 			return me.toLowerCase();
 			return me.toLowerCase();
 	')
 	')

+ 6 - 3
std/js/Boot.hx

@@ -68,7 +68,10 @@ class Boot {
 	}
 	}
 
 
 	static inline function getClass(o:Dynamic) : Dynamic {
 	static inline function getClass(o:Dynamic) : Dynamic {
-		return untyped __define_feature__("js.Boot.getClass", o.__class__);
+		if (Std.is(o, Array))
+			return Array;
+		else
+			return untyped __define_feature__("js.Boot.getClass", o.__class__);
 	}
 	}
 
 
 	@:ifFeature("has_enum")
 	@:ifFeature("has_enum")
@@ -171,6 +174,8 @@ class Boot {
 			return (untyped __js__("typeof"))(o) == "boolean";
 			return (untyped __js__("typeof"))(o) == "boolean";
 		case String:
 		case String:
 			return (untyped __js__("typeof"))(o) == "string";
 			return (untyped __js__("typeof"))(o) == "string";
+		case Array:
+			return (untyped __js__("(o instanceof Array)")) && o.__enum__ == null;
 		case Dynamic:
 		case Dynamic:
 			return true;
 			return true;
 		default:
 		default:
@@ -178,8 +183,6 @@ class Boot {
 				// Check if o is an instance of a Haxe class
 				// Check if o is an instance of a Haxe class
 				if( (untyped __js__("typeof"))(cl) == "function" ) {
 				if( (untyped __js__("typeof"))(cl) == "function" ) {
 					if( untyped __js__("o instanceof cl") ) {
 					if( untyped __js__("o instanceof cl") ) {
-						if( cl == Array )
-							return (o.__enum__ == null);
 						return true;
 						return true;
 					}
 					}
 					if( __interfLoop(getClass(o),cl) )
 					if( __interfLoop(getClass(o),cl) )

+ 9 - 0
std/js/Browser.hx

@@ -37,6 +37,15 @@ class Browser {
 	public static var navigator(get, never):js.html.Navigator;
 	public static var navigator(get, never):js.html.Navigator;
 	inline static function get_navigator() return untyped __js__("window.navigator");
 	inline static function get_navigator() return untyped __js__("window.navigator");
 	
 	
+	/**
+	 * True if a window object exists, false otherwise.
+	 *
+	 * This can be used to check if the code is being executed in a non-browser
+	 * environment such as node.js.
+	 */
+	public static var supported(get, never):Bool;
+	public static function get_supported() return untyped __js__("typeof window != \"undefined\"");
+	
 	/**
 	/**
 	 * Safely gets the browser's local storage, or returns null if localStorage is unsupported or
 	 * Safely gets the browser's local storage, or returns null if localStorage is unsupported or
 	 * disabled.
 	 * disabled.

+ 3 - 3
std/js/_std/Std.hx

@@ -28,8 +28,8 @@ import js.Boot;
 		return untyped js.Boot.__instanceof(v,t);
 		return untyped js.Boot.__instanceof(v,t);
 	}
 	}
 	
 	
-	public static inline function instance<T>( v : { }, c : Class<T> ) : T {
-		return untyped __instanceof__(v, c) ? cast v : null;
+	public static inline function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return untyped __instanceof__(value, c) ? cast value : null;
 	}
 	}
 
 
 	public static function string( s : Dynamic ) : String {
 	public static function string( s : Dynamic ) : String {
@@ -61,7 +61,7 @@ import js.Boot;
 	static function __init__() : Void untyped {
 	static function __init__() : Void untyped {
 		__feature__("js.Boot.getClass",String.prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["String"] = String,String));
 		__feature__("js.Boot.getClass",String.prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["String"] = String,String));
 		__feature__("js.Boot.isClass",String.__name__ = __feature__("Type.getClassName",["String"],true));
 		__feature__("js.Boot.isClass",String.__name__ = __feature__("Type.getClassName",["String"],true));
-		__feature__("js.Boot.getClass",Array.prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Array"] = Array,Array));
+		__feature__("Type.resolveClass",$hxClasses["Array"] = Array);
 		__feature__("js.Boot.isClass",Array.__name__ = __feature__("Type.getClassName",["Array"],true));
 		__feature__("js.Boot.isClass",Array.__name__ = __feature__("Type.getClassName",["Array"],true));
 		__feature__("Date.*", {
 		__feature__("Date.*", {
 			__feature__("js.Boot.getClass",__js__('Date').prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Date"] = __js__('Date'),__js__('Date')));
 			__feature__("js.Boot.getClass",__js__('Date').prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Date"] = __js__('Date'),__js__('Date')));

+ 47 - 0
std/js/_std/haxe/Json.hx

@@ -0,0 +1,47 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package haxe;
+
+@:coreApi
+#if (!haxeJSON && !old_browser)
+@:native("JSON") extern
+#end
+class Json {
+
+	#if haxeJSON inline #end
+	public static function parse( text : String ) : Dynamic {
+		return haxe.format.JsonParser.parse(text);
+	}
+
+	#if haxeJSON inline #end
+	public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic ) : String {
+		return haxe.format.JsonPrinter.print(value, replacer);
+	}
+
+	#if (!haxeJSON && old_browser)
+	static function __init__():Void untyped {
+		if( __js__('typeof(JSON)') != 'undefined' )
+			Json = __js__('JSON');
+	}
+	#end
+
+}

+ 3 - 3
std/js/_std/haxe/ds/ObjectMap.hx

@@ -43,7 +43,7 @@ class ObjectMap<K:{ }, V> implements Map.IMap<K,V> {
 	}
 	}
 	
 	
 	public function set(key:K, value:V):Void untyped {
 	public function set(key:K, value:V):Void untyped {
-		var id = key.__id__ != null ? key.__id__ : assignId(key);
+		var id : Int = untyped key.__id__ || assignId(key);
 		h[id] = value;
 		h[id] = value;
 		h.__keys__[id] = key;
 		h.__keys__[id] = key;
 	}
 	}
@@ -53,12 +53,12 @@ class ObjectMap<K:{ }, V> implements Map.IMap<K,V> {
 	}
 	}
 	
 	
 	public inline function exists(key:K):Bool {
 	public inline function exists(key:K):Bool {
-		return untyped h.hasOwnProperty(getId(key));
+		return untyped h.__keys__[getId(key)] != null;
 	}
 	}
 	
 	
 	public function remove( key : K ) : Bool {
 	public function remove( key : K ) : Bool {
 		var id = getId(key);
 		var id = getId(key);
-		if ( untyped !h.hasOwnProperty(id) ) return false;
+		if ( untyped h.__keys__[id] == null ) return false;
 		untyped  __js__("delete")(h[id]);
 		untyped  __js__("delete")(h[id]);
 		untyped  __js__("delete")(h.__keys__[id]);
 		untyped  __js__("delete")(h.__keys__[id]);
 		return true;
 		return true;

部分文件因为文件数量过多而无法显示