Просмотр исходного кода

change TField implementation to specify in which context the field is accessed

Nicolas Cannasse 12 лет назад
Родитель
Сommit
8d25f80906
16 измененных файлов с 325 добавлено и 242 удалено
  1. 9 3
      codegen.ml
  2. 16 3
      dce.ml
  3. 25 27
      genas3.ml
  4. 49 43
      gencpp.ml
  5. 17 8
      genjs.ml
  6. 4 4
      genneko.ml
  7. 55 53
      genphp.ml
  8. 1 0
      genswf8.ml
  9. 11 8
      genswf9.ml
  10. 2 1
      interp.ml
  11. 10 6
      matcher.ml
  12. 9 6
      optimizer.ml
  13. 35 2
      type.ml
  14. 4 4
      typecore.ml
  15. 6 7
      typeload.ml
  16. 72 67
      typer.ml

+ 9 - 3
codegen.ml

@@ -26,7 +26,7 @@ open Typecore
 (* TOOLS *)
 
 let field e name t p =
-	mk (TField (e,name)) t p
+	mk (TField (e,try quick_field e.etype name with Not_found -> assert false)) t p
 
 let fcall e name el ret p =
 	let ft = tfun (List.map (fun e -> e.etype) el) ret in
@@ -723,7 +723,7 @@ let add_field_inits ctx t =
 				match cf.cf_expr with
 				| None -> assert false
 				| Some e ->
-					let lhs = mk (TField(ethis,cf.cf_name)) cf.cf_type e.epos in
+					let lhs = mk (TField(ethis,FInstance (c,cf))) cf.cf_type e.epos in
 					cf.cf_expr <- None;
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
 					if Common.defined ctx.com Define.As3 then begin
@@ -1700,8 +1700,14 @@ let default_cast ?(vtmp="$t") com e texpr t p =
 	let vexpr = mk (TLocal vtmp) e.etype p in
 	let texpr = mk (TTypeExpr texpr) (mk_texpr texpr) p in
 	let std = (try List.find (fun t -> t_path t = ([],"Std")) com.types with Not_found -> assert false) in
+	let fis = (try
+			let c = (match std with TClassDecl c -> c | _ -> assert false) in
+			FStatic (c, PMap.find "is" c.cl_statics)
+		with Not_found ->
+			assert false
+	) in
 	let std = mk (TTypeExpr std) (mk_texpr std) p in
-	let is = mk (TField (std,"is")) (tfun [t_dynamic;t_dynamic] api.tbool) p in
+	let is = mk (TField (std,fis)) (tfun [t_dynamic;t_dynamic] api.tbool) p in
 	let is = mk (TCall (is,[vexpr;texpr])) api.tbool p in
 	let exc = mk (TThrow (mk (TConst (TString "Class cast error")) api.tstring p)) t p in
 	let check = mk (TIf (mk_parent is,mk (TCast (vexpr,None)) t p,Some exc)) t p in

+ 16 - 3
dce.ml

@@ -259,8 +259,8 @@ and expr dce e =
 		Common.add_feature dce.com ft;
 		expr dce e
 	(* keep toString method when the class is argument to Std.string or haxe.Log.trace *)
-	| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = (["haxe"],"Log")} as c))},"trace")} as ef, ([e2;_] as args))
-	| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = ([],"Std")} as c))},"string")} as ef, ([e2] as args)) ->
+	| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = (["haxe"],"Log")} as c))},FStatic (_,{cf_name="trace"}))} as ef, ([e2;_] as args))
+	| TCall ({eexpr = TField({eexpr = TTypeExpr (TClassDecl ({cl_path = ([],"Std")} as c))},FStatic (_,{cf_name="string"}))} as ef, ([e2] as args)) ->
 		mark_class dce c;
 		(match follow e2.etype with
 			| TInst(c,_) ->	field dce c "toString" false
@@ -270,8 +270,21 @@ and expr dce e =
 	| TCall ({eexpr = TConst TSuper} as e,el) ->
 		mark_t dce e.etype;
 		List.iter (expr dce) el;
-	| TClosure(e,n)
+	| TClosure(e,n) ->
+		(match follow e.etype with
+		| TInst(c,_) ->
+			mark_class dce c;
+			field dce c n false;
+		| TAnon a ->
+			(match !(a.a_status) with
+			| Statics c ->
+				mark_class dce c;
+				field dce c n true;
+			| _ -> ())
+		| _ -> ());
+		expr dce e;
 	| TField(e,n) ->
+		let n = field_name n in
 		(match follow e.etype with
 		| TInst(c,_) ->
 			mark_class dce c;

+ 25 - 27
genas3.ml

@@ -41,15 +41,12 @@ type context = {
 	mutable block_inits : (unit -> unit) option;
 }
 
-let is_var_field e v =
-	match e.eexpr, follow e.etype with
-	| TTypeExpr (TClassDecl c),_
-	| _,TInst(c,_) ->
-		(try
-			let f = try PMap.find v c.cl_fields	with Not_found -> PMap.find v c.cl_statics in
-			(match f.cf_kind with Var _ -> true | _ -> false)
-		with Not_found -> false)
-	| _ -> false
+let is_var_field f =
+	match f with
+	| FStatic (_,f) | FInstance (_,f) ->
+		(match f.cf_kind with Var _ -> true | _ -> false)
+	| _ ->
+		false
 
 let is_special_compare e1 e2 =
 	match e1.eexpr, e2.eexpr with
@@ -461,19 +458,12 @@ let rec gen_call ctx e el r =
 		spr ctx "(";
 		gen_value ctx e;
 		spr ctx ")"
-	| TField ({ eexpr = TTypeExpr (TClassDecl { cl_path = (["flash"],"Lib") }) },f), args ->
-		(match f, args with
-		| "as", [e1;e2] ->
-			gen_value ctx e1;
-			spr ctx " as ";
-			gen_value ctx e2
-		| _ ->
-			gen_value ctx e;
-			spr ctx "(";
-			concat ctx "," (gen_value ctx) el;
-			spr ctx ")")
-	| TField ({ eexpr = TTypeExpr (TClassDecl { cl_path = (["flash"],"Vector") }) },f), args ->
-		(match f, args with
+	| TField (_, FStatic( { cl_path = (["flash"],"Lib") }, { cf_name = "as" })), [e1;e2] ->
+		gen_value ctx e1;
+		spr ctx " as ";
+		gen_value ctx e2
+	| TField (_, FStatic ({ cl_path = (["flash"],"Vector") }, cf)), args ->
+		(match cf.cf_name, args with
 		| "ofArray", [e] | "convert", [e] ->
 			(match follow r with
 			| TInst ({ cl_path = (["flash"],"Vector") },[t]) ->
@@ -482,7 +472,7 @@ let rec gen_call ctx e el r =
 				print ctx ")";
 			| _ -> assert false)
 		| _ -> assert false)
-	| TField(ee,v),args when is_var_field ee v ->
+	| TField (ee,f), args when is_var_field f ->
 		spr ctx "(";
 		gen_value ctx e;
 		spr ctx ")";
@@ -555,7 +545,7 @@ and gen_expr ctx e =
 		spr ctx "]";
 	| TBinop (Ast.OpEq,e1,e2) when (match is_special_compare e1 e2 with Some c -> true | None -> false) ->
 		let c = match is_special_compare e1 e2 with Some c -> c | None -> assert false in
-		gen_expr ctx (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic e.epos,"compare")) t_dynamic e.epos,[e1;e2])) ctx.inf.com.basic.tbool e.epos);
+		gen_expr ctx (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic e.epos,FDynamic "compare")) t_dynamic e.epos,[e1;e2])) ctx.inf.com.basic.tbool e.epos);
 	(* what is this used for? *)
 (* 	| TBinop (op,{ eexpr = TField (e1,s) },e2) ->
 		gen_value_op ctx e1;
@@ -567,19 +557,27 @@ and gen_expr ctx e =
 		print ctx " %s " (Ast.s_binop op);
 		gen_value_op ctx e2;
 	(* variable fields on interfaces are generated as (class["field"] as class) *)
-	| TField ({etype = TInst({cl_interface = true} as c,_)} as e,s)
+	| TField ({etype = TInst({cl_interface = true} as c,_)} as e,FInstance (_,{ cf_name = s }))
 	| TClosure ({etype = TInst({cl_interface = true} as c,_)} as e,s)
 		when (try (match (PMap.find s c.cl_fields).cf_kind with Var _ -> true | _ -> false) with Not_found -> false) ->
 		spr ctx "(";
 		gen_value ctx e;
 		print ctx "[\"%s\"]" s;
 		print ctx " as %s)" (type_str ctx e.etype e.epos);
-	| TField({eexpr = TArrayDecl _} as e1,s) | TClosure({eexpr = TArrayDecl _} as e1,s) ->
+	| TField({eexpr = TArrayDecl _} as e1,s) ->
+		spr ctx "(";
+		gen_expr ctx e1;
+		spr ctx ")";
+		gen_field_access ctx e1.etype (field_name s)
+	| TClosure({eexpr = TArrayDecl _} as e1,s) ->
 		spr ctx "(";
 		gen_expr ctx e1;
 		spr ctx ")";
 		gen_field_access ctx e1.etype s
-	| TField (e,s) | TClosure (e,s) ->
+	| TField (e,s) ->
+   		gen_value ctx e;
+		gen_field_access ctx e.etype (field_name s)
+	| TClosure (e,s) ->
    		gen_value ctx e;
 		gen_field_access ctx e.etype s
 	| TTypeExpr t ->

+ 49 - 43
gencpp.ml

@@ -870,7 +870,9 @@ let rec is_dynamic_in_cpp ctx expr =
 	else begin
 		let result = (
 		match expr.eexpr with
-		| TField( obj, name ) -> ctx.ctx_dbgout ("/* ?tfield "^name^" */");
+		| TField( obj, field ) ->
+			let name = field_name field in
+			ctx.ctx_dbgout ("/* ?tfield "^name^" */");
 				if (is_dynamic_member_lookup_in_cpp ctx obj name) then
             (
                ctx.ctx_dbgout "/* tf=dynobj */";
@@ -1308,6 +1310,48 @@ and gen_expression ctx retval expression =
 		| _ ->  gen_bin_op_string expr1 (Ast.s_binop op) expr2
 		in
 
+	let rec gen_field field_object member =
+		let remap_name = keyword_remap member in
+		let already_dynamic = ref false in
+		(match field_object.eexpr with
+		(* static access ... *)
+		| TTypeExpr type_def ->
+			let class_name = "::" ^ (join_class_path (t_path type_def) "::" ) in
+			if (class_name="::String") then
+				output ("::String::" ^ remap_name)
+			else
+				output (class_name ^ "_obj::" ^ remap_name);
+		(* Special internal access *)
+		| TLocal { v_name = "__global__" } ->
+			output ("::" ^ member )
+		| TConst TSuper -> output (if ctx.ctx_real_this_ptr then "this" else "__this");
+						output ("->super::" ^ remap_name)
+		| TConst TThis when ctx.ctx_real_this_ptr -> output ( "this->" ^ remap_name )
+		| TConst TNull -> output "null()"
+		| _ ->
+			gen_expression ctx true field_object;
+         ctx.ctx_dbgout "/* TField */";
+         if (is_internal_member member) then begin
+				output ( "->" ^ member );
+         end else if (is_dynamic_member_lookup_in_cpp ctx field_object member) then begin
+            if assigning then
+				    output ( "->__FieldRef(" ^ (str member) ^ ")" )
+            else
+				    output ( "->__Field(" ^ (str member) ^ ",true)" );
+            already_dynamic := true;
+         end else begin
+            if ((type_string field_object.etype)="::String" ) then
+				   output ( "." ^ remap_name )
+            else begin
+               cast_if_required ctx field_object (type_string field_object.etype);
+				   output ( "->" ^ remap_name )
+            end;
+         end;
+      );
+		if ( (not !already_dynamic) && (not calling) && (not assigning) && (is_function_member expression) ) then
+         output "_dyn()";
+	in
+
 	(match expression.eexpr with
 	| TConst TNull when not retval ->
 		output "Dynamic()";
@@ -1444,48 +1488,10 @@ and gen_expression ctx retval expression =
 	| TBinop (op,expr1,expr2) -> gen_bin_op op expr1 expr2
 	| TField (expr,name) when (is_null expr) -> output "Dynamic()"
 
-	| TClosure (field_object,member)
-	| TField (field_object,member) ->
-		let remap_name = keyword_remap member in
-		let already_dynamic = ref false in
-		(match field_object.eexpr with
-		(* static access ... *)
-		| TTypeExpr type_def ->
-			let class_name = "::" ^ (join_class_path (t_path type_def) "::" ) in
-			if (class_name="::String") then
-				output ("::String::" ^ remap_name)
-			else
-				output (class_name ^ "_obj::" ^ remap_name);
-		(* Special internal access *)
-		| TLocal { v_name = "__global__" } ->
-			output ("::" ^ member )
-		| TConst TSuper -> output (if ctx.ctx_real_this_ptr then "this" else "__this");
-						output ("->super::" ^ remap_name)
-		| TConst TThis when ctx.ctx_real_this_ptr -> output ( "this->" ^ remap_name )
-		| TConst TNull -> output "null()"
-		| _ ->
-			gen_expression ctx true field_object;
-         ctx.ctx_dbgout "/* TField */";
-         if (is_internal_member member) then begin
-				output ( "->" ^ member );
-         end else if (is_dynamic_member_lookup_in_cpp ctx field_object member) then begin
-            if assigning then
-				    output ( "->__FieldRef(" ^ (str member) ^ ")" )
-            else
-				    output ( "->__Field(" ^ (str member) ^ ",true)" );
-            already_dynamic := true;
-         end else begin
-            if ((type_string field_object.etype)="::String" ) then
-				   output ( "." ^ remap_name )
-            else begin
-               cast_if_required ctx field_object (type_string field_object.etype);
-				   output ( "->" ^ remap_name )
-            end;
-         end;
-      );
-		if ( (not !already_dynamic) && (not calling) && (not assigning) && (is_function_member expression) ) then
-         output "_dyn()";
-
+	| TClosure (field_object,member) ->
+		gen_field field_object member
+	| TField (field_object,field) ->
+		gen_field field_object (field_name field)
 
 	| TParenthesis expr when not retval ->
 			gen_expression ctx retval expr;

+ 17 - 8
genjs.ml

@@ -303,9 +303,12 @@ let handle_expose ctx path meta =
 let this ctx = match ctx.in_value with None -> "this" | Some _ -> "$this"
 
 let is_dynamic_iterator ctx e =
-	match e.eexpr with
-	| TClosure (x,"iterator") | TField (x,"iterator") ->
+	let check x =
 		has_feature ctx "HxOverrides.iter" && (match follow x.etype with TInst ({ cl_path = [],"Array" },_) | TAnon _ | TDynamic _ | TMono _ -> true | _ -> false)
+	in
+	match e.eexpr with
+	| TClosure (x,"iterator") -> check x
+	| TField (x,f) when field_name f = "iterator" -> check x
 	| _ ->
 		false
 
@@ -330,10 +333,11 @@ let rec gen_call ctx e el in_value =
 			List.iter (fun p -> print ctx ","; gen_value ctx p) params;
 			spr ctx ")";
 		);
-	| TField ({ eexpr = TConst TSuper },name) , params ->
+	| TField ({ eexpr = TConst TSuper },f) , params ->
 		(match ctx.current.cl_super with
 		| None -> error "Missing api.setCurrentClass" e.epos
 		| Some (c,_) ->
+			let name = field_name f in
 			print ctx "%s.prototype%s.call(%s" (ctx.type_accessor (TClassDecl c)) (field name) (this ctx);
 			List.iter (fun p -> print ctx ","; gen_value ctx p) params;
 			spr ctx ")";
@@ -411,7 +415,7 @@ and gen_expr ctx e =
 		spr ctx "[";
 		gen_value ctx e2;
 		spr ctx "]";
-	| TBinop (op,{ eexpr = TField (x,"iterator") },e2) ->
+	| TBinop (op,{ eexpr = TField (x,f) },e2) when field_name f = "iterator" ->
 		gen_value ctx x;
 		spr ctx (field "iterator");
 		print ctx " %s " (Ast.s_binop op);
@@ -420,15 +424,20 @@ and gen_expr ctx e =
 		gen_value ctx e1;
 		print ctx " %s " (Ast.s_binop op);
 		gen_value ctx e2;
-	| TClosure (x,"iterator")
-	| TField (x,"iterator") when is_dynamic_iterator ctx e ->
+	| TClosure (x,"iterator") ->
+		add_feature ctx "use.$iterator";
+		print ctx "$iterator(";
+		gen_value ctx x;
+		print ctx ")";
+	| TField (x,f) when field_name f = "iterator" && is_dynamic_iterator ctx e ->
 		add_feature ctx "use.$iterator";
 		print ctx "$iterator(";
 		gen_value ctx x;
 		print ctx ")";
-	| TField (x,s) ->
+	| TField (x,f) ->
 		gen_value ctx x;
-		spr ctx (match follow x.etype with TAnon { a_status = { contents = (Statics _ | EnumStatics _) } } -> static_field s | _ -> field s)
+		let name = field_name f in
+		spr ctx (match f with FStatic _ -> static_field name | FInstance _ | FAnon _ | FDynamic _ -> field name)
 	| TClosure ({ eexpr = TTypeExpr _ } as x,s) ->
 		gen_value ctx x;
 		spr ctx (static_field s)

+ 4 - 4
genneko.ml

@@ -198,7 +198,7 @@ and gen_call ctx p e el =
 	| TField ({ eexpr = TConst TSuper; etype = t },f) , _ ->
 		let c = (match follow t with TInst (c,_) -> c | _ -> assert false) in
 		call p (builtin p "call") [
-			field p (gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path)) f;
+			field p (gen_type_path p (fst c.cl_path,"@" ^ snd c.cl_path)) (field_name f);
 			this p;
 			array p (List.map (gen_expr ctx) el)
 		]
@@ -223,11 +223,11 @@ and gen_expr ctx e =
 	| TArray (e1,e2) ->
 		(EArray (gen_expr ctx e1,gen_expr ctx e2),p)
 	| TBinop (OpAssign,{ eexpr = TField (e1,f) },e2) ->
-		(EBinop ("=",field p (gen_expr ctx e1) f,gen_expr ctx e2),p)
+		(EBinop ("=",field p (gen_expr ctx e1) (field_name f),gen_expr ctx e2),p)
 	| TBinop (op,e1,e2) ->
 		gen_binop ctx p op e1 e2
 	| TField (e,f) ->
-		field p (gen_expr ctx e) f
+		field p (gen_expr ctx e) (field_name f)
 	| TClosure (({ eexpr = TTypeExpr _ } as e),f) ->
 		field p (gen_expr ctx e) f
 	| TClosure (e2,f) ->
@@ -454,7 +454,7 @@ let gen_method ctx p c acc =
 		((c.cf_name, null p) :: acc)
 	| Some e ->
 		match e.eexpr with
-		| TCall ({ eexpr = TField ({ eexpr = TTypeExpr (TClassDecl { cl_path = (["neko"],"Lib") }) }, load)},[{ eexpr = TConst (TString m) };{ eexpr = TConst (TString f) };{ eexpr = TConst (TInt n) }]) when load = "load" || load = "loadLazy" ->
+		| TCall ({ eexpr = TField (_,FStatic ({cl_path=["neko"],"Lib"},{cf_name="load" | "loadLazy" as load})) },[{ eexpr = TConst (TString m) };{ eexpr = TConst (TString f) };{ eexpr = TConst (TInt n) }]) ->
 			let p = pos ctx e.epos in
 			let e = call p (EField (builtin p "loader","loadprim"),p) [(EBinop ("+",(EBinop ("+",str p m,str p "@"),p),str p f),p); (EConst (Int (Int32.to_int n)),p)] in
 			let e = (if load = "load" then e else (ETry (e,"@e",call p (ident p "@lazy_error") [ident p "@e"]),p)) in

+ 55 - 53
genphp.ml

@@ -512,11 +512,11 @@ and gen_call ctx e el =
 			concat ctx "," (gen_value ctx) params;
 			spr ctx ")";
 		);
-	| TField ({ eexpr = TConst TSuper },name) , params ->
+	| TField ({ eexpr = TConst TSuper },f) , params ->
 		(match ctx.curclass.cl_super with
 		| None -> assert false
 		| Some (c,_) ->
-			print ctx "parent::%s(" (s_ident name);
+			print ctx "parent::%s(" (s_ident (field_name f));
 			concat ctx "," (gen_value ctx) params;
 			spr ctx ")";
 		);
@@ -719,7 +719,7 @@ and gen_field_op ctx e =
 	| TField (f,s) ->
 		(match follow e.etype with
 		| TFun _ ->
-			gen_field_access ctx true f s
+			gen_field_access ctx true f (field_name s)
 		| _ ->
 			gen_value_op ctx e)
 	| _ ->
@@ -910,6 +910,45 @@ and gen_while_expr ctx e =
 	ctx.nested_loops <- old_nested_loops;
 	ctx.in_loop <- old_loop
 
+and gen_tfield ctx e e1 s =
+	match follow e.etype with
+	| TFun (args, _) ->
+		(if ctx.is_call then begin
+			gen_field_access ctx false e1 s
+	  	end else if is_in_dynamic_methods ctx e1 s then begin
+	  		gen_field_access ctx true e1 s;
+	  	end else begin
+			let ob ex =
+				(match ex with
+				| TTypeExpr t ->
+					print ctx "\"";
+					spr ctx (s_path ctx (t_path t) false e1.epos);
+					print ctx "\""
+				| _ ->
+					gen_expr ctx e1) in
+
+			spr ctx "(isset(";
+			gen_field_access ctx true e1 s;
+			spr ctx ") ? ";
+			gen_field_access ctx true e1 s;
+			spr ctx ": array(";
+			ob e1.eexpr;
+			print ctx ", \"%s\"))" (s_ident s);
+
+		end)
+	| TMono _ ->
+		if ctx.is_call then
+			gen_field_access ctx false e1 s
+		else
+			gen_uncertain_string_var ctx s e1
+	| _ ->
+		if is_string_expr e1 then
+			gen_string_var ctx s e1
+		else if is_uncertain_expr e1 then
+			gen_uncertain_string_var ctx s e1
+		else
+			gen_field_access ctx true e1 s
+
 and gen_expr ctx e =
 	let in_block = ctx.in_block in
 	ctx.in_block <- false;
@@ -974,13 +1013,13 @@ and gen_expr ctx e =
 				gen_value ctx te2;
 				spr ctx "]";
 			| TField (e1,s) ->
-				gen_field_access ctx true e1 s
+				gen_field_access ctx true e1 (field_name s)
 			| _ ->
 				gen_field_op ctx e1;) in
 		let leftsidef e =
 			(match e.eexpr with
 			| TField (e1,s) ->
-				gen_field_access ctx true e1 s;
+				gen_field_access ctx true e1 (field_name s)
 			| _ ->
 				gen_field_op ctx e1;
 				) in
@@ -1087,7 +1126,7 @@ and gen_expr ctx e =
 				| TField (f, s) when is_anonym_expr e1 || is_unknown_expr e1 ->
 					spr ctx "_hx_field(";
 					gen_value ctx f;
-					print ctx ", \"%s\")" s;
+					print ctx ", \"%s\")" (field_name s);
 				| _ ->
 					gen_field_op ctx e1;
 				);
@@ -1097,7 +1136,7 @@ and gen_expr ctx e =
 				| TField (f, s) when is_anonym_expr e2 || is_unknown_expr e2 ->
 					spr ctx "_hx_field(";
 					gen_value ctx f;
-					print ctx ", \"%s\")" s;
+					print ctx ", \"%s\")" (field_name s);
 				| _ ->
 					gen_field_op ctx e2);
 			end else if
@@ -1148,47 +1187,10 @@ and gen_expr ctx e =
 			print ctx " %s " (Ast.s_binop op);
 			gen_value_op ctx e2;
 		));
-	| TField (e1,s)
+	| TField (e1,s) ->
+		gen_tfield ctx e e1 (field_name s)
 	| TClosure (e1,s) ->
-		(match follow e.etype with
-		| TFun (args, _) ->
-			(if ctx.is_call then begin
-				gen_field_access ctx false e1 s
-	  		end else if is_in_dynamic_methods ctx e1 s then begin
-	  			gen_field_access ctx true e1 s;
-	  		end else begin
-				let ob ex =
-					(match ex with
-					| TTypeExpr t ->
-						print ctx "\"";
-						spr ctx (s_path ctx (t_path t) false e1.epos);
-						print ctx "\""
-					| _ ->
-						gen_expr ctx e1) in
-
-				spr ctx "(isset(";
-				gen_field_access ctx true e1 s;
-				spr ctx ") ? ";
-				gen_field_access ctx true e1 s;
-				spr ctx ": array(";
-				ob e1.eexpr;
-				print ctx ", \"%s\"))" (s_ident s);
-
-			end)
-		| TMono _ ->
-			if ctx.is_call then
-				gen_field_access ctx false e1 s
-			else
-				gen_uncertain_string_var ctx s e1
-		| _ ->
-			if is_string_expr e1 then
-				gen_string_var ctx s e1
-			else if is_uncertain_expr e1 then
-				gen_uncertain_string_var ctx s e1
-			else
-				gen_field_access ctx true e1 s
-		)
-
+		gen_tfield ctx e e1 s
 	| TTypeExpr t ->
 		print ctx "_hx_qtype(\"%s\")" (s_path_haxe (t_path t))
 	| TParenthesis e ->
@@ -1319,11 +1321,11 @@ and gen_expr ctx e =
 			concat ctx ", " (gen_value ctx) el;
 			spr ctx "))";
 		| TField (ef,s) when is_static ef.etype && is_string_expr ef ->
-			gen_string_static_call ctx s ef el
+			gen_string_static_call ctx (field_name s) ef el
 		| TField (ef,s) when is_string_expr ef ->
-			gen_string_call ctx s ef el
-		| TField (ef,s) when is_anonym_expr ef && could_be_string_call s ->
-			gen_uncertain_string_call ctx s ef el
+			gen_string_call ctx (field_name s) ef el
+		| TField (ef,s) when is_anonym_expr ef && could_be_string_call (field_name s) ->
+			gen_uncertain_string_call ctx (field_name s) ef el
 		| _ ->
 			gen_call ctx ec el);
 	| TArrayDecl el ->
@@ -1418,7 +1420,7 @@ and gen_expr ctx e =
 			);
 		| TField (e1,s) ->
 			spr ctx (Ast.s_unop op);
-			gen_field_access ctx true e1 s
+			gen_field_access ctx true e1 (field_name s)
 		| _ ->
 			spr ctx (Ast.s_unop op);
 			gen_value ctx e)
@@ -1430,7 +1432,7 @@ and gen_expr ctx e =
 			gen_value ctx te2;
 			spr ctx "]";
 		| TField (e1,s) ->
-			gen_field_access ctx true e1 s
+			gen_field_access ctx true e1 (field_name s)
 		| _ ->
 			gen_value ctx e);
 		spr ctx (Ast.s_unop op)

+ 1 - 0
genswf8.ml

@@ -582,6 +582,7 @@ let rec gen_access ?(read_write=false) ctx forcall e =
 	| TField (e2,f) ->
 		gen_expr ctx true e2;
 		if read_write then write ctx ADup;
+		let f = field_name f in
 		let p = VStr (f,is_protected ctx e2.etype f) in
 		push ctx [p];
 		if read_write then begin

+ 11 - 8
genswf9.ml

@@ -841,11 +841,13 @@ let pop_value ctx retval =
 let gen_expr_ref = ref (fun _ _ _ -> assert false)
 let gen_expr ctx e retval = (!gen_expr_ref) ctx e retval
 
-let gen_access ctx e (forset : 'a) : 'a access =
+let rec gen_access ctx e (forset : 'a) : 'a access =
 	match e.eexpr with
 	| TLocal v ->
 		gen_local_access ctx v e.epos forset
-	| TField (e1,f) | TClosure (e1,f) ->
+	| TField (e1,f) ->
+		gen_access ctx { e with eexpr = TClosure (e1,field_name f) } forset
+	| TClosure (e1,f) ->
 		let id, k, closure = property ctx f e1.etype in
 		if closure && not ctx.for_call then error "In Flash9, this method cannot be accessed this way : please define a local function" e1.epos;
 		(match e1.eexpr with
@@ -1478,13 +1480,13 @@ and gen_call ctx retval e el r =
 		List.iter (gen_expr ctx true) el;
 		write ctx (HConstructSuper (List.length el));
 	| TField ({ eexpr = TConst TSuper },f) , _ ->
-		let id = ident f in
+		let id = ident (field_name f) in
 		write ctx (HFindPropStrict id);
 		List.iter (gen_expr ctx true) el;
 		write ctx (HCallSuper (id,List.length el));
 		coerce ctx (classify ctx r);
 	| TField ({ eexpr = TConst TThis },f) , _ when not ctx.in_static ->
-		let id = ident f in
+		let id = ident (field_name f) in
 		write ctx (HFindProp id);
 		List.iter (gen_expr ctx true) el;
 		if retval then begin
@@ -1498,7 +1500,7 @@ and gen_call ctx retval e el r =
 		gen_expr ctx true e1;
 		ctx.for_call <- old;
 		List.iter (gen_expr ctx true) el;
-		let id , _, _ = property ctx f e1.etype in
+		let id , _, _ = property ctx (field_name f) e1.etype in
 		if retval then begin
 			write ctx (HCallProperty (id,List.length el));
 			coerce ctx (classify ctx r);
@@ -1613,7 +1615,8 @@ and gen_binop ctx retval op e1 e2 t p =
 		| None ->
 			gen_op A3OEq
 		| Some c ->
-			gen_expr ctx true (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic p,"compare")) t_dynamic p,[e1;e2])) ctx.com.basic.tbool p);
+			let f = FStatic (c,try PMap.find "compare" c.cl_statics with Not_found -> assert false) in
+			gen_expr ctx true (mk (TCall (mk (TField (mk (TTypeExpr (TClassDecl c)) t_dynamic p,f)) t_dynamic p,[e1;e2])) ctx.com.basic.tbool p);
 	in
 	match op with
 	| OpAssign ->
@@ -2073,7 +2076,7 @@ let generate_class ctx c =
 						end_fun ctx [] None f.cf_type
 					else
 						let fk = begin_fun ctx [] f.cf_type [ethis] false p in
-						gen_expr ctx false (mk (TReturn (Some (mk (TCall (mk (TField (ethis,n)) t_dynamic p,[])) f.cf_type p))) t_dynamic p);
+						gen_expr ctx false (mk (TReturn (Some (mk (TCall (mk (TField (ethis,FDynamic n)) t_dynamic p,[])) f.cf_type p))) t_dynamic p);
 						fk()
 					in
 					{
@@ -2098,7 +2101,7 @@ let generate_class ctx c =
 						end_fun ctx [v,None] None f.cf_type
 					else
 						let fk = begin_fun ctx [v,None] f.cf_type [ethis] false p in
-						gen_expr ctx false (mk (TReturn (Some (mk (TCall (mk (TField (ethis,n)) t_dynamic p,[mk (TLocal v) v.v_type p])) f.cf_type p))) t_dynamic p);
+						gen_expr ctx false (mk (TReturn (Some (mk (TCall (mk (TField (ethis,FDynamic n)) t_dynamic p,[mk (TLocal v) v.v_type p])) f.cf_type p))) t_dynamic p);
 						fk()
 					in
 					{

+ 2 - 1
interp.ml

@@ -4360,7 +4360,8 @@ let rec make_ast e =
 	| TEnumField (en,f) -> EField (mk_path en.e_path e.epos,f)
 	| TArray (e1,e2) -> EArray (make_ast e1,make_ast e2)
 	| TBinop (op,e1,e2) -> EBinop (op, make_ast e1, make_ast e2)
-	| TField (e,f) | TClosure (e,f) -> EField (make_ast e, f)
+	| TField (e,f) -> EField (make_ast e, Type.field_name f)
+	| TClosure (e,f) -> EField (make_ast e, f)
 	| TTypeExpr t -> fst (mk_path (t_path t) e.epos)
 	| TParenthesis e -> EParenthesis (make_ast e)
 	| TObjectDecl fl -> EObjectDecl (List.map (fun (f,e) -> f, make_ast e) fl)

+ 10 - 6
matcher.ml

@@ -164,7 +164,7 @@ let s_type = s_type (print_context())
 
 let rec s_expr_small e = match e.eexpr with
 	| TLocal v -> v.v_name
-	| TField (e,s) -> s_expr_small e ^ "." ^ s
+	| TField (e,s) -> s_expr_small e ^ "." ^ field_name s
 	| TBlock [] -> "{}"
 	| _ -> s_expr (s_type) e
 
@@ -338,8 +338,12 @@ let to_pattern mctx e st =
 						e
 				in
 				(match ec.eexpr with
-					| TEnumField(en,s)
-					| TField ({ eexpr = TTypeExpr (TEnumDecl en) },s) ->
+					| TEnumField(en,s) ->
+						let ef = PMap.find s en.e_constrs in
+						unify_enum_field en (List.map (fun _ -> mk_mono()) en.e_types) ef tc;
+						mk_con_pat (CEnum(en,ef)) [] st.st_type p
+					| TField ({ eexpr = TTypeExpr (TEnumDecl en) },f) ->
+						let s = field_name f in
 						let ef = PMap.find s en.e_constrs in
 						unify_enum_field en (List.map (fun _ -> mk_mono()) en.e_types) ef tc;
 						mk_con_pat (CEnum(en,ef)) [] st.st_type p
@@ -697,7 +701,7 @@ let rec st_to_unique_name ctx st = match st.st_def with
 
 let rec st_to_texpr mctx st = match st.st_def with
 	| SVar v -> mk (TLocal v) v.v_type st.st_pos
-	| SField (sts,f) -> mk (TField(st_to_texpr mctx sts,f)) st.st_type st.st_pos
+	| SField (sts,f) -> mk (TField(st_to_texpr mctx sts,FDynamic f)) st.st_type st.st_pos
 	| SArray (sts,i) -> mk (TArray(st_to_texpr mctx sts,mk_const mctx.ctx st.st_pos (TInt (Int32.of_int i)))) st.st_type st.st_pos
 	| STuple (st,_,_) -> st_to_texpr mctx st
 	| SEnum _ ->
@@ -829,7 +833,7 @@ and to_array_switch mctx need_val t st cases =
 			error ("Unexpected "  ^ (s_con con)) con.c_pos
 	in
 	let cases = loop [] cases in
-	let eval = mk (TField(st_to_texpr mctx st,"length")) mctx.ctx.com.basic.tint st.st_pos in
+	let eval = mk (TField(st_to_texpr mctx st,FDynamic "length")) mctx.ctx.com.basic.tint st.st_pos in
 	let t = if not need_val then (mk_mono()) else unify_min mctx.ctx !el in
 	mk (TSwitch(eval,cases,!def)) t eval.epos
 
@@ -868,7 +872,7 @@ let match_expr ctx e cases def need_val with_type p =
 	let stl = ExtList.List.mapi (fun i e ->
 		let rec loop e = match e.eexpr with
 			| TField (ef,s) ->
-				mk_st (SField(loop ef,s)) e.etype e.epos
+				mk_st (SField(loop ef,field_name s)) e.etype e.epos
 			| TParenthesis e ->
 				loop e
 			| TLocal v ->

+ 9 - 6
optimizer.ml

@@ -399,6 +399,9 @@ let optimize_for_loop ctx i e1 e2 p =
 	let t_void = ctx.t.tvoid in
 	let t_int = ctx.t.tint in
 	let lblock el = Some (mk (TBlock el) t_void p) in
+	let mk_field e n =
+		TField (e,try quick_field e.etype n with Not_found -> assert false)
+	in
 	let gen_int_iter pt =
 		let i = add_local ctx i pt in
 		let index = gen_local ctx t_int in
@@ -420,7 +423,7 @@ let optimize_for_loop ctx i e1 e2 p =
 		lblock [
 			mk (TVars (ivar :: avars)) t_void p;
 			mk (TWhile (
-				mk (TBinop (OpLt, iexpr, mk (TField (arr,"length")) t_int p)) ctx.t.tbool p,
+				mk (TBinop (OpLt, iexpr, mk (mk_field arr "length") t_int p)) ctx.t.tbool p,
 				block,
 				NormalWhile
 			)) t_void p;
@@ -491,14 +494,14 @@ let optimize_for_loop ctx i e1 e2 p =
 		let cell = gen_local ctx tcell in
 		let cexpr = mk (TLocal cell) tcell p in
 		let e2 = type_expr ctx e2 false in
-		let evar = mk (TVars [i,Some (mk (TField (cexpr,"elt")) t p)]) t_void p in
-		let enext = mk (TBinop (OpAssign,cexpr,mk (TField (cexpr,"next")) tcell p)) tcell p in
+		let evar = mk (TVars [i,Some (mk (mk_field cexpr "elt") t p)]) t_void p in
+		let enext = mk (TBinop (OpAssign,cexpr,mk (mk_field cexpr "next") tcell p)) tcell p in
 		let block = match e2.eexpr with
 			| TBlock el -> mk (TBlock (evar :: enext :: el)) t_void e2.epos
 			| _ -> mk (TBlock [evar;enext;e2]) t_void p
 		in
 		lblock [
-			mk (TVars [cell,Some (mk (TField (e1,"head")) tcell p)]) t_void p;
+			mk (TVars [cell,Some (mk (mk_field e1 "head") tcell p)]) t_void p;
 			mk (TWhile (
 				mk (TBinop (OpNotEq, cexpr, mk (TConst TNull) tcell p)) ctx.t.tbool p,
 				block,
@@ -870,7 +873,7 @@ let rec reduce_loop ctx e =
 		| _ -> e
 		)
 	| TCall ({ eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },field) },params) ->
-		(match api_inline ctx c field params e.epos with
+		(match api_inline ctx c (field_name field) params e.epos with
 		| None -> reduce_expr ctx e
 		| Some e -> reduce_loop ctx e)
 	| TCall ({ eexpr = TFunction func } as ef,el) ->
@@ -882,7 +885,7 @@ let rec reduce_loop ctx e =
 		| None -> reduce_expr ctx e
 		| Some e -> reduce_loop ctx e)
 	| TCall ({ eexpr = TClosure (o,name) } as f,el) ->
-		{ e with eexpr = TCall ({ f with eexpr = TField (o,name) },el) }
+		{ e with eexpr = TCall ({ f with eexpr = TField (o,try quick_field o.etype name with Not_found -> assert false) },el) }
 	| _ ->
 		reduce_expr ctx e)
 

+ 35 - 2
type.ml

@@ -101,7 +101,7 @@ and texpr_expr =
 	| TEnumField of tenum * string
 	| TArray of texpr * texpr
 	| TBinop of Ast.binop * texpr * texpr
-	| TField of texpr * string
+	| TField of texpr * tfield_access
 	| TClosure of texpr * string
 	| TTypeExpr of module_type
 	| TParenthesis of texpr
@@ -125,6 +125,12 @@ and texpr_expr =
 	| TThrow of texpr
 	| TCast of texpr * module_type option
 
+and tfield_access =
+	| FInstance of tclass * tclass_field
+	| FStatic of tclass * tclass_field
+	| FAnon of tclass_field
+	| FDynamic of string
+
 and texpr = {
 	eexpr : texpr_expr;
 	etype : t;
@@ -299,6 +305,11 @@ let tfun pl r = TFun (List.map (fun t -> "",false,t) pl,r)
 
 let fun_args l = List.map (fun (a,c,t) -> a, c <> None, t) l
 
+let field_name f =
+	match f with
+	| FAnon f | FInstance (_,f) | FStatic (_,f) -> f.cf_name
+	| FDynamic n -> n
+
 let mk_class m path pos =
 	{
 		cl_path = path;
@@ -903,6 +914,28 @@ let rec raw_class_field build_type c i =
 
 let class_field = raw_class_field field_type
 
+let quick_field t n =
+	match follow t with
+	| TInst (c,_) ->
+		let _, f = raw_class_field (fun f -> f.cf_type) c n in
+		FInstance (c,f)
+	| TAnon a ->
+		(match !(a.a_status) with
+		| EnumStatics e ->
+			assert false (* to replace with FEnum later *)
+		| Statics c ->
+			FStatic (c,PMap.find n c.cl_statics)
+		| AbstractStatics _ ->
+			assert false
+		| _ ->
+			FAnon (PMap.find n a.a_fields))
+	| TDynamic _ ->
+		FDynamic n
+	| TEnum _  | TMono _ | TAbstract _ | TFun _ ->
+		raise Not_found
+	| TLazy _ | TType _ ->
+		assert false
+
 let rec get_constructor build_type c =
 	match c.cl_constructor, c.cl_super with
 	| Some c, _ -> build_type c, c
@@ -1374,7 +1407,7 @@ let rec s_expr s_type e =
 	| TBinop (op,e1,e2) ->
 		sprintf "(%s %s %s)" (loop e1) (s_binop op) (loop e2)
 	| TField (e,f) ->
-		sprintf "%s.%s" (loop e) f
+		sprintf "%s.%s" (loop e) (field_name f)
 	| TClosure (e,s) ->
 		sprintf "Closure (%s,%s)" (loop e) s
 	| TTypeExpr m ->

+ 4 - 4
typecore.ml

@@ -26,10 +26,10 @@ type type_patch = {
 }
 
 type current_fun =
-	| FMember
-	| FStatic
-	| FConstructor
-	| FMemberLocal
+	| FunMember
+	| FunStatic
+	| FunConstructor
+	| FunMemberLocal
 
 type macro_mode =
 	| MExpr

+ 6 - 7
typeload.ml

@@ -133,7 +133,7 @@ let type_function_param ctx t e opt p =
 		t, e
 
 let type_var_field ctx t e stat p =
-	if stat then ctx.curfun <- FStatic;
+	if stat then ctx.curfun <- FunStatic;
 	let e = type_expr_with_type ctx e (Some t) false in
 	unify ctx e.etype t p;
 	match t with
@@ -827,7 +827,7 @@ let type_function ctx args ret fmode f p =
 		| Some (csup,_) ->
 			try ignore(get_constructor (fun f->f.cf_type) csup); true with Not_found -> false
 	in
-	if fmode = FConstructor && has_super_constr() then
+	if fmode = FunConstructor && has_super_constr() then
 		(try
 			loop e;
 			display_error ctx "Missing super constructor call" p
@@ -835,7 +835,7 @@ let type_function ctx args ret fmode f p =
 			Exit -> ());
 	locals();
 	let e = match ctx.curfun, ctx.vthis with
-		| (FMember|FConstructor), Some v ->
+		| (FunMember|FunConstructor), Some v ->
 			let ev = mk (TVars [v,Some (mk (TConst TThis) ctx.tthis p)]) ctx.t.tvoid p in
 			(match e.eexpr with
 			| TBlock l -> { e with eexpr = TBlock (ev::l) }
@@ -1111,9 +1111,8 @@ let init_class ctx c p context_init herits fields =
 			| TParenthesis e -> Some e
 			| TTypeExpr _ -> Some e
 			(* try to inline static function calls *)
-			| TCall ({ etype = TFun(_,ret); eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },n) },el) ->
+			| TCall ({ etype = TFun(_,ret); eexpr = TField (_,FStatic (c,cf)) },el) ->
 				(try
-					let cf = PMap.find n c.cl_statics in
 					let func = match cf.cf_expr with Some ({eexpr = TFunction func}) -> func | _ -> raise Not_found in
 					let ethis = mk (TConst TThis) t_dynamic e.epos in
 					let inl = (try Optimizer.type_inline ctx cf func ethis el ret e.epos false with Error (Custom _,_) -> None) in
@@ -1283,7 +1282,7 @@ let init_class ctx c p context_init herits fields =
 					context_init();
 					incr stats.s_methods_typed;
 					if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ name);
-					let e , fargs = type_function ctx args ret (if constr then FConstructor else if stat then FStatic else FMember) fd p in
+					let e , fargs = type_function ctx args ret (if constr then FunConstructor else if stat then FunStatic else FunMember) fd p in
 					let f = {
 						tf_args = fargs;
 						tf_type = ret;
@@ -1823,7 +1822,7 @@ let type_module ctx m file tdecls p =
 		ret = ctx.ret;
 		locals = PMap.empty;
 		type_params = [];
-		curfun = FStatic;
+		curfun = FunStatic;
 		untyped = false;
 		in_super_call = false;
 		in_macro = ctx.in_macro;

+ 72 - 67
typer.ml

@@ -39,9 +39,9 @@ exception DisplayFields of (string * t * documentation) list
 type access_kind =
 	| AKNo of string
 	| AKExpr of texpr
-	| AKField of texpr * tclass_field
+	| AKField of texpr * tclass_field * tfield_access
 	| AKSet of texpr * string * t * string
-	| AKInline of texpr * tclass_field * t
+	| AKInline of texpr * tclass_field * tfield_access * t
 	| AKMacro of texpr * tclass_field
 	| AKUsing of texpr * tclass * tclass_field * texpr
 
@@ -535,7 +535,7 @@ let get_constructor ctx c params p =
 
 let make_call ctx e params t p =
 	try
-		let ethis, fname = (match e.eexpr with TField (ethis,fname) -> ethis, fname | _ -> raise Exit) in
+		let ethis, fname = (match e.eexpr with TField (ethis,f) -> ethis, field_name f | _ -> raise Exit) in
 		let f, cl = (match follow ethis.etype with
 			| TInst (c,params) -> snd (try Type.class_field c fname with Not_found -> raise Exit), Some c
 			| TAnon a -> (try PMap.find fname a.a_fields with Not_found -> raise Exit), (match !(a.a_status) with Statics c -> Some c | _ -> None)
@@ -569,7 +569,7 @@ let make_call ctx e params t p =
 let rec acc_get ctx g p =
 	match g with
 	| AKNo f -> error ("Field " ^ f ^ " cannot be accessed for reading") p
-	| AKExpr e | AKField (e,_) -> e
+	| AKExpr e | AKField (e,_,_) -> e
 	| AKSet _ -> assert false
 	| AKUsing (et,_,_,e) ->
 		(* build a closure with first parameter applied *)
@@ -592,7 +592,7 @@ let rec acc_get ctx g p =
 			}) twrap p in
 			make_call ctx ewrap [e] tcallb p
 		| _ -> assert false)
-	| AKInline (e,f,t) ->
+	| AKInline (e,f,_,t) ->
 		ignore(follow f.cf_type); (* force computing *)
 		(match f.cf_expr with
 		| None ->
@@ -625,14 +625,14 @@ let error_require r p =
 	in
 	error ("Accessing this field requires " ^ r) p
 
-let field_access ctx mode f t e p =
-	let fnormal() = AKField ((mk (TField (e,f.cf_name)) t p),f) in
+let field_access ctx mode f fmode t e p =
+	let fnormal() = AKField ((mk (TField (e,fmode)) t p),f,fmode) in
 	let normal() =
 		match follow e.etype with
 		| TAnon a ->
 			(match !(a.a_status) with
 			| EnumStatics e ->
-				AKField ((mk (TEnumField (e,f.cf_name)) t p),f)
+				AKField ((mk (TEnumField (e,f.cf_name)) t p),f, fmode)
 			| _ -> fnormal())
 		| _ -> fnormal()
 	in
@@ -640,7 +640,7 @@ let field_access ctx mode f t e p =
 	| Method m ->
 		if mode = MSet && m <> MethDynamic && not ctx.untyped then error "Cannot rebind this method : please use 'dynamic' before method declaration" p;
 		(match m, mode with
-		| MethInline, _ -> AKInline (e,f,t)
+		| MethInline, _ -> AKInline (e,f,fmode,t)
 		| MethMacro, MGet -> display_error ctx "Macro functions must be called immediately" p; normal()
 		| MethMacro, MCall -> AKMacro (e,f)
 		| _ , MGet ->
@@ -683,19 +683,19 @@ let field_access ctx mode f t e p =
 					display_error ctx "This field cannot be accessed since it is not an actual var" p;
 					display_error ctx "Add @:isVar here to enable it" f.cf_pos;
 				end;
-				AKExpr (mk (TField (e,prefix ^ f.cf_name)) t p)
+				AKExpr (mk (TField (e,if prefix = "" then fmode else FDynamic (prefix ^ f.cf_name))) t p)
 			else if mode = MSet then
 				AKSet (e,m,t,f.cf_name)
 			else
-				AKExpr (make_call ctx (mk (TField (e,m)) (tfun [] t) p) [] t p)
+				AKExpr (make_call ctx (mk (TField (e,FDynamic m)) (tfun [] t) p) [] t p)
 		| AccResolve ->
 			let fstring = mk (TConst (TString f.cf_name)) ctx.t.tstring p in
 			let tresolve = tfun [ctx.t.tstring] t in
-			AKExpr (make_call ctx (mk (TField (e,"resolve")) tresolve p) [fstring] t p)
+			AKExpr (make_call ctx (mk (TField (e,FDynamic "resolve")) tresolve p) [fstring] t p)
 		| AccNever ->
 			if ctx.untyped then normal() else AKNo f.cf_name
 		| AccInline ->
-			AKInline (e,f,t)
+			AKInline (e,f,fmode,t)
 		| AccRequire (r,msg) ->
 			match msg with
 			| None -> error_require r p
@@ -721,7 +721,7 @@ let using_field ctx mode e i p =
 				if follow e.etype == t_dynamic && follow t0 != t_dynamic then raise Not_found;
 				if has_meta ":noUsing" f.cf_meta then raise Not_found;
 				let et = type_module_type ctx (TClassDecl c) None p in
-				AKUsing (mk (TField (et,i)) t p,c,f,e)
+				AKUsing (mk (TField (et,FStatic (c,f))) t p,c,f,e)
 			| _ -> raise Not_found)
 		with Not_found ->
 			loop l
@@ -730,9 +730,9 @@ let using_field ctx mode e i p =
 
 let get_this ctx p =
 	match ctx.curfun with
-	| FStatic ->
+	| FunStatic ->
 		error "Cannot access this from a static function" p
-	| FMemberLocal ->
+	| FunMemberLocal ->
 		if ctx.untyped then display_error ctx "Cannot access this in 'untyped' mode : use either '__this__' or var 'me = this' (transitional)" p;
 		let v = (match ctx.vthis with
 			| None ->
@@ -744,7 +744,7 @@ let get_this ctx p =
 				v
 		) in
 		mk (TLocal v) ctx.tthis p
-	| FConstructor | FMember ->
+	| FunConstructor | FunMember ->
 		mk (TConst TThis) ctx.tthis p
 
 let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
@@ -770,9 +770,9 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 			| Some (c,params) -> TInst(c,params)
 		) in
 		(match ctx.curfun with
-		| FMember | FConstructor -> ()
-		| FStatic -> error "Cannot access super inside a static function" p;
-		| FMemberLocal -> error "Cannot access super inside a local function" p);
+		| FunMember | FunConstructor -> ()
+		| FunStatic -> error "Cannot access super inside a static function" p;
+		| FunMemberLocal -> error "Cannot access super inside a local function" p);
 		if mode = MSet || not ctx.in_super_call then
 			if mode = MGet && ctx.com.display then
 				AKExpr (mk (TConst TSuper) t p)
@@ -800,19 +800,19 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 				let cf = { (mk_field v.v_name v.v_type e.epos) with cf_params = params; cf_expr = Some e; cf_kind = Method MethInline } in
 				c.cl_extern <- true;
 				c.cl_fields <- PMap.add cf.cf_name cf PMap.empty;
-				AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, t)
+				AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, FInstance(c,cf), t)
 			| _ ->
 				AKExpr (mk (TLocal v) t p))
 		| _ ->
 			AKExpr (mk (TLocal v) v.v_type p))
 	with Not_found -> try
 		(* member variable lookup *)
-		if ctx.curfun = FStatic then raise Not_found;
+		if ctx.curfun = FunStatic then raise Not_found;
 		let t , f = class_field ctx ctx.curclass [] i p in
-		field_access ctx mode f t (get_this ctx p) p
+		field_access ctx mode f (FInstance (ctx.curclass,f)) t (get_this ctx p) p
 	with Not_found -> try
 		(* lookup using on 'this' *)
-		if ctx.curfun = FStatic then raise Not_found;
+		if ctx.curfun = FunStatic then raise Not_found;
 		(match using_field ctx mode (mk (TConst TThis) ctx.tthis p) i p with
 		| AKUsing (et,c,f,_) -> AKUsing (et,c,f,get_this ctx p)
 		| _ -> assert false)
@@ -821,7 +821,7 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 		let f = PMap.find i ctx.curclass.cl_statics in
 		let e = type_type ctx ctx.curclass.cl_path p in
 		(* check_locals_masking already done in type_type *)
-		field_access ctx mode f (field_type ctx ctx.curclass [] f p) e p
+		field_access ctx mode f (FStatic (ctx.curclass,f)) (field_type ctx ctx.curclass [] f p) e p
 	with Not_found -> try
 		if not imported_enums then raise Not_found;
 		(* lookup imported enums *)
@@ -857,7 +857,7 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 and type_field ctx e i p mode =
 	let no_field() =
 		if not ctx.untyped then display_error ctx (s_type (print_context()) e.etype ^ " has no field " ^ i) p;
-		AKExpr (mk (TField (e,i)) (mk_mono()) p)
+		AKExpr (mk (TField (e,FDynamic i)) (mk_mono()) p)
 	in
 	match follow e.etype with
 	| TInst (c,params) ->
@@ -865,10 +865,11 @@ and type_field ctx e i p mode =
 			match c.cl_dynamic with
 			| Some t ->
 				let t = apply_params c.cl_types params t in
-				if (mode = MGet || mode = MCall) && PMap.mem "resolve" c.cl_fields then
-					AKExpr (make_call ctx (mk (TField (e,"resolve")) (tfun [ctx.t.tstring] t) p) [Codegen.type_constant ctx.com (String i) p] t p)
-				else
-					AKExpr (mk (TField (e,i)) t p)
+				if (mode = MGet || mode = MCall) && PMap.mem "resolve" c.cl_fields then begin
+					let f = PMap.find "resolve" c.cl_fields in
+					AKExpr (make_call ctx (mk (TField (e,FInstance (c,f))) (tfun [ctx.t.tstring] t) p) [Codegen.type_constant ctx.com (String i) p] t p)
+				end else
+					AKExpr (mk (TField (e,FDynamic i)) t p)
 			| None ->
 				match c.cl_super with
 				| None -> raise Not_found
@@ -878,7 +879,7 @@ and type_field ctx e i p mode =
 			let t , f = class_field ctx c params i p in
 			if e.eexpr = TConst TSuper && (match f.cf_kind with Var _ -> true | _ -> false) && Common.platform ctx.com Flash then error "Cannot access superclass variable for calling : needs to be a proper method" p;
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
-			field_access ctx mode f (apply_params c.cl_types params t) e p
+			field_access ctx mode f (FInstance (c,f)) (apply_params c.cl_types params t) e p
 		with Not_found -> try
 			using_field ctx mode e i p
 		with Not_found -> try
@@ -894,14 +895,14 @@ and type_field ctx e i p mode =
 					a_fields = PMap.add "next" (mk_field "next" (TFun([],List.hd params)) p) PMap.empty;
 					a_status = ref Closed;
 				} in
-				AKExpr (mk (TField (e,i)) (TFun([],it)) p)
+				AKExpr (mk (TField (e,FDynamic i)) (TFun([],it)) p)
 			end else
 			no_field())
 	| TDynamic t ->
 		(try
 			using_field ctx mode e i p
 		with Not_found ->
-			AKExpr (mk (TField (e,i)) t p))
+			AKExpr (mk (TField (e,FDynamic i)) t p))
 	| TAnon a ->
 		(try
 			let f = PMap.find i a.a_fields in
@@ -911,7 +912,11 @@ and type_field ctx e i p mode =
 				| Statics c when can_access ctx c f true -> ()
 				| _ -> display_error ctx ("Cannot access private field " ^ i) p
 			end;
-			field_access ctx mode f (match !(a.a_status) with Statics c -> field_type ctx c [] f p | _ -> Type.field_type f) e p
+			let fmode, ft = (match !(a.a_status) with
+				| Statics c -> FStatic (c,f), field_type ctx c [] f p
+				| _ -> FAnon f, Type.field_type f
+			) in
+			field_access ctx mode f fmode ft e p
 		with Not_found ->
 			if is_closed a then try
 				using_field ctx mode e i p
@@ -931,7 +936,7 @@ and type_field ctx e i p mode =
 				cf_overloads = [];
 			} in
 			a.a_fields <- PMap.add i f a.a_fields;
-			field_access ctx mode f (Type.field_type f) e p
+			field_access ctx mode f (FAnon f) (Type.field_type f) e p
 		)
 	| TMono r ->
 		if ctx.untyped && (match ctx.com.platform with Flash8 -> Common.defined ctx.com Define.SwfMark | _ -> false) then ctx.com.warning "Mark" p;
@@ -951,7 +956,7 @@ and type_field ctx e i p mode =
 		let t = TAnon { a_fields = PMap.add i f PMap.empty; a_status = x } in
 		ctx.opened <- x :: ctx.opened;
 		r := Some t;
-		field_access ctx mode f (Type.field_type f) e p
+		field_access ctx mode f (FAnon f) (Type.field_type f) e p
 	| _ ->
 		try using_field ctx mode e i p with Not_found -> no_field()
 
@@ -1053,7 +1058,7 @@ let unify_int ctx e k =
 		match e.eexpr with
 		| TLocal _ -> is_dynamic e.etype
 		| TArray({ etype = t } as e,_) -> is_dynamic_array t || maybe_dynamic_rec e t
-		| TField({ etype = t } as e,f) -> is_dynamic_field t f || maybe_dynamic_rec e t
+		| TField({ etype = t } as e,f) -> is_dynamic_field t (field_name f) || maybe_dynamic_rec e t
 		| TCall({ etype = t } as e,_) -> is_dynamic_return t || maybe_dynamic_rec e t
 		| TParenthesis e -> maybe_dynamic_mono e
 		| TIf (_,a,Some b) -> maybe_dynamic_mono a || maybe_dynamic_mono b
@@ -1114,7 +1119,7 @@ let type_generic_function ctx (e,cf) el p =
 			cf2
 		in
 		let e = if stat then type_type ctx c.cl_path p else e in
-		let e = acc_get ctx (field_access ctx MCall cf2 cf2.cf_type e p) p in
+		let e = acc_get ctx (field_access ctx MCall cf2 (if stat then FStatic (c,cf2) else FInstance (c,cf2)) cf2.cf_type e p) p in
 		(el,ret,e)
 	with Codegen.Generic_Exception (msg,p) ->
 		error msg p)
@@ -1123,28 +1128,28 @@ let rec type_binop ctx op e1 e2 p =
 	match op with
 	| OpAssign ->
 		let e1 = type_access ctx (fst e1) (snd e1) MSet in
-		let tt = (match e1 with AKNo _ | AKInline _ | AKUsing _ | AKMacro _ -> None | AKSet(_,_,t,_) -> Some t | AKExpr e | AKField (e,_) -> Some e.etype) in
+		let tt = (match e1 with AKNo _ | AKInline _ | AKUsing _ | AKMacro _ -> None | AKSet(_,_,t,_) -> Some t | AKExpr e | AKField (e,_,_) -> Some e.etype) in
 		let e2 = type_expr_with_type ctx e2 tt in
 		(match e1 with
 		| AKNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p
-		| AKExpr e1 | AKField (e1,_) ->
+		| AKExpr e1 | AKField (e1,_,_) ->
 			unify ctx e2.etype e1.etype p;
 			check_assign ctx e1;
 			(match e1.eexpr , e2.eexpr with
 			| TLocal i1 , TLocal i2 when i1 == i2 -> error "Assigning a value to itself" p
-			| TField ({ eexpr = TConst TThis },i1) , TField ({ eexpr = TConst TThis },i2) when i1 = i2 ->
+			| TField ({ eexpr = TConst TThis },FInstance (_,f1)) , TField ({ eexpr = TConst TThis },FInstance (_,f2)) when f1 == f2 ->
 				error "Assigning a value to itself" p
 			| _ , _ -> ());
 			mk (TBinop (op,e1,e2)) e1.etype p
 		| AKSet (e,m,t,_) ->
 			unify ctx e2.etype t p;
-			make_call ctx (mk (TField (e,m)) (tfun [t] t) p) [e2] t p
+			make_call ctx (mk (TField (e,FDynamic m)) (tfun [t] t) p) [e2] t p
 		| AKInline _ | AKUsing _ | AKMacro _ ->
 			assert false)
 	| OpAssignOp op ->
 		(match type_access ctx (fst e1) (snd e1) MSet with
 		| AKNo s -> error ("Cannot access field or identifier " ^ s ^ " for writing") p
-		| AKExpr e | AKField (e,_) ->
+		| AKExpr e | AKField (e,_,_) ->
 			let eop = type_binop ctx op e1 e2 p in
 			(match eop.eexpr with
 			| TBinop (_,_,e2) ->
@@ -1162,7 +1167,7 @@ let rec type_binop ctx op e1 e2 p =
 			l();
 			mk (TBlock [
 				mk (TVars [v,Some e]) ctx.t.tvoid p;
-				make_call ctx (mk (TField (ev,m)) (tfun [t] t) p) [get] t p
+				make_call ctx (mk (TField (ev,FDynamic m)) (tfun [t] t) p) [get] t p
 			]) t p
 		| AKInline _ | AKUsing _ | AKMacro _ ->
 			assert false)
@@ -1178,7 +1183,7 @@ let rec type_binop ctx op e1 e2 p =
 			let std = type_type ctx ([],"Std") e.epos in
 			let acc = acc_get ctx (type_field ctx std "string" e.epos MCall) e.epos in
 			ignore(follow acc.etype);
-			let acc = (match acc.eexpr with TClosure (e,f) -> { acc with eexpr = TField (e,f) } | _ -> acc) in
+			let acc = (match acc.eexpr with TClosure (e,f) -> { acc with eexpr = TField (e,FDynamic f) } | _ -> acc) in
 			make_call ctx acc [e] ctx.t.tstring e.epos
 		| KInt | KFloat | KString -> e
 	in
@@ -1358,7 +1363,7 @@ and type_unop ctx op flag e p =
 		mk (TUnop (op,flag,e)) t p
 	in
 	match acc with
-	| AKExpr e | AKField (e,_) -> access e
+	| AKExpr e | AKField (e,_,_) -> access e
 	| AKInline _ | AKUsing _ when not set -> access (acc_get ctx acc p)
 	| AKNo s ->
 		error ("The field or identifier " ^ s ^ " is not accessible for " ^ (if set then "writing" else "reading")) p
@@ -1378,7 +1383,7 @@ and type_unop ctx op flag e p =
 			l();
 			mk (TBlock [
 				mk (TVars [v,Some e]) ctx.t.tvoid p;
-				make_call ctx (mk (TField (ev,m)) (tfun [t] t) p) [get] t p
+				make_call ctx (mk (TField (ev,FDynamic m)) (tfun [t] t) p) [get] t p
 			]) t p
 		| Postfix ->
 			let v2 = gen_local ctx t in
@@ -1389,7 +1394,7 @@ and type_unop ctx op flag e p =
 			l();
 			mk (TBlock [
 				mk (TVars [v,Some e; v2,Some get]) ctx.t.tvoid p;
-				make_call ctx (mk (TField (ev,m)) (tfun [plusone.etype] t) p) [plusone] t p;
+				make_call ctx (mk (TField (ev,FDynamic m)) (tfun [plusone.etype] t) p) [plusone] t p;
 				ev2
 			]) t p
 
@@ -1617,7 +1622,7 @@ and type_ident ctx i p mode =
 				let t = mk_mono() in
 				AKExpr (mk (TLocal (alloc_var i t)) t p)
 		end else begin
-			if ctx.curfun = FStatic && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p;
+			if ctx.curfun = FunStatic && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p;
 			let err = Unknown_ident i in
 			if ctx.in_display then raise (Error (err,p));
 			if ctx.com.display then begin
@@ -2138,7 +2143,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 						e1
 					with Error (Unify _,_) ->
 						let acc = acc_get ctx (type_field ctx e1 "iterator" e1.epos MCall) e1.epos in
-						let acc = (match acc.eexpr with TClosure (e,f) -> { acc with eexpr = TField (e,f) } | _ -> acc) in
+						let acc = (match acc.eexpr with TClosure (e,f) -> { acc with eexpr = TField (e,FDynamic f) } | _ -> acc) in
 						match follow acc.etype with
 						| TFun ([],it) ->
 							unify ctx it t e1.epos;
@@ -2156,8 +2161,8 @@ and type_expr ctx ?(need_val=true) (e,p) =
 					if fhasnext.cf_kind <> Method MethInline then raise Exit;
 					let tmp = gen_local ctx e1.etype in
 					let eit = mk (TLocal tmp) e1.etype p in
-					let ehasnext = make_call ctx (mk (TField (eit,"hasNext")) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in
-					let enext = mk (TVars [i,Some (make_call ctx (mk (TField (eit,"next")) (TFun ([],pt)) p) [] pt p)]) ctx.t.tvoid p in
+					let ehasnext = make_call ctx (mk (TField (eit,FInstance (c, fhasnext))) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in
+					let enext = mk (TVars [i,Some (make_call ctx (mk (TField (eit,FDynamic "next")) (TFun ([],pt)) p) [] pt p)]) ctx.t.tvoid p in
 					let eblock = (match e2.eexpr with
 						| TBlock el -> { e2 with eexpr = TBlock (enext :: el) }
 						| _ -> mk (TBlock [enext;e2]) ctx.t.tvoid p
@@ -2337,7 +2342,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 				if v.[0] = '$' then display_error ctx "Variables names starting with a dollar are not allowed" p;
 				Some (add_local ctx v ft)
 		) in
-		let e , fargs = Typeload.type_function ctx args rt (match ctx.curfun with FStatic -> FStatic | _ -> FMemberLocal) f p in
+		let e , fargs = Typeload.type_function ctx args rt (match ctx.curfun with FunStatic -> FunStatic | _ -> FunMemberLocal) f p in
 		ctx.type_params <- old;
 		let f = {
 			tf_args = fargs;
@@ -2411,10 +2416,10 @@ and type_expr ctx ?(need_val=true) (e,p) =
 		ctx.in_display <- true;
 		let e = (try type_expr ctx e with Error (Unknown_ident n,_) -> raise (Parser.TypePath ([n],None))) in
 		let e = match e.eexpr with
-			| TField (e,"callback") ->
+			| TField (e,f) when field_name f = "callback" ->
 				(match follow e.etype with
-					| TFun(args,ret) -> {e with etype = opt_args args ret}
-					| _ -> e)
+				| TFun(args,ret) -> {e with etype = opt_args args ret}
+				| _ -> e)
 			| _ -> e
 		in
 		ctx.in_display <- old;
@@ -2557,7 +2562,7 @@ and type_call ctx e el twith p =
 		else
 			e
 	| (EConst (Ident "super"),sp) , el ->
-		if ctx.curfun <> FConstructor then error "Cannot call super constructor outside class constructor" p;
+		if ctx.curfun <> FunConstructor then error "Cannot call super constructor outside class constructor" p;
 		let el, t = (match ctx.curclass.cl_super with
 		| None -> error "Current class does not have a super" p
 		| Some (c,params) ->
@@ -2584,12 +2589,12 @@ and build_call ctx acc el twith p =
 		| _ -> None
 	in
 	match acc with
-	| AKInline (ethis,f,t) ->
+	| AKInline (ethis,f,fmode,t) ->
 		let params, tfunc = (match follow t with
 			| TFun (args,r) -> unify_call_params ctx (fopts ethis.etype f) el args r p true
 			| _ -> error (s_type (print_context()) t ^ " cannot be called") p
 		) in
-		make_call ctx (mk (TField (ethis,f.cf_name)) t p) params (match tfunc with TFun(_,r) -> r | _ -> assert false) p
+		make_call ctx (mk (TField (ethis,fmode)) t p) params (match tfunc with TFun(_,r) -> r | _ -> assert false) p
 	| AKUsing (et,cl,ef,eparam) when has_meta ":generic" ef.cf_meta ->
 		(match et.eexpr with
 		| TField(ec,_) ->
@@ -2652,11 +2657,11 @@ and build_call ctx acc el twith p =
 	| AKNo _ | AKSet _ ->
 		ignore(acc_get ctx acc p);
 		assert false
-	| AKExpr e | AKField (e,_) ->
+	| AKExpr e | AKField (e,_,_) ->
 		let el , t, e = (match follow e.etype with
 		| TFun (args,r) ->
 			let fopts = (match acc with
-				| AKField (e,f) ->
+				| AKField (e,f,_) ->
 					(match e.eexpr with
 					| TField (e,_) -> fopts e.etype f
 					| _ -> None)
@@ -2664,7 +2669,7 @@ and build_call ctx acc el twith p =
 					None
 			) in
 			(match fopts,acc with
-				| Some (_,cf),AKField({eexpr = TField(e,_)},_) when has_meta ":generic" cf.cf_meta ->
+				| Some (_,cf),AKField({eexpr = TField(e,_)},_,_) when has_meta ":generic" cf.cf_meta ->
 					type_generic_function ctx (e,cf) el p
 				| _ ->
 					let el, tfunc = unify_call_params ctx fopts el args r p false in
@@ -2703,7 +2708,7 @@ let get_main ctx =
 	| None -> None
 	| Some cl ->
 		let t = Typeload.load_type_def ctx null_pos { tpackage = fst cl; tname = snd cl; tparams = []; tsub = None } in
-		let ft, r = (match t with
+		let fmode, ft, r = (match t with
 		| TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ ->
 			error ("Invalid -main : " ^ s_type_path cl ^ " is not a class") null_pos
 		| TClassDecl c ->
@@ -2711,13 +2716,13 @@ let get_main ctx =
 				let f = PMap.find "main" c.cl_statics in
 				let t = Type.field_type f in
 				(match follow t with
-				| TFun ([],r) -> t, r
+				| TFun ([],r) -> FStatic (c,f), t, r
 				| _ -> error ("Invalid -main : " ^ s_type_path cl ^ " has invalid main function") c.cl_pos);
 			with
 				Not_found -> error ("Invalid -main : " ^ s_type_path cl ^ " does not have static function main") c.cl_pos
 		) in
 		let emain = type_type ctx cl null_pos in
-		Some (mk (TCall (mk (TField (emain,"main")) ft null_pos,[])) r null_pos)
+		Some (mk (TCall (mk (TField (emain,fmode)) ft null_pos,[])) r null_pos)
 
 let finalize ctx =
 	flush_pass ctx PFinal "final"
@@ -2815,7 +2820,7 @@ let generate ctx =
 					| TEnumDecl _ -> ()
 					| TAbstractDecl _ -> assert false
 					| TTypeDecl _ -> assert false
-					| TClassDecl c -> walk_static_call p c name)
+					| TClassDecl c -> walk_static_call p c (field_name name))
 				| _ -> ()
 			in
 			loop f
@@ -3392,7 +3397,7 @@ let rec create com =
 		pass = PBuildModule;
 		macro_depth = 0;
 		untyped = false;
-		curfun = FStatic;
+		curfun = FunStatic;
 		in_loop = false;
 		in_super_call = false;
 		in_display = false;