Browse Source

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

Nicolas Cannasse 12 years ago
parent
commit
8d25f80906
16 changed files with 325 additions and 242 deletions
  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;