diff --git a/src/context/meta.ml b/src/context/meta.ml index 492206ede19..95512be5a44 100644 --- a/src/context/meta.ml +++ b/src/context/meta.ml @@ -162,7 +162,6 @@ type strict_meta = | TemplatedCall | ValueUsed | Volatile - | Unbound | UnifyMinDynamic | Unreflective | Unsafe @@ -360,7 +359,6 @@ let get_info = function | Transient -> ":transient",("Adds the 'transient' flag to the class field",[Platform Java; UsedOn TClassField]) | ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[UsedInternally]) | Volatile -> ":volatile",("",[Platforms [Java;Cs]]) - | Unbound -> ":unbound", ("Compiler internal to denote unbounded global variable",[UsedInternally]) | UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField]) | Unreflective -> ":unreflective",("",[Platform Cpp]) | Unsafe -> ":unsafe",("Declares a class, or a method with the C#'s 'unsafe' flag",[Platform Cs; UsedOnEither [TClass;TClassField]]) diff --git a/src/display/display.ml b/src/display/display.ml index 00b53cc62cc..6d2ee55436e 100644 --- a/src/display/display.ml +++ b/src/display/display.ml @@ -450,9 +450,9 @@ module Diagnostics = struct had_effect := true; | TLocal v when not (Meta.has Meta.UserVariable v.v_meta) -> () - | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ when not in_value -> + | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TIdent _ when not in_value -> no_effect e.epos; - | TConst _ | TLocal _ | TTypeExpr _ | TEnumParameter _ | TEnumIndex _ | TVar _ -> + | TConst _ | TLocal _ | TTypeExpr _ | TEnumParameter _ | TEnumIndex _ | TVar _ | TIdent _ -> () | TFunction tf -> loop false tf.tf_expr diff --git a/src/filters/tryCatchWrapper.ml b/src/filters/tryCatchWrapper.ml index d6e04af0719..34c1c11473e 100644 --- a/src/filters/tryCatchWrapper.ml +++ b/src/filters/tryCatchWrapper.ml @@ -127,11 +127,11 @@ let configure_cs com = | TInst (cl,_) -> is_parent base_exception cl | _ -> false in - let v_rethrow = alloc_unbound_var "__rethrow__" t_dynamic null_pos in + let e_rethrow = mk (TIdent "__rethrow__") t_dynamic null_pos in let should_wrap t = not (is_exception t) in let wrap_throw expr = match expr.eexpr with - | TLocal { v_name = "__rethrow__" } -> + | TIdent "__rethrow__" -> make_throw expr expr.epos | _ -> let e_hxexception = make_static_this hx_exception expr.epos in @@ -139,7 +139,7 @@ let configure_cs com = make_throw e_wrap expr.epos in let unwrap_expr local_to_unwrap = Codegen.field (mk_cast local_to_unwrap hx_exception_t local_to_unwrap.epos) "obj" t_dynamic local_to_unwrap.epos in - let rethrow_expr rethrow = make_throw (make_local v_rethrow rethrow.epos) rethrow.epos in + let rethrow_expr rethrow = make_throw e_rethrow rethrow.epos in let catch_map v e = let e_exc = make_static_this exc_cl e.epos in let e_field = Codegen.field e_exc "exception" base_exception_t e.epos in diff --git a/src/generators/codegen.ml b/src/generators/codegen.ml index 25b04f8cc6f..81381280aed 100644 --- a/src/generators/codegen.ml +++ b/src/generators/codegen.ml @@ -531,7 +531,7 @@ let rec constructor_side_effects e = | TBinop _ | TTry _ | TIf _ | TBlock _ | TVar _ | TFunction _ | TArrayDecl _ | TObjectDecl _ | TParenthesis _ | TTypeExpr _ | TLocal _ | TMeta _ - | TConst _ | TContinue | TBreak | TCast _ -> + | TConst _ | TContinue | TBreak | TCast _ | TIdent _ -> try Type.iter (fun e -> if constructor_side_effects e then raise Exit) e; false; diff --git a/src/generators/genas3.ml b/src/generators/genas3.ml index ef4c4af1296..a140953a0ef 100644 --- a/src/generators/genas3.ml +++ b/src/generators/genas3.ml @@ -430,32 +430,32 @@ let rec gen_call ctx e el r = spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; - | TLocal { v_name = "__is__" } , [e1;e2] -> + | TIdent "__is__" , [e1;e2] -> gen_value ctx e1; spr ctx " is "; gen_value ctx e2; - | TLocal { v_name = "__in__" } , [e1;e2] -> + | TIdent "__in__" , [e1;e2] -> spr ctx "("; gen_value ctx e1; spr ctx " in "; gen_value ctx e2; spr ctx ")" - | TLocal { v_name = "__as__" }, [e1;e2] -> + | TIdent "__as__", [e1;e2] -> gen_value ctx e1; spr ctx " as "; gen_value ctx e2; - | TLocal { v_name = "__int__" }, [e] -> + | TIdent "__int__", [e] -> spr ctx "int("; gen_value ctx e; spr ctx ")"; - | TLocal { v_name = "__float__" }, [e] -> + | TIdent "__float__", [e] -> spr ctx "Number("; gen_value ctx e; spr ctx ")"; - | TLocal { v_name = "__typeof__" }, [e] -> + | TIdent "__typeof__", [e] -> spr ctx "typeof "; gen_value ctx e; - | TLocal { v_name = "__keys__" }, [e] -> + | TIdent "__keys__", [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; @@ -463,7 +463,7 @@ let rec gen_call ctx e el r = print ctx "for(var %s : String in " tmp; gen_value ctx e; print ctx ") %s.push(%s)" ret.v_name tmp; - | TLocal { v_name = "__hkeys__" }, [e] -> + | TIdent "__hkeys__", [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; @@ -471,7 +471,7 @@ let rec gen_call ctx e el r = print ctx "for(var %s : String in " tmp; gen_value ctx e; print ctx ") %s.push(%s.substr(1))" ret.v_name tmp; - | TLocal { v_name = "__foreach__" }, [e] -> + | TIdent "__foreach__", [e] -> let ret = (match ctx.in_value with None -> assert false | Some r -> r) in print ctx "%s = new Array()" ret.v_name; newline ctx; @@ -479,22 +479,22 @@ let rec gen_call ctx e el r = print ctx "for each(var %s : * in " tmp; gen_value ctx e; print ctx ") %s.push(%s)" ret.v_name tmp; - | TLocal { v_name = "__new__" }, e :: args -> + | TIdent "__new__", e :: args -> spr ctx "new "; gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) args; spr ctx ")"; - | TLocal { v_name = "__delete__" }, [e;f] -> + | TIdent "__delete__", [e;f] -> spr ctx "delete("; gen_value ctx e; spr ctx "["; gen_value ctx f; spr ctx "]"; spr ctx ")"; - | TLocal { v_name = "__unprotect__" }, [e] -> + | TIdent "__unprotect__", [e] -> gen_value ctx e - | TLocal { v_name = "__vector__" }, [e] -> + | TIdent "__vector__", [e] -> spr ctx (type_str ctx r e.epos); spr ctx "("; gen_value ctx e; @@ -592,7 +592,7 @@ and gen_expr ctx e = gen_constant ctx e.epos c | TLocal v -> spr ctx (s_ident v.v_name) - | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }) -> + | TArray ({ eexpr = TIdent "__global__" },{ eexpr = TConst (TString s) }) -> let path = Ast.parse_path s in spr ctx (s_path ctx false path e.epos) | TArray (e1,e2) -> @@ -811,6 +811,8 @@ and gen_expr ctx e = end | TCast (e1,Some t) -> gen_expr ctx (Codegen.default_cast ctx.inf.com e1 t e.etype e.epos) + | TIdent s -> + spr ctx s and gen_block_element ctx e = match e.eexpr with | TObjectDecl fl -> @@ -872,7 +874,7 @@ and gen_value ctx e = ) in match e.eexpr with - | TCall ({ eexpr = TLocal { v_name = "__keys__" } },_) | TCall ({ eexpr = TLocal { v_name = "__hkeys__" } },_) -> + | TCall ({ eexpr = TIdent "__keys__" },_) | TCall ({ eexpr = TIdent "__hkeys__" },_) -> let v = value true in gen_expr ctx e; v() @@ -890,7 +892,8 @@ and gen_value ctx e = | TCall _ | TNew _ | TUnop _ - | TFunction _ -> + | TFunction _ + | TIdent _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 diff --git a/src/generators/gencommon.ml b/src/generators/gencommon.ml index 657935bbc21..94b54059776 100644 --- a/src/generators/gencommon.ml +++ b/src/generators/gencommon.ml @@ -124,8 +124,7 @@ let mk_local = ExprBuilder.make_local (* the undefined is a special var that works like null, but can have special meaning *) let undefined = - let v_undefined = alloc_var "__undefined__" t_dynamic in - (fun pos -> ExprBuilder.make_local v_undefined pos) + (fun pos -> mk (TIdent "__undefined__") t_dynamic pos) let path_of_md_def md_def = match md_def.m_types with @@ -986,9 +985,8 @@ let get_real_fun gen t = | TFun(args,t) -> TFun(List.map (fun (n,o,t) -> n,o,gen.greal_type t) args, gen.greal_type t) | _ -> t -let v_nativearray = alloc_var "__array__" t_dynamic let mk_nativearray_decl gen t el pos = - mk (TCall (mk_local v_nativearray pos, el)) (gen.gclasses.nativearray t) pos + mk (TCall (mk (TIdent "__array__") t_dynamic pos, el)) (gen.gclasses.nativearray t) pos let ensure_local com block name e = match e.eexpr with diff --git a/src/generators/gencommon/castDetect.ml b/src/generators/gencommon/castDetect.ml index d47df4244fd..60d86b1dafc 100644 --- a/src/generators/gencommon/castDetect.ml +++ b/src/generators/gencommon/castDetect.ml @@ -782,7 +782,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist let pos = (!ef).epos in ef := { eexpr = TCall( - { eexpr = TLocal(alloc_var "__as__" t_dynamic); etype = t_dynamic; epos = pos }, + { eexpr = TIdent "__as__"; etype = t_dynamic; epos = pos }, [!ef]); etype = TInst(declared_cl,List.map (apply_params cl.cl_params params) tl); epos = pos @@ -1029,7 +1029,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete handle e t real_t | TCast( { eexpr = TConst TNull }, _ ) -> { e with eexpr = TConst TNull } - | TCast( { eexpr = TCall( { eexpr = TLocal { v_name = "__delegate__" } } as local, [del] ) } as e2, _) -> + | TCast( { eexpr = TCall( { eexpr = TIdent "__delegate__" } as local, [del] ) } as e2, _) -> { e with eexpr = TCast({ e2 with eexpr = TCall(local, [Type.map_expr run del]) }, None) } | TBinop ( (Ast.OpAssign | Ast.OpAssignOp _ as op), e1, e2 ) -> @@ -1060,7 +1060,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete in let base_type = List.hd base_type in { e with eexpr = TArrayDecl( List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et } - | TCall ({ eexpr = TLocal { v_name = "__array__" } } as arr_local, el) -> + | TCall ({ eexpr = TIdent "__array__" } as arr_local, el) -> let et = e.etype in let base_type = match follow et with | TInst(cl, bt) -> gen.greal_type_param (TClassDecl cl) bt @@ -1068,7 +1068,7 @@ let configure gen ?(overloads_cast_to_base = false) maybe_empty_t calls_paramete in let base_type = List.hd base_type in { e with eexpr = TCall(arr_local, List.map (fun e -> handle (run e) base_type e.etype) el ); etype = et } - | TCall( ({ eexpr = TLocal v } as local), params ) when String.get v.v_name 0 = '_' && String.get v.v_name 1 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> + | TCall( ({ eexpr = TIdent s } as local), params ) when String.get s 0 = '_' && String.get s 1 = '_' && Hashtbl.mem gen.gspecial_vars s -> { e with eexpr = TCall(local, List.map (fun e -> (match e.eexpr with TBlock _ -> in_value := false | _ -> ()); run e) params) } | TCall( ({ eexpr = TField(ef, f) }) as e1, elist ) -> handle_type_parameter gen (Some e) (e1) (run ef) ~clean_ef:ef ~overloads_cast_to_base:overloads_cast_to_base f (List.map run elist) calls_parameters_explicitly diff --git a/src/generators/gencommon/classInstance.ml b/src/generators/gencommon/classInstance.ml index 7d5eb203624..13588f5557a 100644 --- a/src/generators/gencommon/classInstance.ml +++ b/src/generators/gencommon/classInstance.ml @@ -32,10 +32,9 @@ open Gencommon var x = typeof(MyClass); *) let add_typeof = - let v_typeof = alloc_var "__typeof__" t_dynamic in let rec run e = match e.eexpr with - | TCall (({ eexpr = TLocal { v_name = ("__is__" | "__as__" | "__typeof__") } } as elocal), args) -> + | TCall (({ eexpr = TIdent ("__is__" | "__as__" | "__typeof__") } as elocal), args) -> let args = List.map (fun e -> match e.eexpr with TTypeExpr _ -> e | _ -> run e) args in { e with eexpr = TCall (elocal, args) } | TField ({ eexpr = TTypeExpr _ }, _) -> @@ -45,7 +44,7 @@ let add_typeof = | None -> Type.map_expr run e | Some t -> { e with eexpr = TField ({ ef with eexpr = TTypeExpr t }, f)}) | TTypeExpr _ -> - { e with eexpr = TCall (mk_local v_typeof e.epos, [e]) } + { e with eexpr = TCall (mk (TIdent "__typeof__") t_dynamic e.epos, [e]) } | _ -> Type.map_expr run e in diff --git a/src/generators/gencommon/closuresToClass.ml b/src/generators/gencommon/closuresToClass.ml index 9f0b9d761c7..884e4f45270 100644 --- a/src/generators/gencommon/closuresToClass.ml +++ b/src/generators/gencommon/closuresToClass.ml @@ -145,7 +145,7 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu let info = ref null_map_info in let rec run e = match e.eexpr with - | TCast({ eexpr = TCall({ eexpr = TLocal{ v_name = "__delegate__" } } as local, [del] ) } as e2, _) -> + | TCast({ eexpr = TCall({ eexpr = TIdent "__delegate__" } as local, [del] ) } as e2, _) -> let e2 = { e2 with etype = e.etype } in let replace_delegate ex = { e with eexpr = TCast({ e2 with eexpr = TCall(local, [ex]) }, None) } @@ -174,7 +174,7 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu gen.gcon.error "This delegate construct is unsupported" e.epos; replace_delegate (run clean)) - | TCall(({ eexpr = TLocal{ v_name = "__unsafe__" } } as local), [arg]) -> + | TCall(({ eexpr = TIdent "__unsafe__" } as local), [arg]) -> let old = !info in info := { !info with in_unsafe = true }; let arg2 = run arg in @@ -186,7 +186,7 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu | Some tparam_anon_decl -> (match (vv, ve) with | ({ v_extra = Some( _ :: _, _) } as v), Some ({ eexpr = TFunction tf } as f) - | ({ v_extra = Some( _ :: _, _) } as v), Some { eexpr = TArrayDecl([{ eexpr = TFunction tf } as f]) | TCall({ eexpr = TLocal { v_name = "__array__" } }, [{ eexpr = TFunction tf } as f]) } -> (* captured transformation *) + | ({ v_extra = Some( _ :: _, _) } as v), Some { eexpr = TArrayDecl([{ eexpr = TFunction tf } as f]) | TCall({ eexpr = TIdent "__array__" }, [{ eexpr = TFunction tf } as f]) } -> (* captured transformation *) ignore(tparam_anon_decl v f { tf with tf_expr = run tf.tf_expr }); { e with eexpr = TBlock([]) } | _ -> @@ -234,7 +234,7 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu handle_anon_func e { tf with tf_expr = run tf.tf_expr } !info None | TCall({ eexpr = TConst(TSuper) }, _) -> Type.map_expr run e - | TCall({ eexpr = TLocal(v) }, args) when String.get v.v_name 0 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> + | TCall({ eexpr = TIdent s }, args) when String.get s 0 = '_' && Hashtbl.mem gen.gspecial_vars s -> Type.map_expr run e | TCall(tc,params) -> let i = ref 0 in diff --git a/src/generators/gencommon/enumToClass2.ml b/src/generators/gencommon/enumToClass2.ml index 3821feaf369..d39771c6c9c 100644 --- a/src/generators/gencommon/enumToClass2.ml +++ b/src/generators/gencommon/enumToClass2.ml @@ -208,7 +208,7 @@ module EnumToClass2Modf = struct begin let other_v = alloc_var "other" t_dynamic in let eother_local = mk_local other_v pos in - let eas = mk_local (alloc_var "__as__" t_dynamic) pos in + let eas = mk (TIdent "__as__") t_dynamic pos in let ecast = mk (TCall(eas,[eother_local])) cl_ctor_t pos in let equals_exprs = ref (List.rev [ @@ -338,7 +338,6 @@ end;; module EnumToClass2Exprf = struct let init com ec_tbl mk_enum_index_call = - let v_as = alloc_var "__as__" t_dynamic in let rec run e = let get_converted_enum_classes et = let en = match follow et with @@ -374,7 +373,7 @@ module EnumToClass2Exprf = struct let f = { f with etype = TInst(cl_enum, []) } in let cl_ctor = PMap.find ef.ef_name classes.ctors in - let ecast = mk (TCall (mk_local v_as f.epos, [f])) (TInst (cl_ctor, [])) f.epos in + let ecast = mk (TCall (mk (TIdent "__as__") t_dynamic f.epos, [f])) (TInst (cl_ctor, [])) f.epos in (match ef.ef_type with | TFun (params, _) -> diff --git a/src/generators/gencommon/expressionUnwrap.ml b/src/generators/gencommon/expressionUnwrap.ml index 6061bc86460..e2d3142b32e 100644 --- a/src/generators/gencommon/expressionUnwrap.ml +++ b/src/generators/gencommon/expressionUnwrap.ml @@ -222,6 +222,7 @@ let rec shallow_expr_type expr : shallow_expr_type = | _ -> Both expr) | TConst _ | TLocal _ + | TIdent _ | TArray _ | TBinop _ | TField _ @@ -257,7 +258,8 @@ and expr_kind expr = | TConst _ | TLocal _ | TFunction _ - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> KNoSideEffects | TCall (ecall, params) -> aggregate false (ecall :: params) @@ -575,7 +577,7 @@ let configure gen = let rec process_statement e = let e = no_paren e in match e.eexpr, shallow_expr_type e with - | TCall( { eexpr = TLocal v } as elocal, elist ), _ when String.get v.v_name 0 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name -> + | TCall( { eexpr = TIdent s } as elocal, elist ), _ when String.get s 0 = '_' && Hashtbl.mem gen.gspecial_vars s -> new_block := { e with eexpr = TCall( elocal, List.map (fun e -> match e.eexpr with | TBlock _ -> traverse e diff --git a/src/generators/gencommon/filterClosures.ml b/src/generators/gencommon/filterClosures.ml index a86731a099b..c28b5fed9da 100644 --- a/src/generators/gencommon/filterClosures.ml +++ b/src/generators/gencommon/filterClosures.ml @@ -49,7 +49,7 @@ let configure gen (should_change:texpr->string->bool) (filter:texpr->texpr->stri (match clos with | Some (clos, e1, s) -> { e with eexpr = TCall({ clos with eexpr = TClosure(run e1, s) }, List.map run args ) } | None -> Type.map_expr run e)*) - | TCall({ eexpr = TLocal{ v_name = "__delegate__" } } as local, [del]) -> + | TCall({ eexpr = TIdent "__delegate__" } as local, [del]) -> { e with eexpr = TCall(local, [Type.map_expr run del]) } | TCall(({ eexpr = TField(_, _) } as ef), params) -> { e with eexpr = TCall(Type.map_expr run ef, List.map run params) } diff --git a/src/generators/gencommon/initFunction.ml b/src/generators/gencommon/initFunction.ml index d33ee116f5f..a420d01d9da 100644 --- a/src/generators/gencommon/initFunction.ml +++ b/src/generators/gencommon/initFunction.ml @@ -38,7 +38,7 @@ let ensure_simple_expr com e = match e.eexpr with | TConst _ | TLocal _ | TArray _ | TBinop _ | TField _ | TTypeExpr _ | TParenthesis _ | TCast _ | TMeta _ - | TCall _ | TNew _ | TUnop _ -> + | TCall _ | TNew _ | TUnop _ | TIdent _ -> Type.iter iter e | _ -> print_endline (debug_expr e); diff --git a/src/generators/gencommon/realTypeParams.ml b/src/generators/gencommon/realTypeParams.ml index 35c1b14313d..3f0e50b9e7c 100644 --- a/src/generators/gencommon/realTypeParams.ml +++ b/src/generators/gencommon/realTypeParams.ml @@ -473,8 +473,7 @@ struct in let mk_typehandle = - let thandle = alloc_var "__typeof__" t_dynamic in - (fun cl -> mk (TCall (mk_local thandle pos, [ExprBuilder.make_static_this cl pos])) t_dynamic pos) + (fun cl -> mk (TCall (mk (TIdent "__typeof__") t_dynamic pos, [ExprBuilder.make_static_this cl pos])) t_dynamic pos) in let mk_eq cl1 cl2 = binop OpEq (mk_typehandle cl1) (mk_typehandle cl2) basic.tbool pos diff --git a/src/generators/gencommon/reflectionCFs.ml b/src/generators/gencommon/reflectionCFs.ml index ea7fb362d66..24799e114f4 100644 --- a/src/generators/gencommon/reflectionCFs.ml +++ b/src/generators/gencommon/reflectionCFs.ml @@ -663,7 +663,7 @@ let implement_dynamic_object_ctor ctx cl = tf_args = []; tf_expr = { eexpr = TBlock(List.map (fun (f,t) -> - { eexpr = TBinop(Ast.OpAssign, mk_this f t,{ eexpr = TCall(mk_local v_nativearray pos, []); etype = t; epos = pos; }); etype = t; epos = pos } + { eexpr = TBinop(Ast.OpAssign, mk_this f t,{ eexpr = TCall(mk (TIdent "__array__") t_dynamic pos, []); etype = t; epos = pos; }); etype = t; epos = pos } ) fields); etype = basic.tvoid; epos = pos; @@ -766,7 +766,7 @@ let implement_dynamics ctx cl = ] in (if cl.cl_path <> (["haxe"; "lang"], "DynamicObject") then - List.iter (fun cf -> cf.cf_expr <- Some { eexpr = TCall(mk_local v_nativearray pos, []); etype = cf.cf_type; epos = cf.cf_pos }) new_fields + List.iter (fun cf -> cf.cf_expr <- Some { eexpr = TCall(mk (TIdent "__array__") t_dynamic pos, []); etype = cf.cf_type; epos = cf.cf_pos }) new_fields ); let new_fields = diff --git a/src/generators/gencommon/unreachableCodeEliminationSynf.ml b/src/generators/gencommon/unreachableCodeEliminationSynf.ml index 17629c45944..26b0588a4a4 100644 --- a/src/generators/gencommon/unreachableCodeEliminationSynf.ml +++ b/src/generators/gencommon/unreachableCodeEliminationSynf.ml @@ -76,15 +76,14 @@ let init com java_mode = | _ -> expr, kind in - let sbreak = alloc_var "__sbreak__" t_dynamic in - let mk_sbreak = mk_local sbreak in + let mk_sbreak = mk (TIdent "__sbreak__") t_dynamic in let rec has_fallback expr = match expr.eexpr with | TBlock(bl) -> (match List.rev bl with - | { eexpr = TLocal { v_name = "__fallback__" } } :: _ -> true + | { eexpr = TIdent "__fallback__" } :: _ -> true | ({ eexpr = TBlock(_) } as bl) :: _ -> has_fallback bl | _ -> false) - | TLocal { v_name = "__fallback__" } -> true + | TIdent "__fallback__" -> true | _ -> false in @@ -105,7 +104,7 @@ let init com java_mode = | TReturn _ | TThrow _ -> expr, BreaksFunction | TContinue -> expr, BreaksLoop | TBreak -> has_break := true; expr, BreaksLoop - | TCall( { eexpr = TLocal { v_name = "__goto__" } }, _ ) -> expr, BreaksLoop + | TCall( { eexpr = TIdent "__goto__" }, _ ) -> expr, BreaksLoop | TBlock bl -> let new_block = ref [] in diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 172c55382e6..a7582d685f6 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1188,7 +1188,7 @@ let rec is_dynamic_in_cpp ctx expr = | TCall(func,args) -> let is_IaCall = (match (remove_parens_cast func).eexpr with - | TField ( { eexpr = TLocal { v_name = "__global__" }}, field ) -> false + | TField ( { eexpr = TIdent "__global__" }, field ) -> false | TField (obj,FStatic (class_def,field) ) when is_real_function field -> false | TField (obj,FInstance (_,_,field) ) when (is_this obj) && (is_real_function field) -> false | TField (obj,FInstance (_,_,field) ) when is_super obj -> false @@ -1208,7 +1208,7 @@ let rec is_dynamic_in_cpp ctx expr = ); | TParenthesis(expr) | TMeta(_,expr) -> is_dynamic_in_cpp ctx expr | TCast (e,None) -> (type_string expr.etype) = "Dynamic" - | TLocal { v_name = "__global__" } -> false + | TIdent "__global__" -> false | TConst TNull -> true | _ -> false (* others ? *) ) in @@ -2444,7 +2444,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TConst x -> cpp_const_type x - | TLocal { v_name = "__global__" } -> + | TIdent "__global__" -> CppClassOf(([],""),false), TCppGlobal | TLocal tvar -> @@ -2461,6 +2461,20 @@ let retype_expression ctx request_type function_args function_type expression_tr CppGlobal(name), cpp_type_of tvar.v_type end + | TIdent name -> + let tvar = alloc_var name expr.etype expr.epos in + if (Hashtbl.mem !declarations name) then begin + (*print_endline ("Using existing tvar " ^ tvar.v_name);*) + CppVar(VarLocal(tvar)), cpp_type_of tvar.v_type + end else begin + (*print_endline ("Missing tvar " ^ tvar.v_name);*) + Hashtbl.replace !undeclared name tvar; + if tvar.v_capture then + CppVar(VarClosure(tvar)), cpp_type_of tvar.v_type + else + CppGlobal(name), cpp_type_of tvar.v_type + end + | TBreak -> if forCppia then CppBreak, TCppVoid @@ -2641,7 +2655,7 @@ let retype_expression ctx request_type function_args function_type expression_tr CppEnumField(enum, enum_field), TCppEnum(enum) ) - | TCall( {eexpr = TLocal { v_name = "__cpp__" }}, arg_list ) -> + | TCall( {eexpr = TIdent "__cpp__"}, arg_list ) -> let cppExpr = match arg_list with | [{ eexpr = TConst (TString code) }] -> CppCode(code, []) | ({ eexpr = TConst (TString code) }) :: remaining -> @@ -7402,7 +7416,7 @@ class script_writer ctx filename asciiOut = let argN = (string_of_int (List.length arg_list)) ^ " " in let gen_call () = (match (remove_parens_cast func).eexpr with - | TField ( { eexpr = TLocal { v_name = "__global__" }}, field ) -> + | TField ( { eexpr = TIdent "__global__" }, field ) -> this#write ( (this#op IaCallGlobal) ^ (this#stringText (field_name field)) ^ argN ^ (this#commentOf (field_name field)) ^ "\n"); | TField (obj,FStatic (class_def,field) ) when is_real_function field -> this#write ( (this#op IaCallStatic) ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) ^ @@ -7594,6 +7608,7 @@ class script_writer ctx filename asciiOut = | TCast (cast,_) -> this#checkCast expression.etype cast true true; | TParenthesis _ -> abort "Unexpected parens" expression.epos | TMeta(_,_) -> abort "Unexpected meta" expression.epos + | TIdent _ -> abort "Unexpected ident" expression.epos ); this#end_expr; (* } *) diff --git a/src/generators/gencs.ml b/src/generators/gencs.ml index a1da0cb618a..040de889cdb 100644 --- a/src/generators/gencs.ml +++ b/src/generators/gencs.ml @@ -107,7 +107,7 @@ let rec is_null t = let rec get_ptr e = match e.eexpr with | TParenthesis e | TMeta(_,e) | TCast(e,_) -> get_ptr e - | TCall( { eexpr = TLocal({ v_name = "__ptr__" }) }, [ e ] ) -> + | TCall( { eexpr = TIdent "__ptr__" }, [ e ] ) -> Some e | _ -> None @@ -168,8 +168,6 @@ struct let basic = gen.gcon.basic in let uint = match get_type gen ([], "UInt") with | TTypeDecl t -> TType(t, []) | TAbstractDecl a -> TAbstract(a, []) | _ -> assert false in - let is_var = alloc_var "__is__" t_dynamic in - let rec run e = match e.eexpr with (* Std.is() *) @@ -184,7 +182,7 @@ struct ) -> let md = change_md md in let mk_is obj md = - { e with eexpr = TCall( { eexpr = TLocal is_var; etype = t_dynamic; epos = e.epos }, [ + { e with eexpr = TCall( { eexpr = TIdent "__is__"; etype = t_dynamic; epos = e.epos }, [ obj; { eexpr = TTypeExpr md; etype = t_dynamic (* this is after all a syntax filter *); epos = e.epos } ] ) } @@ -361,7 +359,6 @@ struct let is_cl t = match gen.greal_type t with | TInst ( { cl_path = (["System"], "Type") }, [] ) -> true | _ -> false in - let as_var = alloc_var "__as__" t_dynamic in let fast_cast = Common.defined gen.gcon Define.FastCast in let rec run e = @@ -458,14 +455,14 @@ struct if is_cs_basic_type (gen.greal_type e.etype) || is_tparam (gen.greal_type e.etype) then { e with eexpr = TCast(run expr, Some(TClassDecl null_class)) } else - { e with eexpr = TCall(mk_local as_var e.epos, [run expr]) } + { e with eexpr = TCall(mk (TIdent "__as__") t_dynamic e.epos, [run expr]) } | TCast(expr, _) when (is_string e.etype) && (not (is_string expr.etype)) && not (in_runtime_class gen) -> { e with eexpr = TCall( mk_static_field_access_infer runtime_cl "toString" expr.epos [], [run expr] ) } | TCast(expr, _) when is_tparam e.etype && not (in_runtime_class gen) && not (Common.defined gen.gcon Define.EraseGenerics) -> let static = mk_static_field_access_infer (runtime_cl) "genericCast" e.epos [e.etype] in - { e with eexpr = TCall(static, [mk_local (alloc_var "$type_param" e.etype) expr.epos; run expr]); } + { e with eexpr = TCall(static, [mk (TIdent "$type_param") e.etype expr.epos; run expr]); } | TBinop( (Ast.OpNotEq as op), e1, e2) | TBinop( (Ast.OpEq as op), e1, e2) when is_struct e1.etype || is_struct e2.etype -> @@ -1114,7 +1111,7 @@ let generate con = let rec extract_tparams params el = match el with - | ({ eexpr = TLocal({ v_name = "$type_param" }) } as tp) :: tl -> + | ({ eexpr = TIdent "$type_param" } as tp) :: tl -> extract_tparams (tp.etype :: params) tl | _ -> (params, el) in @@ -1138,9 +1135,7 @@ let generate con = let extract_statements expr = let ret = ref [] in let rec loop expr = match expr.eexpr with - | TCall ({ eexpr = TLocal { - v_name = "__is__" | "__typeof__" | "__array__" | "__sizeof__" | "__delegate__" - } }, el) -> + | TCall ({ eexpr = TIdent ("__is__" | "__typeof__" | "__array__" | "__sizeof__" | "__delegate__")}, el) -> List.iter loop el | TNew ({ cl_path = (["cs"], "NativeArray") }, params, [ size ]) -> () @@ -1148,8 +1143,8 @@ let generate con = | TUnop (Ast.Decrement, _, _) | TBinop (Ast.OpAssign, _, _) | TBinop (Ast.OpAssignOp _, _, _) - | TLocal { v_name = "__fallback__" } - | TLocal { v_name = "__sbreak__" } -> + | TIdent "__fallback__" + | TIdent "__sbreak__" -> ret := expr :: !ret | TConst _ | TLocal _ @@ -1285,12 +1280,12 @@ let generate con = write w "default("; write w (t_s e.etype); write w ")" - | TLocal { v_name = "__sbreak__" } -> write w "break" - | TLocal { v_name = "__undefined__" } -> + | TIdent "__sbreak__" -> write w "break" + | TIdent "__undefined__" -> write w (t_s (TInst(runtime_cl, List.map (fun _ -> t_dynamic) runtime_cl.cl_params))); write w ".undefined"; - | TLocal { v_name = "__typeof__" } -> write w "typeof" - | TLocal { v_name = "__sizeof__" } -> write w "sizeof" + | TIdent "__typeof__" -> write w "typeof" + | TIdent "__sizeof__" -> write w "sizeof" | TLocal var -> write_id w var.v_name | TField (_, FEnum(e, ef)) -> @@ -1350,7 +1345,7 @@ let generate con = | TMeta (_,e) -> expr_s w e | TArrayDecl el - | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) + | TCall ({ eexpr = TIdent "__array__" }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["cs"],"NativeArray") }, { cf_name = "make" })) }, el) -> let _, el = extract_tparams [] el in print w "new %s" (t_s e.etype); @@ -1361,46 +1356,46 @@ let generate con = acc + 1 ) 0 el); write w "}" - | TCall ({ eexpr = TLocal { v_name = "__delegate__" } }, [del]) -> + | TCall ({ eexpr = TIdent "__delegate__" }, [del]) -> expr_s w del - | TCall ({ eexpr = TLocal( { v_name = "__is__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> + | TCall ({ eexpr = TIdent "__is__" }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " is "; write w (md_s md); write w " )" - | TCall ({ eexpr = TLocal( { v_name = "__as__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> + | TCall ({ eexpr = TIdent "__as__" }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " as "; write w (md_s md); write w " )" - | TCall ({ eexpr = TLocal( { v_name = "__as__" } ) }, expr :: _ ) -> + | TCall ({ eexpr = TIdent "__as__" }, expr :: _ ) -> write w "( "; expr_s w expr; write w " as "; write w (t_s e.etype); write w " )"; - | TCall ({ eexpr = TLocal( { v_name = "__cs__" } ) }, [ { eexpr = TConst(TString(s)) } ] ) -> + | TCall ({ eexpr = TIdent "__cs__" }, [ { eexpr = TConst(TString(s)) } ] ) -> write w s - | TCall ({ eexpr = TLocal( { v_name = "__cs__" } ) }, { eexpr = TConst(TString(s)) } :: tl ) -> + | TCall ({ eexpr = TIdent "__cs__" }, { eexpr = TConst(TString(s)) } :: tl ) -> Codegen.interpolate_code gen.gcon s tl (write w) (expr_s w) e.epos - | TCall ({ eexpr = TLocal( { v_name = "__stackalloc__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__stackalloc__" }, [ e ] ) -> write w "stackalloc byte["; expr_s w e; write w "]" - | TCall ({ eexpr = TLocal( { v_name = "__unsafe__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__unsafe__" }, [ e ] ) -> write w "unsafe"; expr_s w (mk_block e) - | TCall ({ eexpr = TLocal( { v_name = "__checked__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__checked__" }, [ e ] ) -> write w "checked"; expr_s w (mk_block e) - | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, [ eobj; eblock ] ) -> + | TCall ({ eexpr = TIdent "__lock__" }, [ eobj; eblock ] ) -> write w "lock("; expr_s w eobj; write w ")"; expr_s w (mk_block eblock) - | TCall ({ eexpr = TLocal( { v_name = "__fixed__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__fixed__" }, [ e ] ) -> let fixeds = ref [] in let rec loop = function | ({ eexpr = TVar(v, Some(e) ) } as expr) :: tl when is_pointer gen v.v_type -> @@ -1441,11 +1436,11 @@ let generate con = trace (debug_expr e); gen.gcon.error "Invalid 'fixed' keyword format" e.epos ) - | TCall ({ eexpr = TLocal( { v_name = "__addressOf__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__addressOf__" }, [ e ] ) -> let e = ensure_local e "for addressOf" in write w "&"; expr_s w e - | TCall ({ eexpr = TLocal( { v_name = "__valueOf__" } ) }, [ e ] ) -> + | TCall ({ eexpr = TIdent "__valueOf__" }, [ e ] ) -> write w "*("; expr_s w e; write w ")" @@ -1629,7 +1624,7 @@ let generate con = if is_some eopt then (write w " "; expr_s w (get eopt)) | TBreak -> write w "break" | TContinue -> write w "continue" - | TThrow { eexpr = TLocal { v_name = "__rethrow__" } } -> + | TThrow { eexpr = TIdent "__rethrow__" } -> write w "throw" | TThrow e -> write w "throw "; @@ -1655,6 +1650,7 @@ let generate con = | TFunction _ -> write w "[ func decl not supported ]"; if !strict_mode then assert false | TEnumParameter _ -> write w "[ enum parameter not supported ]"; if !strict_mode then assert false | TEnumIndex _ -> write w "[ enum index not supported ]"; if !strict_mode then assert false + | TIdent s -> write w "[ ident not supported ]"; if !strict_mode then assert false ) and do_call w e el = let params, el = extract_tparams [] el in @@ -1965,7 +1961,7 @@ let generate con = raise Exit (* don't recurse into explicit checked blocks *) - | TCall ({ eexpr = TLocal({ v_name = "__checked__" }) }, _) -> + | TCall ({ eexpr = TIdent "__checked__" }, _) -> () (* skip reflection field hashes as they are safe *) @@ -2679,8 +2675,7 @@ let generate con = | _ -> () ) gen.gtypes_list; - let tp_v = alloc_var "$type_param" t_dynamic in - let mk_tp t pos = { eexpr = TLocal(tp_v); etype = t; epos = pos } in + let mk_tp t pos = { eexpr = TIdent "$type_param"; etype = t; epos = pos } in gen.gparam_func_call <- (fun ecall efield params elist -> match efield.eexpr with | TField(_, FEnum _) -> @@ -2987,7 +2982,7 @@ let generate con = in let is_undefined e = match e.eexpr with - | TLocal { v_name = "__undefined__" } | TField(_,FStatic({cl_path=["haxe";"lang"],"Runtime"},{cf_name="undefined"})) -> true + | TIdent "__undefined__" | TField(_,FStatic({cl_path=["haxe";"lang"],"Runtime"},{cf_name="undefined"})) -> true | _ -> false in diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml index 2c77fa5a90a..5501828dee8 100644 --- a/src/generators/genhl.ml +++ b/src/generators/genhl.ml @@ -1515,9 +1515,9 @@ and eval_expr ctx e = r ) | _ -> assert false); - | TCall ({ eexpr = TLocal v }, el) when v.v_name.[0] = '$' -> + | TCall ({ eexpr = TIdent s }, el) when s.[0] = '$' -> let invalid() = abort "Invalid native call" e.epos in - (match v.v_name, el with + (match s, el with | "$new", [{ eexpr = TTypeExpr (TClassDecl _) }] -> (match follow e.etype with | TInst (c,pl) -> @@ -1921,7 +1921,7 @@ and eval_expr ctx e = free ctx min; r | _ -> - abort ("Unknown native call " ^ v.v_name) e.epos) + abort ("Unknown native call " ^ s) e.epos) | TEnumIndex v -> get_enum_index ctx v | TCall ({ eexpr = TField (_,FStatic ({ cl_path = [],"Type" },{ cf_name = "enumIndex" })) },[{ eexpr = TCast(v,_) }]) when (match follow v.etype with TEnum _ -> true | _ -> false) -> @@ -2717,6 +2717,8 @@ and eval_expr ctx e = else op ctx (OSafeCast (r,re)); r + | TIdent s -> + assert false and gen_assign_op ctx acc e1 f = let f r = diff --git a/src/generators/genjava.ml b/src/generators/genjava.ml index e9e110db0ee..f5b20d7fad1 100644 --- a/src/generators/genjava.ml +++ b/src/generators/genjava.ml @@ -231,8 +231,6 @@ struct let f_md = ( get_type gen (["java";"lang"], "Float")) in let bool_md = get_type gen (["java";"lang"], "Boolean") in - let is_var = alloc_var "__is__" t_dynamic in - let rec run e = match e.eexpr with (* Math changes *) @@ -262,7 +260,7 @@ struct ) -> let mk_is is_basic obj md = let obj = if is_basic then mk_cast t_dynamic obj else obj in - { e with eexpr = TCall( { eexpr = TLocal is_var; etype = t_dynamic; epos = e.epos }, [ + { e with eexpr = TCall( { eexpr = TIdent "__is__"; etype = t_dynamic; epos = e.epos }, [ run obj; { eexpr = TTypeExpr md; etype = t_dynamic (* this is after all a syntax filter *); epos = e.epos } ] ) } @@ -362,7 +360,7 @@ struct | TReturn _ | TThrow _ -> true (* this is hack to not use 'break' on switch cases *) - | TLocal { v_name = "__fallback__" } when is_switch -> true + | TIdent "__fallback__" when is_switch -> true | TMeta ((Meta.LoopLabel,_,_), { eexpr = TBreak }) -> true | TParenthesis p | TMeta (_,p) -> is_final_return_expr p | TBlock bl -> is_final_return_block is_switch bl @@ -572,7 +570,7 @@ struct epos = e.epos } in - let e = if has_fallback then { e with eexpr = TBlock([ e; mk_local (alloc_var "__fallback__" t_dynamic) e.epos]) } else e in + let e = if has_fallback then { e with eexpr = TBlock([ e; mk (TIdent "__fallback__") t_dynamic e.epos]) } else e in (el, e) in @@ -1351,8 +1349,8 @@ let generate con = let has_semicolon e = match e.eexpr with - | TLocal { v_name = "__fallback__" } - | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, _ ) -> false + | TIdent "__fallback__" + | TCall ({ eexpr = TIdent "__lock__" }, _ ) -> false | TBlock _ | TFor _ | TSwitch _ | TTry _ | TIf _ -> false | TWhile (_,_,flag) when flag = Ast.NormalWhile -> false | _ -> true @@ -1388,7 +1386,7 @@ let generate con = let rec extract_tparams params el = match el with - | ({ eexpr = TLocal({ v_name = "$type_param" }) } as tp) :: tl -> + | ({ eexpr = TIdent "$type_param" } as tp) :: tl -> extract_tparams (tp.etype :: params) tl | _ -> (params, el) in @@ -1405,9 +1403,7 @@ let generate con = let extract_statements expr = let ret = ref [] in let rec loop expr = match expr.eexpr with - | TCall ({ eexpr = TLocal { - v_name = "__is__" | "__typeof__" | "__array__" - } }, el) -> + | TCall ({ eexpr = TIdent ("__is__" | "__typeof__" | "__array__")}, el) -> List.iter loop el | TNew ({ cl_path = (["java"], "NativeArray") }, params, [ size ]) -> () @@ -1415,11 +1411,12 @@ let generate con = | TUnop (Ast.Decrement, _, _) | TBinop (Ast.OpAssign, _, _) | TBinop (Ast.OpAssignOp _, _, _) - | TLocal { v_name = "__fallback__" } - | TLocal { v_name = "__sbreak__" } -> + | TIdent "__fallback__" + | TIdent "__sbreak__" -> ret := expr :: !ret | TConst _ | TLocal _ + | TIdent _ | TArray _ | TBinop _ | TField _ @@ -1471,13 +1468,15 @@ let generate con = | t -> write w ("null") ) | TThis -> write w "this" | TSuper -> write w "super") - | TLocal { v_name = "__fallback__" } -> () - | TLocal { v_name = "__sbreak__" } -> write w "break" - | TLocal { v_name = "__undefined__" } -> + | TIdent "__fallback__" -> () + | TIdent "__sbreak__" -> write w "break" + | TIdent "__undefined__" -> write w (t_s e.epos (TInst(runtime_cl, List.map (fun _ -> t_dynamic) runtime_cl.cl_params))); write w ".undefined"; | TLocal var -> write_id w var.v_name + | TIdent s -> + write_id w s | TField(_, FEnum(en,ef)) -> let s = ef.ef_name in print w "%s." (path_s_import e.epos en.e_path en.e_meta); write_field w s @@ -1517,7 +1516,7 @@ let generate con = | _ -> assert false) | TMeta (_,e) -> expr_s w e - | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) + | TCall ({ eexpr = TIdent "__array__" }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["java"],"NativeArray") }, { cf_name = "make" })) }, el) | TArrayDecl el when t_has_type_param e.etype -> let _, el = extract_tparams [] el in @@ -1529,7 +1528,7 @@ let generate con = acc + 1 ) 0 el); write w "}) )" - | TCall ({ eexpr = TLocal { v_name = "__array__" } }, el) + | TCall ({ eexpr = TIdent "__array__" }, el) | TCall ({ eexpr = TField(_, FStatic({ cl_path = (["java"],"NativeArray") }, { cf_name = "make" })) }, el) | TArrayDecl el -> let _, el = extract_tparams [] el in @@ -1553,17 +1552,17 @@ let generate con = write w "Character.toString((char) "; expr_s w cc; write w ")" - | TCall ({ eexpr = TLocal( { v_name = "__is__" } ) }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> + | TCall ({ eexpr = TIdent "__is__" }, [ expr; { eexpr = TTypeExpr(md) } ] ) -> write w "( "; expr_s w expr; write w " instanceof "; write w (md_s e.epos md); write w " )" - | TCall ({ eexpr = TLocal( { v_name = "__java__" } ) }, [ { eexpr = TConst(TString(s)) } ] ) -> + | TCall ({ eexpr = TIdent "__java__" }, [ { eexpr = TConst(TString(s)) } ] ) -> write w s - | TCall ({ eexpr = TLocal( { v_name = "__java__" } ) }, { eexpr = TConst(TString(s)) } :: tl ) -> + | TCall ({ eexpr = TIdent "__java__" }, { eexpr = TConst(TString(s)) } :: tl ) -> Codegen.interpolate_code gen.gcon s tl (write w) (expr_s w) e.epos - | TCall ({ eexpr = TLocal( { v_name = "__lock__" } ) }, [ eobj; eblock ] ) -> + | TCall ({ eexpr = TIdent "__lock__" }, [ eobj; eblock ] ) -> write w "synchronized("; let rec loop eobj = match eobj.eexpr with | TTypeExpr md -> @@ -1585,7 +1584,7 @@ let generate con = if has_semicolon eblock then write w ";"; end_block w; ) - | TCall ({ eexpr = TLocal( { v_name = "__typeof__" } ) }, [ { eexpr = TTypeExpr md } as expr ] ) -> + | TCall ({ eexpr = TIdent "__typeof__" }, [ { eexpr = TTypeExpr md } as expr ] ) -> expr_s w expr; write w ".class" | TCall (e, el) -> @@ -2501,7 +2500,7 @@ let generate con = is_dynamic_expr is_dynamic_op e1 | _ -> false) (fun e1 e2 -> - let is_null e = match e.eexpr with | TConst(TNull) | TLocal({ v_name = "__undefined__" }) -> true | _ -> false in + let is_null e = match e.eexpr with | TConst(TNull) | TIdent "__undefined__" -> true | _ -> false in match e1.eexpr, e2.eexpr with | TConst c1, TConst c2 when is_null e1 || is_null e2 -> diff --git a/src/generators/genjs.ml b/src/generators/genjs.ml index 6d4d925c604..b74ad08c7e3 100644 --- a/src/generators/genjs.ml +++ b/src/generators/genjs.ml @@ -344,64 +344,64 @@ let rec gen_call ctx e el in_value = List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); - | TCall (x,_) , el when (match x.eexpr with TLocal { v_name = "__js__" } -> false | _ -> true) -> + | TCall (x,_) , el when (match x.eexpr with TIdent "__js__" -> false | _ -> true) -> spr ctx "("; gen_value ctx e; spr ctx ")"; spr ctx "("; concat ctx "," (gen_value ctx) el; spr ctx ")"; - | TLocal { v_name = "__new__" }, { eexpr = TConst (TString cl) } :: params -> + | TIdent "__new__", { eexpr = TConst (TString cl) } :: params -> print ctx "new %s(" cl; concat ctx "," (gen_value ctx) params; spr ctx ")"; - | TLocal { v_name = "__new__" }, e :: params -> + | TIdent "__new__", e :: params -> spr ctx "new "; gen_value ctx e; spr ctx "("; concat ctx "," (gen_value ctx) params; spr ctx ")"; - | TLocal { v_name = "__js__" }, [{ eexpr = TConst (TString "this") }] -> + | TIdent "__js__", [{ eexpr = TConst (TString "this") }] -> spr ctx (this ctx) - | TLocal { v_name = "__js__" }, [{ eexpr = TConst (TString code) }] -> + | TIdent "__js__", [{ eexpr = TConst (TString code) }] -> spr ctx (String.concat "\n" (ExtString.String.nsplit code "\r\n")) - | TLocal { v_name = "__js__" }, { eexpr = TConst (TString code); epos = p } :: tl -> + | TIdent "__js__", { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p - | TLocal { v_name = "__instanceof__" }, [o;t] -> + | TIdent "__instanceof__", [o;t] -> spr ctx "("; gen_value ctx o; print ctx " instanceof "; gen_value ctx t; spr ctx ")"; - | TLocal { v_name = "__typeof__" }, [o] -> + | TIdent "__typeof__", [o] -> spr ctx "typeof("; gen_value ctx o; spr ctx ")"; - | TLocal { v_name = "__strict_eq__" } , [x;y] -> + | TIdent "__strict_eq__" , [x;y] -> (* add extra parenthesis here because of operator precedence *) spr ctx "(("; gen_value ctx x; spr ctx ") === "; gen_value ctx y; spr ctx ")"; - | TLocal { v_name = "__strict_neq__" } , [x;y] -> + | TIdent "__strict_neq__" , [x;y] -> (* add extra parenthesis here because of operator precedence *) spr ctx "(("; gen_value ctx x; spr ctx ") !== "; gen_value ctx y; spr ctx ")"; - | TLocal ({v_name = "__define_feature__"}), [_;e] -> + | TIdent "__define_feature__", [_;e] -> gen_expr ctx e - | TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse -> + | TIdent "__feature__", { eexpr = TConst (TString f) } :: eif :: eelse -> (if has_feature ctx f then gen_value ctx eif else match eelse with | [] -> () | e :: _ -> gen_value ctx e) - | TLocal { v_name = "__rethrow__" }, [] -> + | TIdent "__rethrow__", [] -> spr ctx "throw $hx_rethrow"; - | TLocal { v_name = "__resources__" }, [] -> + | TIdent "__resources__", [] -> spr ctx "["; concat ctx "," (fun (name,data) -> spr ctx "{ "; @@ -412,7 +412,7 @@ let rec gen_call ctx e el in_value = spr ctx "}" ) (Hashtbl.fold (fun name data acc -> (name,data) :: acc) ctx.com.resources []); spr ctx "]"; - | TLocal { v_name = "`trace" }, [e;infos] -> + | TIdent "`trace", [e;infos] -> if has_feature ctx "haxe.Log.trace" then begin let t = (try List.find (fun t -> t_path t = (["haxe"],"Log")) ctx.com.types with _ -> assert false) in spr ctx (ctx.type_accessor t); @@ -675,7 +675,7 @@ and gen_expr ctx e = if (has_feature ctx "js.Lib.rethrow") then begin let has_rethrow (_,e) = let rec loop e = match e.eexpr with - | TCall({eexpr = TLocal {v_name = "__rethrow__"}}, []) -> raise Exit + | TCall({eexpr = TIdent "__rethrow__"}, []) -> raise Exit | _ -> Type.iter loop e in try (loop e; false) with Exit -> true @@ -799,7 +799,10 @@ and gen_expr ctx e = gen_expr ctx e1; spr ctx " , "; spr ctx (ctx.type_accessor t); - spr ctx ")"); + spr ctx ")" + | TIdent s -> + spr ctx s + ); Option.may (fun smap -> smap.current_expr <- None) ctx.smap @@ -807,7 +810,7 @@ and gen_block_element ?(after=false) ctx e = match e.eexpr with | TBlock el -> List.iter (gen_block_element ~after ctx) el - | TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) -> + | TCall ({ eexpr = TIdent "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse) -> if has_feature ctx f then gen_block_element ~after ctx eif else (match eelse with @@ -867,7 +870,8 @@ and gen_value ctx e = | TArrayDecl _ | TNew _ | TUnop _ - | TFunction _ -> + | TFunction _ + | TIdent _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 diff --git a/src/generators/genlua.ml b/src/generators/genlua.ml index b3355fc9c5a..33763dabca3 100644 --- a/src/generators/genlua.ml +++ b/src/generators/genlua.ml @@ -235,7 +235,7 @@ let index_of f l = (* create a __lua__ call *) let mk_lua_code com code args t pos = - let lua_local = Codegen.ExprBuilder.make_local (alloc_var "__lua__" t_dynamic pos) pos in + let lua_local = mk (TIdent "__lua__") t_dynamic pos in let code_const = Codegen.ExprBuilder.make_string com code pos in mk (TCall (lua_local, code_const :: args)) t pos @@ -331,27 +331,27 @@ let rec gen_call ctx e el in_value = List.iter (fun p -> print ctx ","; gen_value ctx p) params; spr ctx ")"; ); - | TCall (x,_) , el when (match x.eexpr with TLocal { v_name = "__lua__" } -> false | _ -> true) -> + | TCall (x,_) , el when (match x.eexpr with TIdent "__lua__" -> false | _ -> true) -> gen_paren ctx [e]; gen_paren ctx el; - | TLocal { v_name = "__new__" }, { eexpr = TConst (TString cl) } :: params -> + | TIdent "__new__", { eexpr = TConst (TString cl) } :: params -> print ctx "%s.new(" cl; concat ctx "," (gen_value ctx) params; spr ctx ")"; - | TLocal { v_name = "__new__" }, e :: params -> + | TIdent "__new__", e :: params -> gen_value ctx e; spr ctx ".new("; concat ctx "," (gen_value ctx) params; spr ctx ")"; - | TLocal { v_name = "__callself__" }, { eexpr = TConst (TString head) } :: { eexpr = TConst (TString tail) } :: el -> + | TIdent "__callself__", { eexpr = TConst (TString head) } :: { eexpr = TConst (TString tail) } :: el -> print ctx "%s:%s" head tail; gen_paren ctx el; - | TLocal { v_name = "__call__" }, { eexpr = TConst (TString code) } :: el -> + | TIdent "__call__", { eexpr = TConst (TString code) } :: el -> spr ctx code; gen_paren ctx el; - | TLocal { v_name = "__lua_length__" }, [e]-> + | TIdent "__lua_length__", [e]-> spr ctx "#"; gen_value ctx e; - | TLocal { v_name = "__lua_table__" }, el -> + | TIdent "__lua_table__", el -> let count = ref 0 in spr ctx "({"; List.iter (fun e -> @@ -372,22 +372,22 @@ let rec gen_call ctx e el in_value = abort "__lua_table__ only accepts array or anonymous object arguments" e.epos; )) el; spr ctx "})"; - | TLocal { v_name = "__lua__" }, [{ eexpr = TConst (TString code) }] -> + | TIdent "__lua__", [{ eexpr = TConst (TString code) }] -> spr ctx (String.concat "\n" (ExtString.String.nsplit code "\r\n")) - | TLocal { v_name = "__lua__" }, { eexpr = TConst (TString code); epos = p } :: tl -> + | TIdent "__lua__", { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p - | TLocal { v_name = "__type__" }, [o] -> + | TIdent "__type__", [o] -> spr ctx "type"; gen_paren ctx [o]; - | TLocal ({v_name = "__define_feature__"}), [_;e] -> + | TIdent "__define_feature__", [_;e] -> gen_expr ctx e - | TLocal { v_name = "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse -> + | TIdent "__feature__", { eexpr = TConst (TString f) } :: eif :: eelse -> (if has_feature ctx f then gen_value ctx eif else match eelse with | [] -> () | e :: _ -> gen_value ctx e) - | TLocal { v_name = "__resources__" }, [] -> + | TIdent "__resources__", [] -> (* TODO: Array declaration helper *) spr ctx "_hx_tab_array({"; let count = ref 0 in @@ -402,7 +402,7 @@ let rec gen_call ctx e el in_value = incr count ) (Hashtbl.fold (fun name data acc -> (name,data) :: acc) ctx.com.resources []); print ctx "}, %i)" !count; - | TLocal { v_name = "`trace" }, [e;infos] -> + | TIdent "`trace", [e;infos] -> if has_feature ctx "haxe.Log.trace" then begin let t = (try List.find (fun t -> t_path t = (["haxe"],"Log")) ctx.com.types with _ -> assert false) in spr ctx (ctx.type_accessor t); @@ -916,6 +916,8 @@ and gen_expr ?(local=true) ctx e = begin spr ctx ")" | TCast (e1,None) -> gen_value ctx e1; + | TIdent s -> + spr ctx s end; (* gen_block_element handles expressions that map to "statements" in lua. *) @@ -933,10 +935,10 @@ and gen_block_element ctx e = | TArrayDecl el | TBlock el -> List.iter (gen_block_element ctx) el; (* For plain lua table instantiations, just capture argument operations *) - | TCall({ eexpr = TLocal { v_name = "__lua_table__" }} , el) -> + | TCall({ eexpr = TIdent "__lua_table__"} , el) -> List.iter(fun x -> gen_block_element ctx x) el (* make a no-op __define_feature__ expression possible *) - | TCall({eexpr = TLocal ({v_name = "__define_feature__"})}, [_;e]) -> + | TCall({eexpr = TIdent "__define_feature__"}, [_;e]) -> gen_block_element ctx e | TObjectDecl fl -> List.iter (fun (_,e) -> gen_block_element ctx e) fl @@ -962,7 +964,7 @@ and gen_block_element ctx e = let f () = gen_expr ctx e in gen_iife_assign ctx f; semicolon ctx; - | TCall ({ eexpr = TLocal { v_name = "__feature__" } }, { eexpr = TConst (TString f) } :: eif :: eelse) -> + | TCall ({ eexpr = TIdent "__feature__" }, { eexpr = TConst (TString f) } :: eif :: eelse) -> if has_feature ctx f then gen_block_element ctx eif else (match eelse with @@ -1051,7 +1053,8 @@ and gen_value ctx e = | TArrayDecl _ | TNew _ | TUnop _ - | TFunction _ -> + | TFunction _ + | TIdent _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 diff --git a/src/generators/genneko.ml b/src/generators/genneko.ml index c353cc45da2..981d7e2220c 100644 --- a/src/generators/genneko.ml +++ b/src/generators/genneko.ml @@ -199,7 +199,7 @@ and gen_call ctx p e el = this p; array p (List.map (gen_expr ctx) el) ] - | TLocal { v_name = "__resources__" }, [] -> + | TIdent "__resources__", [] -> call p (builtin p "array") (Hashtbl.fold (fun name data acc -> (EObject [("name",gen_constant ctx e.epos (TString name));("data",gen_big_string ctx p data)],p) :: acc ) ctx.com.resources []) @@ -219,8 +219,8 @@ and gen_expr ctx e = match e.eexpr with | TConst c -> gen_constant ctx e.epos c - | TLocal v when v.v_name.[0] = '$' -> - (EConst (Builtin (String.sub v.v_name 1 (String.length v.v_name - 1))),p) + | TIdent s when s.[0] = '$' -> + (EConst (Builtin (String.sub s 1 (String.length s - 1))),p) | TLocal v -> if v.v_capture then (EArray (ident p v.v_name,int p 0),p) @@ -370,6 +370,8 @@ and gen_expr ctx e = gen_expr ctx e | TCast (e1,Some t) -> gen_expr ctx (Codegen.default_cast ~vtmp:"@tmp" ctx.com e1 t e.etype e.epos) + | TIdent s -> + ident p s | TSwitch (e,cases,eo) -> let e = gen_expr ctx e in let eo = (match eo with None -> None | Some e -> Some (gen_expr ctx e)) in diff --git a/src/generators/genphp.ml b/src/generators/genphp.ml index c1608c042de..c19b933f333 100644 --- a/src/generators/genphp.ml +++ b/src/generators/genphp.ml @@ -222,8 +222,7 @@ let rec is_string_type t = let is_string_expr e = is_string_type e.etype let to_string ctx e = - let v = alloc_var "__call__" t_dynamic e.epos in - let f = mk (TLocal v) t_dynamic e.epos in + let f = mk (TIdent "__call__") t_dynamic e.epos in mk (TCall (f, [ ExprBuilder.make_string ctx.com "_hx_string_rec" e.epos; e; ExprBuilder.make_string ctx.com "" e.epos])) ctx.com.basic.tstring e.epos let as_string_expr ctx e = @@ -235,8 +234,7 @@ let as_string_expr ctx e = | _ -> e (* for known String type that could have null value *) let to_string_null ctx e = - let v = alloc_var "__call__" t_dynamic e.epos in - let f = mk (TLocal v) t_dynamic e.epos in + let f = mk (TIdent "__call__") t_dynamic e.epos in mk (TCall (f, [ ExprBuilder.make_string ctx.com "_hx_string_or_null" e.epos; e])) ctx.com.basic.tstring e.epos @@ -572,54 +570,54 @@ and gen_call ctx e el = spr ctx ", "; concat ctx ", " (gen_value ctx) el; spr ctx ")"; - | TLocal { v_name = "__set__" }, { eexpr = TConst (TString code) } :: el -> + | TIdent "__set__", { eexpr = TConst (TString code) } :: el -> print ctx "$%s" code; genargs el; - | TLocal { v_name = "__set__" }, e :: el -> + | TIdent "__set__", e :: el -> gen_value ctx e; genargs el; - | TLocal { v_name = "__setfield__" }, e :: (f :: el) -> + | TIdent "__setfield__", e :: (f :: el) -> gen_value ctx e; spr ctx "->{"; gen_value ctx f; spr ctx "}"; genargs el; - | TLocal { v_name = "__field__" }, e :: ({ eexpr = TConst (TString code) } :: el) -> + | TIdent "__field__", e :: ({ eexpr = TConst (TString code) } :: el) -> gen_value ctx e; spr ctx "->"; spr ctx code; gen_array_args ctx el; - | TLocal { v_name = "__field__" }, e :: (f :: el) -> + | TIdent "__field__", e :: (f :: el) -> gen_value ctx e; spr ctx "->"; gen_value ctx f; gen_array_args ctx el; - | TLocal { v_name = "__prefix__" }, [] -> + | TIdent "__prefix__", [] -> (match ctx.com.php_prefix with | Some prefix -> print ctx "\"%s\"" prefix | None -> spr ctx "null") - | TLocal { v_name = "__var__" }, { eexpr = TConst (TString code) } :: el -> + | TIdent "__var__", { eexpr = TConst (TString code) } :: el -> print ctx "$%s" code; gen_array_args ctx el; - | TLocal { v_name = "__var__" }, e :: el -> + | TIdent "__var__", e :: el -> gen_value ctx e; gen_array_args ctx el; - | TLocal { v_name = "__call__" }, { eexpr = TConst (TString code) } :: el -> + | TIdent "__call__", { eexpr = TConst (TString code) } :: el -> spr ctx code; spr ctx "("; concat ctx ", " (gen_value ctx) el; spr ctx ")"; - | TLocal { v_name = "__php__" }, [{ eexpr = TConst (TString code) }] -> + | TIdent "__php__", [{ eexpr = TConst (TString code) }] -> (*--php-prefix*) spr ctx (prefix_init_replace ctx.com code) - | TLocal { v_name = "__php__" }, { eexpr = TConst (TString code); epos = p } :: tl -> + | TIdent "__php__", { eexpr = TConst (TString code); epos = p } :: tl -> Codegen.interpolate_code ctx.com code tl (spr ctx) (gen_expr ctx) p - | TLocal { v_name = "__instanceof__" }, [e1;{ eexpr = TConst (TString t) }] -> + | TIdent "__instanceof__", [e1;{ eexpr = TConst (TString t) }] -> gen_value ctx e1; print ctx " instanceof %s" t; - | TLocal { v_name = "__physeq__" }, [e1;e2] -> + | TIdent "__physeq__", [e1;e2] -> spr ctx "("; gen_value ctx e1; spr ctx " === "; @@ -1716,6 +1714,8 @@ and gen_expr ctx e = spr ctx ", "; gen_expr ctx (mk (TTypeExpr t) (mk_texpr t) e1.epos); spr ctx ")" + | TIdent s -> + spr ctx s and argument_list_from_locals include_this in_var l = let lst = ref [] in @@ -1814,7 +1814,8 @@ and gen_value ctx e = | TCall _ | TUnop _ | TNew _ - | TFunction _ -> + | TFunction _ + | TIdent _ -> gen_expr ctx e | TMeta (_,e1) -> gen_value ctx e1 diff --git a/src/generators/genphp7.ml b/src/generators/genphp7.ml index ed6ad48f83a..9c4e006aea4 100644 --- a/src/generators/genphp7.ml +++ b/src/generators/genphp7.ml @@ -701,7 +701,7 @@ let is_access expr = *) let is_magic expr = match expr.eexpr with - | TCall ({ eexpr = TLocal { v_name = name }}, _) -> + | TCall ({ eexpr = TIdent name}, _) -> (match name with | "__php__" -> true | "__call__" -> true @@ -1586,7 +1586,7 @@ class code_writer (ctx:Common.context) hx_type_path php_name = | TArrayDecl exprs -> self#write_expr_array_decl exprs | TCall (target, [arg1; arg2]) when is_std_is target && instanceof_compatible arg1 arg2 -> self#write_expr_lang_instanceof [arg1; arg2] | TCall (_, [arg]) when is_native_struct_array_cast expr && is_object_declaration arg -> self#write_assoc_array_decl arg - | TCall ({ eexpr = TLocal { v_name = name }}, args) when is_magic expr -> self#write_expr_magic name args + | TCall ({ eexpr = TIdent name}, args) when is_magic expr -> self#write_expr_magic name args | TCall ({ eexpr = TField (expr, access) }, args) when is_string expr -> self#write_expr_call_string expr access args | TCall (expr, args) when is_lang_extern expr -> self#write_expr_call_lang_extern expr args | TCall (target, args) when is_sure_var_field_access target -> self#write_expr_call (parenthesis target) args @@ -1612,6 +1612,7 @@ class code_writer (ctx:Common.context) hx_type_path php_name = | TMeta (_, expr) -> self#write_expr expr | TEnumParameter (expr, constructor, index) -> self#write_expr_enum_parameter expr constructor index | TEnumIndex expr -> self#write_expr_enum_index expr + | TIdent s -> self#write s ); expr_hierarchy <- List.tl expr_hierarchy (** diff --git a/src/generators/genpy.ml b/src/generators/genpy.ml index b0554b265e5..98c747a9607 100644 --- a/src/generators/genpy.ml +++ b/src/generators/genpy.ml @@ -951,7 +951,7 @@ module Transformer = struct let f = exprs_to_func (new_expr.a_blocks @ [new_expr.a_expr]) (ae.a_next_id()) ae in lift_expr ~is_value:true ~blocks:f.a_blocks f.a_expr - | ( _, TBreak ) | ( _, TContinue ) -> + | ( _, TBreak ) | ( _, TContinue ) | ( _, TIdent _) -> lift_expr a_expr and transform e = @@ -1213,7 +1213,7 @@ module Printer = struct Printf.sprintf "%s = %s" (print_expr pctx e1) (print_expr pctx (remove_outer_parens e2)) | TBinop(op,e1,({eexpr = TBinop(_,_,_)} as e2)) -> print_expr pctx { e with eexpr = TBinop(op, e1, { e2 with eexpr = TParenthesis(e2) })} - | TBinop(OpEq,{eexpr = TCall({eexpr = TLocal {v_name = "__typeof__"}},[e1])},e2) -> + | TBinop(OpEq,{eexpr = TCall({eexpr = TIdent "__typeof__"},[e1])},e2) -> begin match e2.eexpr with | TConst(TString s) -> begin match s with @@ -1381,6 +1381,8 @@ module Printer = struct Printf.sprintf "(%s if %s else %s)" (print_expr pctx eif) (print_expr pctx econd) (print_expr pctx eelse) | TMeta(_,e1) -> print_expr pctx e1 + | TIdent s -> + s | TSwitch _ | TCast(_, Some _) | TFor _ | TUnop(_,Postfix,_) -> assert false @@ -1607,7 +1609,7 @@ module Printer = struct PMap.foldi fold_dict native_fields "" in match e1.eexpr, el with - | TLocal { v_name = "`trace" }, [e;infos] -> + | TIdent "`trace", [e;infos] -> if has_feature pctx "haxe.Log.trace" then begin "haxe_Log.trace(" ^ (print_expr pctx e) ^ "," ^ (print_expr pctx infos) ^ ")" end else if is_safe_string pctx e then diff --git a/src/generators/genswf9.ml b/src/generators/genswf9.ml index 228911f5c46..daed1c19c59 100644 --- a/src/generators/genswf9.ml +++ b/src/generators/genswf9.ml @@ -926,7 +926,7 @@ let rec gen_access ctx e (forset : 'a) : 'a access = else VCast (id,classify ctx e.etype) ) - | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }) -> + | TArray ({ eexpr = TIdent "__global__" },{ eexpr = TConst (TString s) }) -> let path = parse_path s in let id = type_path ctx path in if is_set forset then write ctx HGetGlobalScope; @@ -1351,10 +1351,12 @@ let rec gen_expr_content ctx retval e = j(); write ctx (HCast tid) end + | TIdent s -> + abort ("Unbound variable " ^ s) e.epos and gen_call ctx retval e el r = match e.eexpr , el with - | TLocal { v_name = "__is__" }, [e;t] -> + | TIdent "__is__", [e;t] -> gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OIs) @@ -1363,31 +1365,31 @@ and gen_call ctx retval e el r = gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OIs) - | TLocal { v_name = "__as__" }, [e;t] -> + | TIdent "__as__", [e;t] -> gen_expr ctx true e; gen_expr ctx true t; write ctx (HOp A3OAs) - | TLocal { v_name = "__int__" }, [e] -> + | TIdent "__int__", [e] -> gen_expr ctx true e; write ctx HToInt - | TLocal { v_name = "__float__" }, [e] -> + | TIdent "__float__", [e] -> gen_expr ctx true e; write ctx HToNumber - | TLocal { v_name = "__foreach__" }, [obj;counter] -> + | TIdent "__foreach__", [obj;counter] -> gen_expr ctx true obj; gen_expr ctx true counter; write ctx HForEach - | TLocal { v_name = "__forin__" }, [obj;counter] -> + | TIdent "__forin__", [obj;counter] -> gen_expr ctx true obj; gen_expr ctx true counter; write ctx HForIn - | TLocal { v_name = "__has_next__" }, [obj;counter] -> + | TIdent "__has_next__", [obj;counter] -> let oreg = match gen_access ctx obj Read with VReg r -> r | _ -> abort "Must be a local variable" obj.epos in let creg = match gen_access ctx counter Read with VReg r -> r | _ -> abort "Must be a local variable" obj.epos in write ctx (HNext (oreg.rid,creg.rid)) - | TLocal { v_name = "__hkeys__" }, [e2] - | TLocal { v_name = "__foreach__" }, [e2] - | TLocal { v_name = "__keys__" }, [e2] -> + | TIdent "__hkeys__", [e2] + | TIdent "__foreach__", [e2] + | TIdent "__keys__", [e2] -> let racc = alloc_reg ctx (KType (type_path ctx ([],"Array"))) in let rcounter = alloc_reg ctx KInt in let rtmp = alloc_reg ctx KDynamic in @@ -1403,9 +1405,9 @@ and gen_call ctx retval e el r = write ctx (HReg rtmp.rid); write ctx (HReg rcounter.rid); (match e.eexpr with - | TLocal { v_name = "__foreach__" } -> + | TIdent "__foreach__" -> write ctx HForEach - | TLocal { v_name = "__hkeys__" } -> + | TIdent "__hkeys__" -> write ctx HForIn; write ctx (HSmallInt 1); write ctx (HCallProperty (as3 "substr",1)); @@ -1419,26 +1421,26 @@ and gen_call ctx retval e el r = free_reg ctx rtmp; free_reg ctx rcounter; free_reg ctx racc; - | TLocal { v_name = "__new__" }, e :: el -> + | TIdent "__new__", e :: el -> gen_expr ctx true e; List.iter (gen_expr ctx true) el; write ctx (HConstruct (List.length el)) - | TLocal { v_name = "__delete__" }, [o;f] -> + | TIdent "__delete__", [o;f] -> gen_expr ctx true o; gen_expr ctx true f; write ctx (HDeleteProp dynamic_prop); - | TLocal { v_name = "__unprotect__" }, [e] -> + | TIdent "__unprotect__", [e] -> write ctx (HGetLex (type_path ctx (["flash"],"Boot"))); gen_expr ctx true e; write ctx (HCallProperty (ident "__unprotect__",1)); - | TLocal { v_name = "__typeof__" }, [e] -> + | TIdent "__typeof__", [e] -> gen_expr ctx true e; write ctx HTypeof - | TLocal { v_name = "__in__" }, [e; f] -> + | TIdent "__in__", [e; f] -> gen_expr ctx true e; gen_expr ctx true f; write ctx (HOp A3OIn) - | TLocal { v_name = "__resources__" }, [] -> + | TIdent "__resources__", [] -> let count = ref 0 in Hashtbl.iter (fun name data -> incr count; @@ -1447,7 +1449,7 @@ and gen_call ctx retval e el r = write ctx (HObject 1); ) ctx.com.resources; write ctx (HArray !count) - | TLocal { v_name = "__vmem_set__" }, [{ eexpr = TConst (TInt code) };e1;e2] -> + | TIdent "__vmem_set__", [{ eexpr = TConst (TInt code) };e1;e2] -> gen_expr ctx true e2; gen_expr ctx true e1; write ctx (HOp (match code with @@ -1458,7 +1460,7 @@ and gen_call ctx retval e el r = | 4l -> A3OMemSetDouble | _ -> assert false )) - | TLocal { v_name = "__vmem_get__" }, [{ eexpr = TConst (TInt code) };e] -> + | TIdent "__vmem_get__", [{ eexpr = TConst (TInt code) };e] -> gen_expr ctx true e; write ctx (HOp (match code with | 0l -> A3OMemGet8 @@ -1468,7 +1470,7 @@ and gen_call ctx retval e el r = | 4l -> A3OMemGetDouble | _ -> assert false )) - | TLocal { v_name = "__vmem_sign__" }, [{ eexpr = TConst (TInt code) };e] -> + | TIdent "__vmem_sign__", [{ eexpr = TConst (TInt code) };e] -> gen_expr ctx true e; write ctx (HOp (match code with | 0l -> A3OSign1 @@ -1476,12 +1478,12 @@ and gen_call ctx retval e el r = | 2l -> A3OSign16 | _ -> assert false )) - | TLocal { v_name = "__vector__" }, [ep] -> + | TIdent "__vector__", [ep] -> gen_type ctx (type_id ctx r); write ctx HGetGlobalScope; gen_expr ctx true ep; write ctx (HCallStack 1) - | TArray ({ eexpr = TLocal { v_name = "__global__" } },{ eexpr = TConst (TString s) }), _ -> + | TArray ({ eexpr = TIdent "__global__" },{ eexpr = TConst (TString s) }), _ -> (match gen_access ctx e Read with | VGlobal id -> write ctx (HFindPropStrict id); diff --git a/src/macro/eval/evalJit.ml b/src/macro/eval/evalJit.ml index 409861be6ee..9696d89e1f4 100644 --- a/src/macro/eval/evalJit.ml +++ b/src/macro/eval/evalJit.ml @@ -611,12 +611,12 @@ and jit_expr jit return e = end | _ -> match e1.eexpr,el with - | TLocal({v_name = "$__mk_pos__"}),[file;min;max] -> + | TIdent "$__mk_pos__",[file;min;max] -> let exec1 = jit_expr jit false file in let exec2 = jit_expr jit false min in let exec3 = jit_expr jit false max in emit_mk_pos exec1 exec2 exec3 - | TLocal({v_name = "$__delayed_call__"}),[{eexpr = TConst(TInt i)}] -> + | TIdent "$__delayed_call__",[{eexpr = TConst(TInt i)}] -> let f = ctx.curapi.MacroApi.delayed_macro (Int32.to_int i) in (fun env -> let f = f() in @@ -775,6 +775,8 @@ and jit_expr jit return e = loop (Codegen.for_remap (ctx.curapi.MacroApi.get_com()) v e1 e2 e.epos) | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> loop e1 + | TIdent s -> + Error.error ("Unknown identifier: " ^ s) e.epos in let f = loop e in if ctx.debug.support_debugger then begin match e.eexpr with diff --git a/src/macro/macroApi.ml b/src/macro/macroApi.ml index 040903ec986..842bc9b5845 100644 --- a/src/macro/macroApi.ml +++ b/src/macro/macroApi.ml @@ -1205,6 +1205,7 @@ and encode_texpr e = | TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1] | TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;vint i] | TEnumIndex e1 -> 27,[loop e1] + | TIdent s -> 28,[encode_string s] in encode_obj OTypedExprDef [ "pos", encode_pos e.epos; @@ -1352,6 +1353,7 @@ and decode_texpr v = | 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1) | 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,decode_int i) | 27, [v1] -> TEnumIndex(loop v1) + | 28, [v1] -> TIdent(decode_string v1) | i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr in try diff --git a/src/optimization/analyzer.ml b/src/optimization/analyzer.ml index 82bebfa7796..9f3b1c3d010 100644 --- a/src/optimization/analyzer.ml +++ b/src/optimization/analyzer.ml @@ -153,15 +153,15 @@ module Ssa = struct v' in let rec loop is_phi i e = match e.eexpr with - | TLocal v when not (is_unbound v) -> + | TLocal v -> let v' = local ctx e v bb in add_ssa_edge ctx.graph v' bb is_phi i; {e with eexpr = TLocal v'} - | TVar(v,Some e1) when not (is_unbound v) -> + | TVar(v,Some e1) -> let e1 = (loop is_phi i) e1 in let v' = write_var v is_phi i in {e with eexpr = TVar(v',Some e1)} - | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) when not (is_unbound v) -> + | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> let e2 = (loop is_phi i) e2 in let v' = write_var v is_phi i in {e with eexpr = TBinop(OpAssign,{e1 with eexpr = TLocal v'},e2)}; @@ -384,7 +384,7 @@ module ConstPropagation = DataFlow(struct | TConst ct -> Const ct | TLocal v -> - if is_unbound v || (follow v.v_type) == t_dynamic || v.v_capture then + if (follow v.v_type) == t_dynamic || v.v_capture then Bottom else get_cell v.v_id @@ -603,7 +603,7 @@ module LocalDce = struct let rec has_side_effect e = let rec loop e = match e.eexpr with - | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> () + | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TIdent _ -> () | TCall ({ eexpr = TField(_,FStatic({ cl_path = ([],"Std") },{ cf_name = "string" })) },args) -> Type.iter loop e | TCall ({eexpr = TField(_,FEnum _)},_) -> Type.iter loop e | TCall ({eexpr = TConst (TString ("phi" | "fun"))},_) -> () @@ -637,9 +637,9 @@ module LocalDce = struct end end and expr e = match e.eexpr with - | TLocal v when not (is_unbound v) -> + | TLocal v -> use v; - | TBinop(OpAssign,{eexpr = TLocal v},e1) | TVar(v,Some e1) when not (is_unbound v) -> + | TBinop(OpAssign,{eexpr = TLocal v},e1) | TVar(v,Some e1) -> if has_side_effect e1 || keep v then expr e1 else () | _ -> diff --git a/src/optimization/analyzerTexpr.ml b/src/optimization/analyzerTexpr.ml index b74e1c3c203..c8938410b14 100644 --- a/src/optimization/analyzerTexpr.ml +++ b/src/optimization/analyzerTexpr.ml @@ -142,12 +142,12 @@ let rec can_be_used_as_value com e = let wrap_meta s e = mk (TMeta((Meta.Custom s,[],e.epos),e)) e.etype e.epos -let is_really_unbound v = match v.v_name with +let is_really_unbound s = match s with | "`trace" | "__int__" -> false - | _ -> is_unbound v + | _ -> true let r = Str.regexp "^\\([A-Za-z0-9_]\\)+$" -let is_unbound_call_that_might_have_side_effects v el = match v.v_name,el with +let is_unbound_call_that_might_have_side_effects s el = match s,el with | "__js__",[{eexpr = TConst (TString s)}] when Str.string_match r s 0 -> false | _ -> true @@ -236,7 +236,8 @@ module TexprKindMapper = struct | TLocal _ | TBreak | TContinue - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> e | TArray(e1,e2) -> let e1 = f KAccess e1 in @@ -487,7 +488,7 @@ module InterferenceReport = struct loop e1; loop e2; (* state *) - | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> + | TCall({eexpr = TIdent s},el) when not (is_unbound_call_that_might_have_side_effects s el) -> List.iter loop el | TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> set_state_read ir; @@ -879,7 +880,7 @@ module Fusion = struct || has_field_write ir (field_name fa) || has_state_write ir -> raise Exit (* state *) - | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> + | TCall({eexpr = TIdent s},el) when not (is_unbound_call_that_might_have_side_effects s el) -> e | TNew(c,tl,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> let el = handle_el el in @@ -898,7 +899,7 @@ module Fusion = struct {e with eexpr = TCall(ef,el)} | TCall(e1,el) -> let e1,el = match e1.eexpr with - | TLocal v when is_really_unbound v -> e1,el + | TIdent s when s <> "`trace" && s <> "__int__" -> e1,el | _ -> handle_call e1 el in if not !found && (((has_state_read ir || has_any_field_read ir)) || has_state_write ir || has_any_field_write ir) then raise Exit; @@ -1037,7 +1038,7 @@ module Fusion = struct in let el = fuse_loop el in {e with eexpr = TBlock el} - | TCall({eexpr = TLocal v},_) when is_really_unbound v -> + | TCall({eexpr = TIdent s},_) when is_really_unbound s -> e | _ -> Type.map_expr loop e @@ -1069,7 +1070,7 @@ module Cleanup = struct if_or_op e e1 e2 e3; | TUnop((Increment | Decrement),_,e1) when (match (Texpr.skip e1).eexpr with TConst _ -> true | _ -> false) -> loop e1 - | TCall({eexpr = TLocal v},_) when is_really_unbound v -> + | TCall({eexpr = TIdent s},_) when is_really_unbound s -> e | TBlock el -> let el = List.map (fun e -> @@ -1222,7 +1223,7 @@ module Purity = struct | _ -> taint_raise node (* Can that even happen? *) end - | TCall({eexpr = TLocal v},el) when not (is_unbound_call_that_might_have_side_effects v el) -> + | TCall({eexpr = TIdent s},el) when not (is_unbound_call_that_might_have_side_effects s el) -> List.iter loop el; | TCall _ -> taint_raise node diff --git a/src/optimization/analyzerTexprTransformer.ml b/src/optimization/analyzerTexprTransformer.ml index efc5d802e74..eebf5c0cea1 100644 --- a/src/optimization/analyzerTexprTransformer.ml +++ b/src/optimization/analyzerTexprTransformer.ml @@ -81,12 +81,12 @@ let rec func ctx bb tf t p = close_node g bb; g.g_unreachable in - let check_unbound_call v el = - if v.v_name = "$ref" then begin match el with + let check_unbound_call s el = + if s = "$ref" then begin match el with | [{eexpr = TLocal v}] -> v.v_capture <- true | _ -> () end; - if is_unbound_call_that_might_have_side_effects v el then ctx.has_unbound <- true; + if is_unbound_call_that_might_have_side_effects s el then ctx.has_unbound <- true; in let no_void t p = if ExtType.is_void (follow t) then Error.error "Cannot use Void as value" p @@ -96,7 +96,7 @@ let rec func ctx bb tf t p = (fun () -> ctx.name_stack <- List.tl ctx.name_stack) in let rec value' bb e = match e.eexpr with - | TLocal v -> + | TLocal _ | TIdent _ -> bb,e | TBinop(OpAssign,({eexpr = TLocal v} as e1),e2) -> block_element bb e,e1 @@ -104,8 +104,8 @@ let rec func ctx bb tf t p = value bb e1 | TBlock _ | TIf _ | TSwitch _ | TTry _ -> bind_to_temp bb false e - | TCall({eexpr = TLocal v},el) when is_really_unbound v -> - check_unbound_call v el; + | TCall({eexpr = TIdent s},el) when is_really_unbound s -> + check_unbound_call s el; bb,e | TCall(e1,el) -> call bb e e1 el @@ -564,8 +564,8 @@ let rec func ctx bb tf t p = add_terminator bb {e with eexpr = TThrow e1}; end (* side_effects *) - | TCall({eexpr = TLocal v},el) when is_really_unbound v -> - check_unbound_call v el; + | TCall({eexpr = TIdent s},el) when is_really_unbound s -> + check_unbound_call s el; add_texpr bb e; bb | TCall(e1,el) -> @@ -606,7 +606,7 @@ let rec func ctx bb tf t p = add_texpr bb e; bb (* no-side-effect *) - | TEnumParameter _ | TEnumIndex _ | TFunction _ | TConst _ | TTypeExpr _ | TLocal _ -> + | TEnumParameter _ | TEnumIndex _ | TFunction _ | TConst _ | TTypeExpr _ | TLocal _ | TIdent _ -> bb (* no-side-effect composites *) | TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) | TField(e1,_) | TUnop(_,_,e1) -> @@ -717,9 +717,9 @@ and func ctx i = let bb,t,p,tf = Hashtbl.find ctx.graph.g_functions i in let e = block_to_texpr ctx bb in let rec loop e = match e.eexpr with - | TLocal v when not (is_unbound v) -> + | TLocal v -> {e with eexpr = TLocal (get_var_origin ctx.graph v)} - | TVar(v,eo) when not (is_unbound v) -> + | TVar(v,eo) -> let eo = Option.map loop eo in let v' = get_var_origin ctx.graph v in {e with eexpr = TVar(v',eo)} @@ -747,7 +747,7 @@ and func ctx i = end | TCall({eexpr = TConst (TString "fun")},[{eexpr = TConst (TInt i32)}]) -> func ctx (Int32.to_int i32) - | TCall({eexpr = TLocal v},_) when is_really_unbound v -> + | TCall({eexpr = TIdent s},_) when is_really_unbound s -> e | _ -> Type.map_expr loop e diff --git a/src/optimization/analyzerTypes.ml b/src/optimization/analyzerTypes.ml index e3cb2153b85..39cf4a9e98b 100644 --- a/src/optimization/analyzerTypes.ml +++ b/src/optimization/analyzerTypes.ml @@ -458,10 +458,10 @@ module Graph = struct () end; DynArray.iter (fun e -> match e.eexpr with - | TVar(v,eo) when not (is_unbound v) -> + | TVar(v,eo) -> declare_var g v bb; if eo <> None then add_var_def g bb v; - | TBinop(OpAssign,{eexpr = TLocal v},_) when not (is_unbound v) -> + | TBinop(OpAssign,{eexpr = TLocal v},_) -> add_var_def g bb v | _ -> () diff --git a/src/optimization/dce.ml b/src/optimization/dce.ml index f99f709cd0b..35ffea7dd43 100644 --- a/src/optimization/dce.ml +++ b/src/optimization/dce.ml @@ -471,11 +471,11 @@ and expr dce e = expr dce e; mark_t dce e.epos v.v_type; ) vl; - | TCall ({eexpr = TLocal ({v_name = "`trace"})},[p;{ eexpr = TObjectDecl(v)}]) -> + | TCall ({eexpr = TIdent "`trace"},[p;{ eexpr = TObjectDecl(v)}]) -> check_and_add_feature dce "has_anon_trace"; List.iter (fun (_,e) -> expr dce e) v; expr dce p; - | TCall ({eexpr = TLocal ({v_name = "__define_feature__"})},[{eexpr = TConst (TString ft)};e]) -> + | TCall ({eexpr = TIdent "__define_feature__"},[{eexpr = TConst (TString ft)};e]) -> Hashtbl.replace dce.curclass.cl_module.m_extra.m_features ft true; check_feature dce ft; expr dce e; diff --git a/src/optimization/optimizer.ml b/src/optimization/optimizer.ml index d893988e190..2ffff254a18 100644 --- a/src/optimization/optimizer.ml +++ b/src/optimization/optimizer.ml @@ -30,7 +30,7 @@ open Globals let mk_untyped_call name p params = { - eexpr = TCall({ eexpr = TLocal(alloc_unbound_var name t_dynamic p); etype = t_dynamic; epos = p }, params); + eexpr = TCall({ eexpr = TIdent name; etype = t_dynamic; epos = p }, params); etype = t_dynamic; epos = p; } @@ -130,14 +130,7 @@ let api_inline2 com c field params p = let api_inline ctx c field params p = match c.cl_path, field, params with | ([],"Std"),"is",[o;t] | (["js"],"Boot"),"__instanceof",[o;t] when ctx.com.platform = Js -> - let mk_local ctx n t pos = - mk (TLocal (try - PMap.find n ctx.locals - with _ -> - let v = add_local ctx n t p in - v.v_meta <- [Meta.Unbound,[],p]; - v - )) t pos in + let mk_local ctx n t pos = mk (TIdent n) t pos in let tstring = ctx.com.basic.tstring in let tbool = ctx.com.basic.tbool in @@ -150,7 +143,7 @@ let api_inline ctx c field params p = match c.cl_path, field, params with in let typeof t = - let tof = mk_local ctx "__typeof__" (tfun [o.etype] tstring) p in + let tof = mk (TIdent "__typeof__") (tfun [o.etype] tstring) p in let tof = mk (TCall (tof, [o])) tstring p in mk (TBinop (Ast.OpEq, tof, (mk (TConst (TString t)) tstring p))) tbool p in @@ -260,7 +253,6 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f Hashtbl.find locals v.v_id with Not_found -> let v' = alloc_var v.v_name v.v_type v.v_pos in - if Meta.has Meta.Unbound v.v_meta then v'.v_meta <- [Meta.Unbound,[],p]; v'.v_extra <- v.v_extra; let i = { i_var = v; @@ -282,8 +274,6 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f let l = try Hashtbl.find locals v.v_id with Not_found -> - (* make sure to duplicate unbound inline variable to prevent dependency leak when unifying monomorph *) - if has_meta Meta.Unbound v.v_meta then local v else { i_var = v; i_subst = v; @@ -928,7 +918,8 @@ let standard_precedence op = let rec need_parent e = match e.eexpr with - | TConst _ | TLocal _ | TArray _ | TField _ | TEnumParameter _ | TEnumIndex _ | TParenthesis _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false + | TConst _ | TLocal _ | TArray _ | TField _ | TEnumParameter _ | TEnumIndex _ | TParenthesis _ + | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ | TIdent _ -> false | TCast (e,None) | TMeta(_,e) -> need_parent e | TCast _ | TThrow _ | TReturn _ | TTry _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak | TBlock _ | TVar _ | TFunction _ | TUnop _ -> true @@ -949,7 +940,7 @@ let sanitize_expr com e = match e.eexpr with | TVar _ (* needs to be put into blocks *) | TFor _ (* a temp var is needed for holding iterator *) - | TCall ({ eexpr = TLocal { v_name = "__js__" } },_) (* we never know *) + | TCall ({ eexpr = TIdent "__js__" },_) (* we never know *) -> block e | _ -> e in diff --git a/src/optimization/optimizerTexpr.ml b/src/optimization/optimizerTexpr.ml index ccd1f99ea38..97c5a395727 100644 --- a/src/optimization/optimizerTexpr.ml +++ b/src/optimization/optimizerTexpr.ml @@ -64,7 +64,7 @@ end let has_side_effect e = let rec loop e = match e.eexpr with - | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ -> () + | TConst _ | TLocal _ | TTypeExpr _ | TFunction _ | TIdent _ -> () | TCall({eexpr = TField(e1,fa)},el) when PurityState.is_pure_field_access fa -> loop e1; List.iter loop el | TNew(c,_,el) when (match c.cl_constructor with Some cf when PurityState.is_pure c cf -> true | _ -> false) -> List.iter loop el | TNew _ | TCall _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit @@ -88,7 +88,7 @@ let is_read_only_field_access e fa = match fa with true | FDynamic _ -> false - | FAnon {cf_kind = Var {v_write = AccNo}} when (match e.eexpr with TLocal v when is_unbound v -> true | _ -> false) -> true + | FAnon {cf_kind = Var {v_write = AccNo}} when (match e.eexpr with TIdent _ -> true | _ -> false) -> true | FInstance (c,_,cf) | FStatic (c,cf) | FClosure (Some(c,_),cf) -> begin match cf.cf_kind with | Method MethDynamic -> false diff --git a/src/typing/type.ml b/src/typing/type.ml index c68c047094f..a2abac4ca25 100644 --- a/src/typing/type.ml +++ b/src/typing/type.ml @@ -139,6 +139,7 @@ and texpr_expr = | TMeta of metadata_entry * texpr | TEnumParameter of texpr * tenum_field * int | TEnumIndex of texpr + | TIdent of string and tfield_access = | FInstance of tclass * tparams * tclass_field @@ -337,11 +338,6 @@ let alloc_var = let uid = ref 0 in (fun n t p -> incr uid; { v_name = n; v_type = t; v_id = !uid; v_capture = false; v_extra = None; v_meta = []; v_pos = p }) -let alloc_unbound_var n t p = - let v = alloc_var n t p in - v.v_meta <- [Meta.Unbound,[],null_pos]; - v - let alloc_mid = let mid = ref 0 in (fun() -> incr mid; !mid) @@ -353,9 +349,6 @@ let mk_block e = | TBlock _ -> e | _ -> mk (TBlock [e]) e.etype e.epos -let is_unbound v = - Meta.has Meta.Unbound v.v_meta - let mk_cast e t p = mk (TCast(e,None)) t p let null t p = mk (TConst TNull) t p @@ -1008,6 +1001,7 @@ let s_expr_kind e = | TThrow _ -> "Throw" | TCast _ -> "Cast" | TMeta _ -> "Meta" + | TIdent _ -> "Ident" let s_const = function | TInt i -> Int32.to_string i @@ -1095,6 +1089,8 @@ let rec s_expr s_type e = sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e) | TMeta ((n,el,_),e) -> sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e) + | TIdent s -> + "Ident " ^ s ) in sprintf "(%s : %s)" str (s_type e.etype) @@ -1164,6 +1160,8 @@ let rec s_expr_pretty print_var_ids tabs top_level s_type e = sprintf "cast (%s,%s)" (loop e) (s_type_path (t_path mt)) | TMeta ((n,el,_),e) -> sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e) + | TIdent s -> + s let rec s_expr_ast print_var_ids tabs s_type e = let sprintf = Printf.sprintf in @@ -1250,6 +1248,8 @@ let rec s_expr_ast print_var_ids tabs s_type e = | _ -> sprintf "%s(%s)" s (String.concat ", " (List.map Ast.s_expr el)) in tag "Meta" [s; loop e1] + | TIdent s -> + tag "Ident" [s] let s_types ?(sep = ", ") tl = let pctx = print_context() in @@ -2217,7 +2217,8 @@ let iter f e = | TLocal _ | TBreak | TContinue - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> () | TArray (e1,e2) | TBinop (_,e1,e2) @@ -2267,7 +2268,8 @@ let map_expr f e = | TLocal _ | TBreak | TContinue - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> e | TArray (e1,e2) -> let e1 = f e1 in @@ -2331,7 +2333,8 @@ let map_expr_type f ft fv e = | TConst _ | TBreak | TContinue - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> { e with etype = ft e.etype } | TLocal v -> { e with eexpr = TLocal (fv v); etype = ft e.etype } @@ -2574,7 +2577,8 @@ module TExprToExpr = struct ) in ECast (convert_expr e,t) | TMeta ((Meta.Ast,[e1,_],_),_) -> e1 - | TMeta (m,e) -> EMeta(m,convert_expr e)) + | TMeta (m,e) -> EMeta(m,convert_expr e) + | TIdent s -> EConst (Ident s)) ,e.epos) end @@ -2697,7 +2701,8 @@ module Texpr = struct | TLocal _ | TBreak | TContinue - | TTypeExpr _ -> + | TTypeExpr _ + | TIdent _ -> acc,e | TArray (e1,e2) -> let acc,e1 = f acc e1 in diff --git a/src/typing/typecore.ml b/src/typing/typecore.ml index 67b70e92a2b..6b26626e094 100644 --- a/src/typing/typecore.ml +++ b/src/typing/typecore.ml @@ -210,11 +210,6 @@ let add_local ctx n t p = ctx.locals <- PMap.add n v ctx.locals; v -let add_unbound_local ctx n t p = - let v = add_local ctx n t p in - v.v_meta <- (Meta.Unbound,[],null_pos) :: v.v_meta; - v - let gen_local_prefix = "`" let gen_local ctx t p = diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 753937657af..84a9b438d1d 100644 --- a/src/typing/typer.ml +++ b/src/typing/typer.ml @@ -67,7 +67,7 @@ let mk_infos ctx p params = let check_assign ctx e = match e.eexpr with - | TLocal {v_extra = None} | TArray _ | TField _ -> + | TLocal {v_extra = None} | TArray _ | TField _ | TIdent _ -> () | TConst TThis | TTypeExpr _ when ctx.untyped -> () @@ -2423,8 +2423,7 @@ and type_ident ctx i p mode = AKExpr (mk (TConst TThis) ctx.tthis p) else let t = mk_mono() in - let v = alloc_unbound_var i t p in - AKExpr (mk (TLocal v) t p) + AKExpr ((mk (TIdent i)) t p) end else begin if ctx.curfun = FunStatic && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p; begin try @@ -2447,11 +2446,11 @@ and type_ident ctx i p mode = | DMDiagnostics b when b || ctx.is_display_file -> Display.ToplevelCollector.handle_unresolved_identifier ctx i p false; let t = mk_mono() in - AKExpr (mk (TLocal (add_unbound_local ctx i t p)) t p) + AKExpr (mk (TIdent i) t p) | _ -> display_error ctx (error_msg err) p; let t = mk_mono() in - AKExpr (mk (TLocal (add_unbound_local ctx i t p)) t p) + AKExpr (mk (TIdent i) t p) end end @@ -2679,7 +2678,7 @@ and type_vars ctx vl p = with Error (e,p) -> check_error ctx e p; - add_unbound_local ctx v t_dynamic pv, None + add_local ctx v t_dynamic pv, None (* TODO: What to do with this... *) ) vl in match vl with | [v,eo] -> @@ -4063,8 +4062,8 @@ and type_call ctx e el (with_type:with_type) p = | _ -> e in - let v_trace = alloc_unbound_var "`trace" t_dynamic p in - mk (TCall (mk (TLocal v_trace) t_dynamic p,[e;infos])) ctx.t.tvoid p + let e_trace = mk (TIdent "`trace") t_dynamic p in + mk (TCall (e_trace,[e;infos])) ctx.t.tvoid p else type_expr ctx (ECall ((EField ((EField ((EConst (Ident "haxe"),p),"Log"),p),"trace"),p),[mk_to_string_meta e;infos]),p) NoValue | (EField ((EConst (Ident "super"),_),_),_), _ -> @@ -4093,8 +4092,8 @@ and type_call ctx e el (with_type:with_type) p = let e = type_expr ctx e Value in if Common.platform ctx.com Flash then let t = tfun [e.etype] e.etype in - let v_unprotect = alloc_unbound_var "__unprotect__" t p in - mk (TCall (mk (TLocal v_unprotect) t p,[e])) e.etype e.epos + let e_unprotect = mk (TIdent "__unprotect__") t p in + mk (TCall (e_unprotect,[e])) e.etype e.epos else e | (EDisplay((EConst (Ident "super"),_ as e1),false),_),_ -> diff --git a/std/haxe/macro/Type.hx b/std/haxe/macro/Type.hx index 3f47c529bed..19d03d95ab1 100644 --- a/std/haxe/macro/Type.hx +++ b/std/haxe/macro/Type.hx @@ -974,6 +974,11 @@ enum TypedExprDef { Access to an enum index (generated by the pattern matcher). **/ TEnumIndex(e1:TypedExpr); + + /** + An unknown identifier. + **/ + TIdent(s:String); } /** diff --git a/std/haxe/macro/TypedExprTools.hx b/std/haxe/macro/TypedExprTools.hx index 48369bb70ef..8ef9f396430 100644 --- a/std/haxe/macro/TypedExprTools.hx +++ b/std/haxe/macro/TypedExprTools.hx @@ -47,7 +47,7 @@ class TypedExprTools { **/ static public function map(e:TypedExpr, f:TypedExpr -> TypedExpr):TypedExpr { return switch(e.expr) { - case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_): e; + case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_) | TIdent(_): e; case TArray(e1, e2): with(e, TArray(f(e1), f(e2))); case TBinop(op, e1, e2): with(e, TBinop(op, f(e1), f(e2))); case TFor(v, e1, e2): with(e, TFor(v, f(e1), f(e2))); @@ -83,7 +83,7 @@ class TypedExprTools { **/ static public function iter(e:TypedExpr, f:TypedExpr -> Void):Void { switch(e.expr) { - case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_): + case TConst(_) | TLocal(_) | TBreak | TContinue | TTypeExpr(_) | TIdent(_): case TArray(e1, e2) | TBinop(_, e1, e2) | TFor(_, e1, e2) | TWhile(e1, e2, _): f(e1); f(e2); @@ -128,7 +128,7 @@ class TypedExprTools { **/ static public function mapWithType(e:TypedExpr, f:TypedExpr -> TypedExpr, ft:Type -> Type, fv:TVar -> TVar):TypedExpr { return switch(e.expr) { - case TConst(_) | TBreak | TContinue | TTypeExpr(_): with(e, ft(e.t)); + case TConst(_) | TBreak | TContinue | TTypeExpr(_) | TIdent(_): with(e, ft(e.t)); case TLocal(v): with(e, TLocal(fv(v)), ft(e.t)); case TArray(e1, e2): with(e, TArray(f(e1), f(e2)), ft(e.t)); case TBinop(op, e1, e2): with(e, TBinop(op, f(e1), f(e2)), ft(e.t));