|
@@ -21,6 +21,33 @@ open Type
|
|
|
open Common
|
|
|
open Typecore
|
|
|
|
|
|
+(* ---------------------------------------------------------------------- *)
|
|
|
+(* API OPTIMIZATIONS *)
|
|
|
+
|
|
|
+let has_side_effect e =
|
|
|
+ let rec loop e =
|
|
|
+ match e.eexpr with
|
|
|
+ | TConst _ | TLocal _ | TEnumField _ | TTypeExpr _ | TFunction _ -> ()
|
|
|
+ | TMatch _ | TNew _ | TCall _ | TClosure _ | TField _ | TArray _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
|
|
|
+ | TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
|
|
|
+ | TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TWhile _ | TFor _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TVars _ | TBlock _ | TObjectDecl _ -> Type.iter loop e
|
|
|
+ in
|
|
|
+ try
|
|
|
+ loop e; false
|
|
|
+ with Exit ->
|
|
|
+ true
|
|
|
+
|
|
|
+let api_inline ctx c field params p =
|
|
|
+ match c.cl_path, field, params with
|
|
|
+ | ([],"Type"),"enumIndex",[{ eexpr = TEnumField (en,f) }] ->
|
|
|
+ let c = (try PMap.find f en.e_constrs with Not_found -> assert false) in
|
|
|
+ Some (mk (TConst (TInt (Int32.of_int c.ef_index))) ctx.t.tint p)
|
|
|
+ | ([],"Type"),"enumIndex",[{ eexpr = TCall({ eexpr = TEnumField (en,f) },pl) }] when List.for_all (fun e -> not (has_side_effect e)) pl ->
|
|
|
+ let c = (try PMap.find f en.e_constrs with Not_found -> assert false) in
|
|
|
+ Some (mk (TConst (TInt (Int32.of_int c.ef_index))) ctx.t.tint p)
|
|
|
+ | _ ->
|
|
|
+ None
|
|
|
+
|
|
|
(* ---------------------------------------------------------------------- *)
|
|
|
(* INLINING *)
|
|
|
|
|
@@ -32,6 +59,17 @@ type in_local = {
|
|
|
}
|
|
|
|
|
|
let rec type_inline ctx cf f ethis params tret p force =
|
|
|
+ (* perform some specific optimization before we inline the call since it's not possible to detect at final optimization time *)
|
|
|
+ try
|
|
|
+ let cl = (match follow ethis.etype with
|
|
|
+ | TInst (c,_) -> c
|
|
|
+ | TAnon a -> (match !(a.a_status) with Statics c -> c | _ -> raise Exit)
|
|
|
+ | _ -> raise Exit
|
|
|
+ ) in
|
|
|
+ (match api_inline ctx cl cf.cf_name params p with
|
|
|
+ | None -> raise Exit
|
|
|
+ | Some e -> Some e)
|
|
|
+ with Exit ->
|
|
|
(* type substitution on both class and function type parameters *)
|
|
|
let has_params, map_type =
|
|
|
let rec get_params c pl =
|
|
@@ -698,6 +736,10 @@ let rec reduce_loop ctx e =
|
|
|
e
|
|
|
| _ -> e
|
|
|
)
|
|
|
+ | TCall ({ eexpr = TField ({ eexpr = TTypeExpr (TClassDecl c) },field) },params) ->
|
|
|
+ (match api_inline ctx c field params e.epos with
|
|
|
+ | None -> reduce_expr ctx e
|
|
|
+ | Some e -> reduce_loop ctx e)
|
|
|
| TCall ({ eexpr = TFunction func } as ef,el) ->
|
|
|
let cf = mk_field "" ef.etype e.epos in
|
|
|
let ethis = mk (TConst TThis) t_dynamic e.epos in
|