Browse Source

change TVars to not hold a list

Simon Krajewski 11 years ago
parent
commit
c88ecce5e5
18 changed files with 181 additions and 214 deletions
  1. 11 15
      codegen.ml
  2. 3 5
      dce.ml
  3. 23 29
      filters.ml
  4. 8 11
      genas3.ml
  5. 29 35
      gencpp.ml
  6. 5 8
      genjs.ml
  7. 5 5
      genneko.ml
  8. 12 16
      genphp.ml
  9. 3 4
      genswf.ml
  10. 2 4
      genswf8.ml
  11. 8 10
      genswf9.ml
  12. 6 6
      interp.ml
  13. 35 36
      optimizer.ml
  14. 1 1
      std/haxe/macro/Type.hx
  15. 2 2
      std/haxe/macro/TypedExprTools.hx
  16. 11 11
      type.ml
  17. 1 1
      typeload.ml
  18. 16 15
      typer.ml

+ 11 - 15
codegen.ml

@@ -788,10 +788,8 @@ module PatternMatchConversion = struct
 				else
 					((v,Some e) :: vl), el
 			) ([],[e]) bl in
-			mk (TBlock
-				((mk (TVars (vl)) cctx.ctx.t.tvoid e.epos)
-				:: el)
-			) e.etype e.epos
+			let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) cctx.ctx.t.tvoid e.epos) vl in
+			mk (TBlock (el_v @ el)) e.etype e.epos
 		| DTGoto i ->
 			convert_dt cctx (cctx.dt_lookup.(i))
 		| DTExpr e ->
@@ -819,10 +817,8 @@ module PatternMatchConversion = struct
 		if dt.dt_var_init = [] then
 			e
 		else begin
-			mk (TBlock [
-				mk (TVars dt.dt_var_init) t_dynamic e.epos;
-				e;
-			]) dt.dt_type e.epos
+			let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) cctx.ctx.t.tvoid p) dt.dt_var_init in
+			mk (TBlock (el_v @ [e])) dt.dt_type e.epos
 		end
 end
 
@@ -938,7 +934,7 @@ let stack_context_init com stack_var exc_var pos_var tmp_var use_add p =
 	let stack_return e =
 		let tmp = alloc_var tmp_var e.etype in
 		mk (TBlock [
-			mk (TVars [tmp, Some e]) t.tvoid e.epos;
+			mk (TVars (tmp, Some e)) t.tvoid e.epos;
 			stack_pop;
 			mk (TReturn (Some (mk (TLocal tmp) e.etype e.epos))) e.etype e.epos
 		]) e.etype e.epos
@@ -950,7 +946,7 @@ let stack_context_init com stack_var exc_var pos_var tmp_var use_add p =
 		stack_pos = p;
 		stack_expr = stack_e;
 		stack_pop = stack_pop;
-		stack_save_pos = mk (TVars [pos_var, Some (field stack_e "length" t.tint p)]) t.tvoid p;
+		stack_save_pos = mk (TVars (pos_var, Some (field stack_e "length" t.tint p))) t.tvoid p;
 		stack_push = stack_push;
 		stack_return = stack_return;
 		stack_restore = [
@@ -1062,10 +1058,10 @@ let fix_override com c f fd =
 						let e = fd.tf_expr in
 						let el = (match e.eexpr with TBlock el -> el | _ -> [e]) in
 						let p = (match el with [] -> e.epos | e :: _ -> e.epos) in
-						let v = mk (TVars (List.map (fun (v,v2) ->
-							(v,Some (mk (TCast (mk (TLocal v2) v2.v_type p,None)) v.v_type p))
-						) args)) com.basic.tvoid p in
-						{ e with eexpr = TBlock (v :: el) }
+						let el_v = List.map (fun (v,v2) ->
+							mk (TVars (v,Some (mk (TCast (mk (TLocal v2) v2.v_type p,None)) v.v_type p))) com.basic.tvoid p
+						) args in
+						{ e with eexpr = TBlock (el_v @ el) }
 				);
 			} in
 			(* as3 does not allow wider visibility, so the base method has to be made public *)
@@ -1269,7 +1265,7 @@ let default_cast ?(vtmp="$t") com e texpr t p =
 		| TTypeDecl _ -> assert false
 	in
 	let vtmp = alloc_var vtmp e.etype in
-	let var = mk (TVars [vtmp,Some e]) api.tvoid p in
+	let var = mk (TVars (vtmp,Some e)) api.tvoid p in
 	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

+ 3 - 5
dce.ml

@@ -292,11 +292,9 @@ and expr dce e =
 		field dce c "new" false;
 		List.iter (expr dce) el;
 		List.iter (mark_t dce e.epos) pl;
-	| TVars vl ->
-		List.iter (fun (v,e1) ->
-			opt (expr dce) e1;
-			mark_t dce e.epos v.v_type;
-		) vl;
+	| TVars (v,e1) ->
+		opt (expr dce) e1;
+		mark_t dce e.epos v.v_type;
 	| TCast(e, Some mt) ->
 		check_feature dce "typed_cast";
 		mark_mt dce mt;

+ 23 - 29
filters.ml

@@ -35,7 +35,7 @@ let mk_block_context com gen_temp =
 	let push e = block_el := e :: !block_el in
 	let declare_temp t eo p =
 		let v = gen_temp t in
-		let e = mk (TVars [v,eo]) com.basic.tvoid p in
+		let e = mk (TVars (v,eo)) com.basic.tvoid p in
 		push e;
 		mk (TLocal v) t p
 	in
@@ -189,18 +189,16 @@ let promote_complex_rhs ctx e =
 		let r = ref [] in
 		List.iter (fun e ->
 			match e.eexpr with
-			| TVars(vl) ->
-				List.iter (fun (v,eo) ->
-					match eo with
+			| TVars(v,eo) ->
+				begin match eo with
 					| Some e when is_complex e ->
 						r := (loop (fun e -> mk (TBinop(OpAssign,mk (TLocal v) v.v_type e.epos,e)) v.v_type e.epos) e)
-							:: ((mk (TVars [v,None]) ctx.basic.tvoid e.epos))
+							:: ((mk (TVars (v,None)) ctx.basic.tvoid e.epos))
 							:: !r
 					| Some e ->
-						r := (mk (TVars [v,Some (find e)]) ctx.basic.tvoid e.epos) :: !r
-					| None -> r := (mk (TVars [v,None]) ctx.basic.tvoid e.epos) :: !r
-
-				) vl
+						r := (mk (TVars (v,Some (find e))) ctx.basic.tvoid e.epos) :: !r
+					| None -> r := (mk (TVars (v,None)) ctx.basic.tvoid e.epos) :: !r
+				end
 			| _ -> r := (find e) :: !r
 		) el;
 		List.rev !r
@@ -274,15 +272,15 @@ let check_local_vars_init e =
 				if v.v_name = "this" then error "Missing this = value" e.epos
 				else error ("Local variable " ^ v.v_name ^ " used without being initialized") e.epos
 			end
-		| TVars vl ->
-			List.iter (fun (v,eo) ->
+		| TVars (v,eo) ->
+			begin
 				match eo with
 				| None ->
 					declared := v.v_id :: !declared;
 					vars := PMap.add v.v_id false !vars
 				| Some e ->
 					loop vars e
-			) vl
+			end
 		| TBlock el ->
 			let old = !declared in
 			let old_vars = !vars in
@@ -412,11 +410,9 @@ let rec local_usage f e =
 	match e.eexpr with
 	| TLocal v ->
 		f (Use v)
-	| TVars l ->
-		List.iter (fun (v,e) ->
-			(match e with None -> () | Some e -> local_usage f e);
-			f (Declare v);
-		) l
+	| TVars (v,eo) ->
+		(match eo with None -> () | Some e -> local_usage f e);
+		f (Declare v);
 	| TFunction tf ->
 		let cc f =
 			List.iter (fun (v,_) -> f (Declare v)) tf.tf_args;
@@ -478,7 +474,7 @@ let captured_vars com e =
 	let t = com.basic in
 
 	let rec mk_init av v pos =
-		mk (TVars [av,Some (mk (TArrayDecl [mk (TLocal v) v.v_type pos]) av.v_type pos)]) t.tvoid pos
+		mk (TVars (av,Some (mk (TArrayDecl [mk (TLocal v) v.v_type pos]) av.v_type pos))) t.tvoid pos
 
 	and mk_var v used =
 		let v2 = alloc_var v.v_name (PMap.find v.v_id used) in
@@ -487,14 +483,14 @@ let captured_vars com e =
 
 	and wrap used e =
 		match e.eexpr with
-		| TVars vl ->
-			let vl = List.map (fun (v,ve) ->
+		| TVars (v,ve) ->
+			let v,ve =
 				if PMap.mem v.v_id used then
 					v, Some (mk (TArrayDecl (match ve with None -> [] | Some e -> [wrap used e])) v.v_type e.epos)
 				else
 					v, (match ve with None -> None | Some e -> Some (wrap used e))
-			) vl in
-			{ e with eexpr = TVars vl }
+			 in
+			{ e with eexpr = TVars (v,ve) }
 		| TLocal v when PMap.mem v.v_id used ->
 			mk (TArray ({ e with etype = v.v_type },mk (TConst (TInt 0l)) t.tint e.epos)) e.etype e.epos
 		| TFor (v,it,expr) when PMap.mem v.v_id used ->
@@ -735,12 +731,10 @@ let rename_local_vars com e =
 	in
 	let rec loop e =
 		match e.eexpr with
-		| TVars l ->
-			List.iter (fun (v,eo) ->
-				if not cfg.pf_locals_scope then declare v e.epos;
-				(match eo with None -> () | Some e -> loop e);
-				if cfg.pf_locals_scope then declare v e.epos;
-			) l
+		| TVars (v,eo) ->
+			if not cfg.pf_locals_scope then declare v e.epos;
+			(match eo with None -> () | Some e -> loop e);
+			if cfg.pf_locals_scope then declare v e.epos;
 		| TFunction tf ->
 			let old = save() in
 			List.iter (fun (v,_) -> declare v e.epos) tf.tf_args;
@@ -976,7 +970,7 @@ let add_field_inits ctx t =
 					end else
 						eassign;
 			) inits in
-			let el = if !need_this then (mk (TVars([v, Some ethis])) ethis.etype ethis.epos) :: el else el in
+			let el = if !need_this then (mk (TVars((v, Some ethis))) ethis.etype ethis.epos) :: el else el in
 			match c.cl_constructor with
 			| None ->
 				let ct = TFun([],ctx.com.basic.tvoid) in

+ 8 - 11
genas3.ml

@@ -648,18 +648,15 @@ and gen_expr ctx e =
 	| TThrow e ->
 		spr ctx "throw ";
 		gen_value ctx e;
-	| TVars [] ->
-		()
-	| TVars vl ->
+	| TVars (v,eo) ->
 		spr ctx "var ";
-		concat ctx ", " (fun (v,eo) ->
-			print ctx "%s : %s" (s_ident v.v_name) (type_str ctx v.v_type e.epos);
-			match eo with
-			| None -> ()
-			| Some e ->
-				spr ctx " = ";
-				gen_value ctx e
-		) vl;
+		print ctx "%s : %s" (s_ident v.v_name) (type_str ctx v.v_type e.epos);
+		begin match eo with
+		| None -> ()
+		| Some e ->
+			spr ctx " = ";
+			gen_value ctx e
+		end
 	| TNew (c,params,el) ->
 		(match c.cl_path, params with
 		| (["flash"],"Vector"), [pt] -> print ctx "new Vector.<%s>(" (type_str ctx pt e.epos)

+ 29 - 35
gencpp.ml

@@ -803,8 +803,8 @@ let rec iter_retval f retval e =
 	| TCall (e,el) ->
 		f true e;
 		List.iter (f true) el
-	| TVars vl ->
-		List.iter (fun (_,e) -> match e with None -> () | Some e -> f true e) vl
+	| TVars (_,eo) ->
+		(match eo with None -> () | Some e -> f true e)
 	| TFunction fu ->
 		f false fu.tf_expr
 	| TIf (e,e1,e2) ->
@@ -892,15 +892,13 @@ let find_undeclared_variables_ctx ctx undeclared declarations this_suffix allow_
 	let output = ctx.ctx_output in
 	let rec find_undeclared_variables undeclared declarations this_suffix allow_this expression =
 		match expression.eexpr with
-		| TVars var_list ->
-			List.iter (fun (tvar, optional_init) ->
+		| TVars (tvar,optional_init) ->
 				Hashtbl.add declarations (keyword_remap tvar.v_name) ();
 				if (ctx.ctx_debug) then
 					output ("/* found var " ^ tvar.v_name ^ "*/ ");
-				match optional_init with
+				(match optional_init with
 				| Some expression -> find_undeclared_variables undeclared declarations this_suffix allow_this expression
-				| _ -> ()
-				) var_list
+				| _ -> ())
 		| TFunction func -> List.iter ( fun (tvar, opt_val) ->
 				if (ctx.ctx_debug) then
 					output ("/* found arg " ^ tvar.v_name ^ " = " ^ (type_string tvar.v_type) ^ " */ ");
@@ -1854,28 +1852,26 @@ and gen_expression ctx retval expression =
 			output ("function " ^ func_name ^ " not found.");
 		)
 
-	| TVars var_list ->
-		let count = ref (List.length var_list) in
-		List.iter (fun (tvar, optional_init) ->
-			if (retval && !count==1) then
-				(match optional_init with
-				| None -> output "null()"
-				| Some expression -> gen_expression ctx true expression )
-			else begin
-            let type_name = (type_string tvar.v_type) in
-				output (if type_name="Void" then "Dynamic" else type_name );
-				let name = (keyword_remap tvar.v_name) in
-				output (" " ^ name );
-				(match optional_init with
-				| None -> ()
-				| Some expression -> output " = "; gen_expression ctx true expression);
-				count := !count -1;
-            if (ctx.ctx_dump_stack_line) then
-				   output (";\t\tHX_STACK_VAR(" ^name ^",\""^ tvar.v_name ^"\")");
-				if (!count > 0) then begin output ";\n"; output_i "" end
-			end
-		) var_list
-	| TFor (tvar, init, loop) ->
+	| TVars (tvar,optional_init) ->
+		let count = ref 1 in (* TODO: this section can be simplified *)
+		if (retval && !count==1) then
+			(match optional_init with
+			| None -> output "null()"
+			| Some expression -> gen_expression ctx true expression )
+		else begin
+        let type_name = (type_string tvar.v_type) in
+			output (if type_name="Void" then "Dynamic" else type_name );
+			let name = (keyword_remap tvar.v_name) in
+			output (" " ^ name );
+			(match optional_init with
+			| None -> ()
+			| Some expression -> output " = "; gen_expression ctx true expression);
+			count := !count -1;
+        if (ctx.ctx_dump_stack_line) then
+			   output (";\t\tHX_STACK_VAR(" ^name ^",\""^ tvar.v_name ^"\")");
+			if (!count > 0) then begin output ";\n"; output_i "" end
+		end
+| TFor (tvar, init, loop) ->
 		output ("for(::cpp::FastIterator_obj< " ^  (type_string tvar.v_type) ^
              " > *__it = ::cpp::CreateFastIterator< "^(type_string tvar.v_type) ^ " >(");
 		gen_expression ctx true init;
@@ -2393,8 +2389,8 @@ let find_referenced_types ctx obj super_deps constructor_deps header_only for_de
                with Not_found -> ();
                end
 				(* Must visit type too, Type.iter will visit the expressions ... *)
-				| TVars var_list ->
-					List.iter (fun (v, _) -> visit_type v.v_type) var_list
+				| TVars (v,_) ->
+					 visit_type v.v_type
 				(* Must visit args too, Type.iter will visit the expressions ... *)
 				| TFunction func_def ->
 					List.iter (fun (v,_) -> visit_type v.v_type) func_def.tf_args;
@@ -4180,9 +4176,8 @@ class script_writer common_ctx ctx filename =
      (* TODO - lval op-assign local/member/array *)
      | TLocal var -> this#write ("VAR " ^ (string_of_int var.v_id) );
 
-     | TVars var_list ->
-         this#write ("TVARS " ^ (string_of_int (List.length var_list)) ^ "\n");
-         List.iter (fun (tvar, optional_init) ->
+     | TVars (tvar,optional_init) ->
+         this#write ("TVARS " ^ (string_of_int (1)) ^ "\n");
             this#write ("\t\t" ^ indent);
             (match optional_init with
             | None -> this#write ("VARDECL ");
@@ -4193,7 +4188,6 @@ class script_writer common_ctx ctx filename =
                       this#write (" " ^ (this#typeText init.etype));
                       this#write "\n";
                       this#checkCast tvar.v_type init false);
-         ) var_list
      | TNew (clazz,params,arg_list) ->
         this#write ("NEW " ^ (this#typeText (TInst(clazz,params))) ^ (string_of_int (List.length arg_list)) ^ "\n");
         List.iter this#gen_expression arg_list;

+ 5 - 8
genjs.ml

@@ -524,19 +524,16 @@ and gen_expr ctx e =
 	| TThrow e ->
 		spr ctx "throw ";
 		gen_value ctx e;
-	| TVars [] ->
-		()
-	| TVars vl ->
+	| TVars (v,eo) ->
 		spr ctx "var ";
-		concat ctx ", " (fun (v,e) ->
-			check_var_declaration v;
-			spr ctx (ident v.v_name);
-			match e with
+		check_var_declaration v;
+		spr ctx (ident v.v_name);
+		begin match eo with
 			| None -> ()
 			| Some e ->
 				spr ctx " = ";
 				gen_value ctx e
-		) vl;
+		end
 	| TNew (c,_,el) ->
 		print ctx "new %s(" (ctx.type_accessor (TClassDecl c));
 		concat ctx "," (gen_value ctx) el;

+ 5 - 5
genneko.ml

@@ -270,9 +270,9 @@ and gen_expr ctx e =
 		call p (field p (gen_type_path p c.cl_path) "new") (List.map (gen_expr ctx) params)
 	| TUnop (op,flag,e) ->
 		gen_unop ctx p op flag e
-	| TVars vl ->
-		(EVars (List.map (fun (v,e) ->
-			let e = (match e with
+	| TVars (v,eo) ->
+		(EVars (
+			let e = (match eo with
 				| None ->
 					if v.v_capture then
 						Some (call p (builtin p "array") [null p])
@@ -285,8 +285,8 @@ and gen_expr ctx e =
 					else
 						Some e
 			) in
-			v.v_name , e
-		) vl),p)
+			[v.v_name, e]
+		),p)
 	| TFunction f ->
 		let inits = List.fold_left (fun acc (a,c) ->
 			let acc = if a.v_capture then

+ 12 - 16
genphp.ml

@@ -1384,23 +1384,19 @@ and gen_expr ctx e =
 		spr ctx "throw new HException(";
 		gen_value ctx e;
 		spr ctx ")";
-	| TVars [] ->
-		()
-	| TVars vl ->
+	| TVars (v,eo) ->
 		spr ctx "$";
-		concat ctx ("; $") (fun (v,e) ->
-			let restore = save_locals ctx in
-			let n = define_local ctx v.v_name in
-			let restore2 = save_locals ctx in
-			restore();
-			(match e with
-			| None ->
-				print ctx "%s = null" (s_ident_local n)
-			| Some e ->
-				print ctx "%s = " (s_ident_local n);
-				gen_value ctx e);
-			restore2()
-		) vl;
+		let restore = save_locals ctx in
+		let n = define_local ctx v.v_name in
+		let restore2 = save_locals ctx in
+		restore();
+		(match eo with
+		| None ->
+			print ctx "%s = null" (s_ident_local n)
+		| Some e ->
+			print ctx "%s = " (s_ident_local n);
+			gen_value ctx e);
+		restore2()
 	| TNew (c,_,el) ->
 		(match c.cl_path, el with
 		| ([], "String"), _ ->

+ 3 - 4
genswf.ml

@@ -623,13 +623,12 @@ let build_dependencies t =
 			add_type v.v_type;
 			add_expr e1;
 			add_expr e2;
-		| TVars vl ->
-			List.iter (fun (v,e) ->
+		| TVars (v,eo) ->
 				add_type v.v_type;
-				match e with
+			begin match eo with
 				| None -> ()
 				| Some e -> add_expr e
-			) vl
+			end
 		| _ ->
 			Type.iter add_expr e
 	and add_field f =

+ 2 - 4
genswf8.ml

@@ -997,10 +997,8 @@ and gen_expr_2 ctx retval e =
 		let b = open_block ctx in
 		loop el;
 		b()
-	| TVars vl ->
-		List.iter (fun (v,e) ->
-			define_var ctx v (match e with None -> None | Some e -> Some (fun() -> gen_expr ctx true e))
-		) vl;
+	| TVars (v,eo) ->
+		define_var ctx v (match eo with None -> None | Some e -> Some (fun() -> gen_expr ctx true e));
 		if retval then push ctx [VNull]
 	| TArrayDecl el ->
 		List.iter (gen_expr ctx true) (List.rev el);

+ 8 - 10
genswf9.ml

@@ -1024,16 +1024,14 @@ let rec gen_expr_content ctx retval e =
 		let b = open_block ctx retval in
 		loop el;
 		b();
-	| TVars vl ->
-		List.iter (fun (v,ei) ->
-			define_local ctx v e.epos;
-			(match ei with
-			| None -> ()
-			| Some e ->
-				let acc = gen_local_access ctx v e.epos Write in
-				gen_expr ctx true e;
-				setvar ctx acc None)
-		) vl
+	| TVars (v,ei) ->
+		define_local ctx v e.epos;
+		(match ei with
+		| None -> ()
+		| Some e ->
+			let acc = gen_local_access ctx v e.epos Write in
+			gen_expr ctx true e;
+			setvar ctx acc None)
 	| TReturn None ->
 		write ctx HRetVoid;
 		ctx.infos.icond <- true;

+ 6 - 6
interp.ml

@@ -4469,11 +4469,11 @@ and encode_texpr e =
 			| TNew(c,pl,el) -> 10,[encode_clref c;encode_tparams pl;encode_texpr_list el]
 			| TUnop(op,flag,e1) -> 11,[encode_unop op;VBool (flag = Postfix);loop e1]
 			| TFunction func -> 12,[encode_tfunc func]
-			| TVars vl -> 13,[enc_array (List.map (fun (v,e) ->
+			| TVars (v,eo) -> 13,[
 				enc_obj [
 					"v",encode_tvar v;
-					"expr",vopt encode_texpr e
-				]) vl)]
+					"expr",vopt encode_texpr eo
+				]]
 			| TBlock el -> 14,[encode_texpr_list el]
 			| TFor(v,e1,e2) -> 15,[encode_tvar v;loop e1;loop e2]
 			| TIf(eif,ethen,eelse) -> 16,[loop eif;loop ethen;vopt encode_texpr eelse]
@@ -4635,7 +4635,7 @@ let rec decode_texpr v =
 		| 10, [c;tl;vl] -> TNew(decode_ref c,List.map decode_type (dec_array tl),List.map loop (dec_array vl))
 		| 11, [op;pf;v1] -> TUnop(decode_unop op,(if dec_bool pf then Postfix else Prefix),loop v1)
 		| 12, [f] -> TFunction(decode_tfunc f)
-		| 13, [vl] -> TVars(List.map (fun v -> decode_tvar (field v "v"),opt loop (field v "expr")) (dec_array vl))
+		| 13, [v;eo] -> TVars(decode_tvar v,opt loop eo)
 		| 14, [vl] -> TBlock(List.map loop (dec_array vl))
 		| 15, [v;v1;v2] -> TFor(decode_tvar v,loop v1,loop v2)
 		| 16, [vif;vthen;velse] -> TIf(loop vif,loop vthen,opt loop velse)
@@ -4864,8 +4864,8 @@ let rec make_ast e =
 	| TFunction f ->
 		let arg (v,c) = v.v_name, false, mk_ot v.v_type, (match c with None -> None | Some c -> Some (EConst (mk_const c),e.epos)) in
 		EFunction (None,{ f_params = []; f_args = List.map arg f.tf_args; f_type = mk_ot f.tf_type; f_expr = Some (make_ast f.tf_expr) })
-	| TVars vl ->
-		EVars (List.map (fun (v,e) -> v.v_name, mk_ot v.v_type, eopt e) vl)
+	| TVars (v,eo) ->
+		EVars ([v.v_name, mk_ot v.v_type, eopt eo])
 	| TBlock el -> EBlock (List.map make_ast el)
 	| TFor (v,it,e) ->
 		let ein = (EIn ((EConst (Ident v.v_name),it.epos),make_ast it),it.epos) in

+ 35 - 36
optimizer.ml

@@ -222,12 +222,9 @@ let rec type_inline ctx cf f ethis params tret config p force =
 			let l = read_local vthis in
 			l.i_read <- l.i_read + (if !in_loop then 2 else 1);
 			{ e with eexpr = TLocal l.i_subst }
-		| TVars vl ->
+		| TVars (v,eo) ->
 			has_vars := true;
-			let vl = List.map (fun (v,e) ->
-				(local v).i_subst,opt (map false) e
-			) vl in
-			{ e with eexpr = TVars vl }
+			{ e with eexpr = TVars ((local v).i_subst,opt (map false) eo)}
 		| TReturn eo when not !in_local_fun ->
 			if not term then error "Cannot inline a not final return" po;
 			(match eo with
@@ -385,7 +382,7 @@ let rec type_inline ctx cf f ethis params tret config p force =
 		| _ -> Type.map_expr inline_params e
 	in
 	let e = (if PMap.is_empty subst then e else inline_params e) in
-	let init = (match vars with [] -> None | l -> Some (mk (TVars (List.rev l)) ctx.t.tvoid p)) in
+	let init = match vars with [] -> None | l -> Some l in
 	(*
 		If we have local variables and returning a value, then this will result in
 		unoptimized JS code, so let's instead skip inlining.
@@ -424,8 +421,12 @@ let rec type_inline ctx cf f ethis params tret config p force =
 				{e with etype = tret}
 			| TBlock [e] , None -> wrap e
 			| _ , None -> wrap e
-			| TBlock l, Some init -> mk (TBlock (init :: l)) tret e.epos
-			| _, Some init -> mk (TBlock [init;e]) tret e.epos
+			| TBlock l, Some vl ->
+				let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) ctx.t.tvoid e.epos) vl in
+				mk (TBlock (el_v @ l)) tret e.epos
+			| _, Some vl ->
+				let el_v = List.map (fun (v,eo) -> mk (TVars (v,eo)) ctx.t.tvoid e.epos) vl in
+				mk (TBlock (el_v @ [e])) tret e.epos
 		) in
 		(* we need to replace type-parameters that were used in the expression *)
 		if not has_params then
@@ -473,20 +474,20 @@ let rec optimize_for_loop ctx i e1 e2 p =
 		let i = add_local ctx i pt in
 		let index = gen_local ctx t_int in
 		let arr, avars = (match e1.eexpr with
-			| TLocal _ -> e1, []
+			| TLocal _ -> e1, None
 			| _ ->
 				let atmp = gen_local ctx e1.etype in
-				mk (TLocal atmp) e1.etype e1.epos, [atmp,Some e1]
+				mk (TLocal atmp) e1.etype e1.epos, (Some (atmp,Some e1))
 		) in
 		let iexpr = mk (TLocal index) t_int p in
 		let e2 = type_expr ctx e2 NoValue in
-		let aget = mk (TVars [i,Some (mk (TArray (arr,iexpr)) pt p)]) t_void p in
+		let aget = mk (TVars (i,Some (mk (TArray (arr,iexpr)) pt p))) t_void p in
 		let incr = mk (TUnop (Increment,Prefix,iexpr)) t_int p in
 		let block = match e2.eexpr with
 			| TBlock el -> mk (TBlock (aget :: incr :: el)) t_void e2.epos
 			| _ -> mk (TBlock [aget;incr;e2]) t_void p
 		in
-		let ivar = index, Some (mk (TConst (TInt 0l)) t_int p) in
+		let ivar = Some (mk (TConst (TInt 0l)) t_int p) in
 		let elength = match follow e1.etype with
 			| TAbstract({a_impl = Some c},_) ->
 				let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
@@ -495,14 +496,15 @@ let rec optimize_for_loop ctx i e1 e2 p =
 				make_call ctx efield [arr] t_int e1.epos
 			| _ -> mk (mk_field arr "length") t_int p
 		in
-		lblock [
-			mk (TVars (ivar :: avars)) t_void p;
-			mk (TWhile (
+		let el = [mk (TWhile (
 				mk (TBinop (OpLt, iexpr, elength)) ctx.t.tbool p,
 				block,
 				NormalWhile
 			)) t_void p;
-		]
+		] in
+		let el = match avars with None -> el | Some (v,eo) -> (mk (TVars (v,eo)) t_void p) :: el in
+		let el = (mk (TVars (index,ivar)) t_void p) :: el in
+		lblock el
 	in
 	match e1.eexpr, follow e1.etype with
 	| TNew ({ cl_path = ([],"IntIterator") },[],[i1;i2]) , _ ->
@@ -527,7 +529,7 @@ let rec optimize_for_loop ctx i e1 e2 p =
 		check e2;
 		let etmp = mk (TLocal tmp) t_int p in
 		let incr = mk (TUnop (Increment,Postfix,etmp)) t_int p in
-		let init = mk (TVars [i,Some incr]) t_void p in
+		let init = mk (TVars (i,Some incr)) t_void p in
 		let block = match e2.eexpr with
 			| TBlock el -> mk (TBlock (init :: el)) t_void e2.epos
 			| _ -> mk (TBlock [init;e2]) t_void p
@@ -542,7 +544,7 @@ let rec optimize_for_loop ctx i e1 e2 p =
 		(match max with
 		| None ->
 			lblock [
-				mk (TVars [tmp,Some i1]) t_void p;
+				mk (TVars (tmp,Some i1)) t_void p;
 				mk (TWhile (
 					mk (TBinop (OpLt, etmp, i2)) ctx.t.tbool p,
 					block,
@@ -551,7 +553,8 @@ let rec optimize_for_loop ctx i e1 e2 p =
 			]
 		| Some max ->
 			lblock [
-				mk (TVars [tmp,Some i1;max,Some i2]) t_void p;
+				mk (TVars (tmp,Some i1)) t_void p;
+				mk (TVars (max,Some i2)) t_void p;
 				mk (TWhile (
 					mk (TBinop (OpLt, etmp, mk (TLocal max) t_int p)) ctx.t.tbool p,
 					block,
@@ -571,14 +574,14 @@ let rec 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 NoValue in
-		let evar = mk (TVars [i,Some (mk (mk_field cexpr "elt") t p)]) t_void 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 (mk_field 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,
@@ -1008,10 +1011,9 @@ let inline_constructors ctx e =
 	in
 	let rec find_locals e =
 		match e.eexpr with
-		| TVars vl ->
+		| TVars (v,eo) ->
 			Type.iter find_locals e;
-			List.iter (fun (v,e) ->
-				match e with
+			begin match eo with
 				| Some n ->
 					begin match get_inline_ctor_info n with
 					| Some (f,cst,c,pl) ->
@@ -1048,7 +1050,7 @@ let inline_constructors ctx e =
 						()
 					end
 				| None -> ()
-			) vl
+			end
 		| TField ({ eexpr = TLocal _ },FInstance (_,{ cf_kind = Var _ })) ->
 			()
 		| TLocal v when v.v_id < 0 ->
@@ -1076,19 +1078,16 @@ let inline_constructors ctx e =
 		) vars in
 		let rec subst e =
 			match e.eexpr with
-			| TVars vl ->
-				let rec loop acc vl =
-					match vl with
-					| [] -> List.rev acc
-					| (v,None) :: vl -> loop ((v,None) :: acc) vl
-					| (v,Some e) :: vl when v.v_id < 0 ->
+			| TVars (v,eo) ->
+				let v,eo = match eo with
+					| None -> (v,None)
+					| Some e when v.v_id < 0 ->
 						let vars, _ = PMap.find (-v.v_id) vfields in
-						loop (List.map (fun (v,e) -> v, Some (subst e)) vars @ acc) vl
-					| (v,Some e) :: vl ->
-						loop ((v,Some (subst e)) :: acc) vl
+						v, Some (subst e)
+					| Some e ->
+						v,Some (subst e)
 				in
-				let vl = loop [] vl in
-				mk (TVars vl) e.etype e.epos
+				mk (TVars (v,eo)) e.etype e.epos
 			| TField ({ eexpr = TLocal v },FInstance (_,cf)) when v.v_id < 0 ->
 				let _, vars = PMap.find (-v.v_id) vfields in
 				(try

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

@@ -251,7 +251,7 @@ enum TypedExprDef {
 	TNew(c:Ref<ClassType>, params: Array<Type>, el:Array<TypedExpr>);
 	TUnop(op:Expr.Unop, postFix:Bool, e:TypedExpr);
 	TFunction(tfunc:TFunc);
-	TVars(vl:Array<{v:TVar, expr:Null<TypedExpr>}>);
+	TVars(v:TVar, expr:Null<TypedExpr>);
 	TBlock(el:Array<TypedExpr>);
 	TFor(v:TVar, e1:TypedExpr, e2:TypedExpr);
 	TIf(econd:TypedExpr, eif:TypedExpr, eelse:Null<TypedExpr>);

+ 2 - 2
std/haxe/macro/TypedExprTools.hx

@@ -60,7 +60,7 @@ class TypedExprTools {
 			case TBlock(el): with(e, TBlock(el.map(f)));
 			case TObjectDecl(fl): with(e, TObjectDecl(fl.map(function(field) return { name: field.name, expr: f(field.expr) })));
 			case TCall(e1, el): with(e, TCall(f(e1), el.map(f)));
-			case TVars(vl): with(e, TVars(vl.map(function(v) return { v: v.v, expr: v.expr == null ? null : f(v.expr) })));
+			case TVars(v,eo): with(e, TVars(v, eo == null ? null : f(eo)));
 			case TFunction(fu): with(e, TFunction({ t: fu.t, args: fu.args, expr: f(fu.expr)}));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), f(e3)));
 			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)));
@@ -99,7 +99,7 @@ class TypedExprTools {
 			case TBlock(el): with(e, TBlock(el.map(f)), ft(e.t));
 			case TObjectDecl(fl): with(e, TObjectDecl(fl.map(function(field) return { name: field.name, expr: f(field.expr) })), ft(e.t));
 			case TCall(e1, el): with(e, TCall(f(e1), el.map(f)), ft(e.t));
-			case TVars(vl): with(e, TVars(vl.map(function(v) return { v: fv(v.v), expr: v.expr == null ? null : f(v.expr) })), ft(e.t));
+			case TVars(v,eo): with(e, TVars(fv(v), eo == null ? null : f(eo)), ft(e.t));
 			case TFunction(fu): with(e, TFunction({ t: ft(fu.t), args: fu.args.map(function(arg) return { v: fv(arg.v), value: arg.value }), expr: f(fu.expr)}), ft(e.t));
 			case TIf(e1, e2, e3): with(e, TIf(f(e1), f(e2), f(e3)), ft(e.t));
 			case TSwitch(e1, cases, e2): with(e, TSwitch(e1, cases.map(function(c) return { values: c.values, expr: f(c.expr) }), e2 == null ? null : f(e2)), ft(e.t));

+ 11 - 11
type.ml

@@ -114,7 +114,7 @@ and texpr_expr =
 	| TNew of tclass * tparams * texpr list
 	| TUnop of Ast.unop * Ast.unop_flag * texpr
 	| TFunction of tfunc
-	| TVars of (tvar * texpr option) list
+	| TVars of tvar * texpr option
 	| TBlock of texpr list
 	| TFor of tvar * texpr * texpr
 	| TIf of texpr * texpr * texpr option
@@ -1350,8 +1350,8 @@ let iter f e =
 	| TCall (e,el) ->
 		f e;
 		List.iter f el
-	| TVars vl ->
-		List.iter (fun (_,e) -> match e with None -> () | Some e -> f e) vl
+	| TVars (v,eo) ->
+		(match eo with None -> () | Some e -> f e)
 	| TFunction fu ->
 		f fu.tf_expr
 	| TIf (e,e1,e2) ->
@@ -1427,8 +1427,8 @@ let map_expr f e =
 		{ e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) }
 	| TCall (e1,el) ->
 		{ e with eexpr = TCall (f e1, List.map f el) }
-	| TVars vl ->
-		{ e with eexpr = TVars (List.map (fun (v,e) -> v , match e with None -> None | Some e -> Some (f e)) vl) }
+	| TVars (v,eo) ->
+		{ e with eexpr = TVars (v, match eo with None -> None | Some e -> Some (f e)) }
 	| TFunction fu ->
 		{ e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } }
 	| TIf (ec,e1,e2) ->
@@ -1505,8 +1505,8 @@ let map_expr_type f ft fv e =
 	| TCall (e1,el) ->
 		let e1 = f e1 in
 		{ e with eexpr = TCall (e1, List.map f el); etype = ft e.etype }
-	| TVars vl ->
-		{ e with eexpr = TVars (List.map (fun (v,e) -> fv v, match e with None -> None | Some e -> Some (f e)) vl); etype = ft e.etype }
+	| TVars (v,eo) ->
+		{ e with eexpr = TVars (fv v, match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype }
 	| TFunction fu ->
 		let fu = {
 			tf_expr = f fu.tf_expr;
@@ -1627,8 +1627,8 @@ let rec s_expr s_type e =
 	| TFunction f ->
 		let args = slist (fun (v,o) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in
 		sprintf "Function(%s) : %s = %s" args (s_type f.tf_type) (loop f.tf_expr)
-	| TVars vl ->
-		sprintf "Vars %s" (slist (fun (v,eo) -> sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match eo with None -> "" | Some e -> " = " ^ loop e)) vl)
+	| TVars (v,eo) ->
+		sprintf "Vars %s" (sprintf "%s : %s%s" (s_var v) (s_type v.v_type) (match eo with None -> "" | Some e -> " = " ^ loop e))
 	| TBlock el ->
 		sprintf "Block {\n%s}" (String.concat "" (List.map (fun e -> sprintf "%s;\n" (loop e)) el))
 	| TFor (v,econd,e) ->
@@ -1702,8 +1702,8 @@ let rec s_expr_pretty tabs s_type e =
 	| TFunction f ->
 		let args = slist (fun (v,o) -> sprintf "%s:%s%s" v.v_name (s_type v.v_type) (match o with None -> "" | Some c -> " = " ^ s_const c)) f.tf_args in
 		sprintf "function(%s) = %s" args (loop f.tf_expr)
-	| TVars vl ->
-		sprintf "var %s" (slist (fun (v,eo) -> sprintf "%s%s" v.v_name (match eo with None -> "" | Some e -> " = " ^ loop e)) vl)
+	| TVars (v,eo) ->
+		sprintf "var %s" (sprintf "%s%s" v.v_name (match eo with None -> "" | Some e -> " = " ^ loop e))
 	| TBlock el ->
 		let ntabs = tabs ^ "\t" in
 		let s = sprintf "{\n%s" (String.concat "" (List.map (fun e -> sprintf "%s%s;\n" ntabs (s_expr_pretty ntabs s_type e)) el)) in

+ 1 - 1
typeload.ml

@@ -1222,7 +1222,7 @@ let type_function ctx args ret fmode f do_display p =
 	locals();
 	let e = match ctx.curfun, ctx.vthis with
 		| (FunMember|FunConstructor), Some v ->
-			let ev = mk (TVars [v,Some (mk (TConst TThis) ctx.tthis p)]) ctx.t.tvoid p in
+			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) }
 			| _ -> mk (TBlock [ev;e]) e.etype p)

+ 16 - 15
typer.ml

@@ -1559,7 +1559,7 @@ let rec type_binop ctx op e1 e2 is_assign_op p =
 			unify ctx get.etype t p;
 			l();
 			mk (TBlock [
-				mk (TVars [v,Some e]) ctx.t.tvoid p;
+				mk (TVars (v,Some e)) ctx.t.tvoid p;
 				make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [t] t) p) [get] t p
 			]) t p
  		| AKUsing(ef,c,cf,et) ->
@@ -1578,7 +1578,7 @@ let rec type_binop ctx op e1 e2 is_assign_op p =
 			unify ctx get.etype ret p;
 			l();
 			mk (TBlock [
-				mk (TVars [v,Some et]) ctx.t.tvoid p;
+				mk (TVars (v,Some et)) ctx.t.tvoid p;
 				make_call ctx ef [ev;get] ret p
 			]) ret p
 		| AKAccess(ebase,ekey) ->
@@ -1595,7 +1595,7 @@ let rec type_binop ctx op e1 e2 is_assign_op p =
 					let save = save_locals ctx in
 					let v = gen_local ctx ekey.etype in
 					let e = mk (TLocal v) ekey.etype p in
-					e, fun () -> (save(); Some (mk (TVars [v,Some ekey]) ctx.t.tvoid p))
+					e, fun () -> (save(); Some (mk (TVars (v,Some ekey)) ctx.t.tvoid p))
 			in
 			let ast_call = ECall((EField(Interp.make_ast ebase,cf_get.cf_name),p),[Interp.make_ast ekey]),p in
 			let eget = type_binop ctx op ast_call e2 true p in
@@ -1943,7 +1943,7 @@ and type_unop ctx op flag e p =
 			unify ctx get.etype t p;
 			l();
 			mk (TBlock [
-				mk (TVars [v,Some e]) ctx.t.tvoid p;
+				mk (TVars (v,Some e)) ctx.t.tvoid p;
 				make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [t] t) p) [get] t p
 			]) t p
 		| Postfix ->
@@ -1954,7 +1954,8 @@ and type_unop ctx op flag e p =
 			unify ctx get.etype t p;
 			l();
 			mk (TBlock [
-				mk (TVars [v,Some e; v2,Some get]) ctx.t.tvoid p;
+				mk (TVars (v,Some e)) ctx.t.tvoid p;
+				mk (TVars (v2,Some get)) ctx.t.tvoid p;
 				make_call ctx (mk (TField (ev,quick_field_dynamic ev.etype ("set_" ^ cf.cf_name))) (tfun [plusone.etype] t) p) [plusone] t p;
 				ev2
 			]) t p
@@ -2236,9 +2237,9 @@ and type_vars ctx vl p in_block =
 	save();
 
 	match vl with
-	| [v] -> mk (TVars vl) ctx.t.tvoid p
+	| [v,eo] -> mk (TVars (v,eo)) ctx.t.tvoid p
 	| _ ->
-		let e = mk (TBlock (List.map (fun (v,e) -> (mk (TVars [v,e]) ctx.t.tvoid p)) vl)) ctx.t.tvoid p in
+		let e = mk (TBlock (List.map (fun (v,e) -> (mk (TVars (v,e)) ctx.t.tvoid p)) vl)) ctx.t.tvoid p in
 		mk (TMeta((Meta.MergeBlock,[],p), e)) e.etype e.epos
 
 and with_type_error ctx with_type msg p =
@@ -2511,7 +2512,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		unify ctx v.v_type ea.etype p;
 		let efor = type_expr ctx e NoValue in
 		mk (TBlock [
-			mk (TVars [v,Some ea]) ctx.t.tvoid p;
+			mk (TVars (v,Some ea)) ctx.t.tvoid p;
 			efor;
 			mk (TLocal v) v.v_type p;
 		]) v.v_type p
@@ -2558,7 +2559,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 				error "Expected a => b" (snd e)
 		) [] el in
 		let enew = mk (TNew(c,[tkey;tval],[])) tmap p in
-		let el = (mk (TVars [v,Some enew]) t_dynamic p) :: (List.rev el) in
+		let el = (mk (TVars (v,Some enew)) t_dynamic p) :: (List.rev el) in
 		mk (TBlock el) tmap p
 	| EArrayDecl el ->
 		let tp = (match with_type with
@@ -2646,13 +2647,13 @@ and type_expr ctx (e,p) (with_type:with_type) =
 					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,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 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
 					) in
 					mk (TBlock [
-						mk (TVars [tmp,Some e1]) ctx.t.tvoid p;
+						mk (TVars (tmp,Some e1)) ctx.t.tvoid p;
 						mk (TWhile (ehasnext,eblock,NormalWhile)) ctx.t.tvoid p
 					]) ctx.t.tvoid p
 				with Exit ->
@@ -2928,15 +2929,15 @@ and type_expr ctx (e,p) (with_type:with_type) =
 			let decl = (if is_rec then begin
 				if inline then display_error ctx "Inline function cannot be recursive" e.epos;
 				let vnew = add_local ctx v.v_name ft in
-				mk (TVars [vnew,Some (mk (TBlock [
-					mk (TVars [v,Some (mk (TConst TNull) ft p)]) ctx.t.tvoid p;
+				mk (TVars (vnew,Some (mk (TBlock [
+					mk (TVars (v,Some (mk (TConst TNull) ft p))) ctx.t.tvoid p;
 					mk (TBinop (OpAssign,mk (TLocal v) ft p,e)) ft p;
 					mk (TLocal v) ft p
-				]) ft p)]) ctx.t.tvoid p
+				]) ft p))) ctx.t.tvoid p
 			end else if inline then
 				mk (TBlock []) ctx.t.tvoid p (* do not add variable since it will be inlined *)
 			else
-				mk (TVars [v,Some e]) ctx.t.tvoid p
+				mk (TVars (v,Some e)) ctx.t.tvoid p
 			) in
 			if with_type <> NoValue && not inline then mk (TBlock [decl;mk (TLocal v) v.v_type p]) v.v_type p else decl)
 	| EUntyped e ->