Răsfoiți Sursa

[java/cs] Complex return w/ statement w/ throw now works correctly;
Distinction between calling a parameter explicitly or needing to be inferred; inferred cases are handled correctly
Closure now casts to function type to prevent some target-specific unifications

Caue Waneck 12 ani în urmă
părinte
comite
a11c6bfff5
3 a modificat fișierele cu 25 adăugiri și 21 ștergeri
  1. 22 18
      gencommon.ml
  2. 2 2
      gencs.ml
  3. 1 1
      genjava.ml

+ 22 - 18
gencommon.ml

@@ -2626,9 +2626,9 @@ struct
                 let rec loop must_wrap_catches = match must_wrap_catches with
                   | (vcatch,catch) :: tl ->
                     { eexpr = TIf(mk_std_is vcatch.v_type catch.epos,
-                      { eexpr = TBlock({ eexpr=TVars([vcatch, Some(mk_cast vcatch.v_type catchall_local)]); etype=gen.gcon.basic.tvoid; epos=catch.epos } :: [catch] ); etype = gen.gcon.basic.tvoid; epos = catch.epos },
+                      { eexpr = TBlock({ eexpr=TVars([vcatch, Some(mk_cast vcatch.v_type catchall_local)]); etype=gen.gcon.basic.tvoid; epos=catch.epos } :: [catch] ); etype = catch.etype; epos = catch.epos },
                       Some (loop tl));
-                    etype = gen.gcon.basic.tvoid; epos = catch.epos }
+                    etype = catch.etype; epos = catch.epos }
                   | [] ->
                     match catchall with
                       | Some (v,s) ->
@@ -3722,11 +3722,11 @@ struct
   (* this function will receive the original function argument, the applied function argument and the original function parameters. *)
   (* from this info, it will infer the applied tparams for the function *)
   (* this function is used by CastDetection module *)
-  let infer_params gen pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t) list) impossible_tparam_is_dynamic : tparams =
+  let infer_params gen pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t) list) calls_parameters_explicitly : tparams =
     match params with
     | [] -> []
     | _ ->
-      let args_list args = (if impossible_tparam_is_dynamic then t_dynamic else snd args) :: (List.map (fun (n,o,t) -> t) (fst args)) in
+      let args_list args = (if not calls_parameters_explicitly then t_dynamic else snd args) :: (List.map (fun (n,o,t) -> t) (fst args)) in
 
       let monos = List.map (fun _ -> mk_mono()) params in
       let original = args_list (get_fun (apply_params params monos (TFun(fst original_args,snd original_args)))) in
@@ -4954,7 +4954,7 @@ struct
       | TVars([v,Some({ eexpr = TBinop(Ast.OpBoolAnd,_,_) } as right)])
       | TVars([v,Some({ eexpr = TBinop(Ast.OpBoolOr,_,_) } as right)]) ->
         let right = short_circuit_op_unwrap gen add_statement right in
-        Some { expr with eexpr = TVars([v, Some(right)]); etype = v.v_type }
+        Some { expr with eexpr = TVars([v, Some(right)]) }
       | TVars([v,Some(right)]) when shallow_expr_type right = Statement ->
         add_statement ({ expr with eexpr = TVars([v, Some(null right.etype right.epos)]) });
         handle_assign Ast.OpAssign { expr with eexpr = TLocal(v); etype = v.v_type } right
@@ -5030,8 +5030,8 @@ struct
                 let kinds = get_kinds e in
                 if has_problematic_expressions kinds then begin
                   match try_call_unwrap_statement gen problematic_expression_unwrap add_statement e with
-                    | Some { eexpr = TConst(TNull) } (* no op *) ->
-                      ()
+                    | Some { eexpr = TConst(TNull) } (* no op *)
+                    | Some { eexpr = TBlock [] } -> ()
                     | Some e ->
                       if has_problematic_expressions (get_kinds e) then begin
                         process_statement e
@@ -5160,6 +5160,8 @@ struct
           (* a return must be inside a function *)
           let ret_type = match !current_ret_type with | Some(s) -> s | None -> gen.gcon.error "Invalid return outside function declaration." e.epos; assert false in
           (match eopt with
+          | None when not (is_void ret_type) ->
+            { e with eexpr = TReturn( Some(null ret_type e.epos)) }
           | None -> e
           | Some eret ->
             { e with eexpr = TReturn( Some(handle (run eret) ret_type eret.etype ) ) })
@@ -5672,7 +5674,7 @@ struct
   *)
 
   (* match e.eexpr with | TCall( ({ eexpr = TField(ef, f) }) as e1, elist ) -> *)
-  let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist impossible_tparam_is_dynamic =
+  let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist calls_parameters_explicitly =
     (* the ONLY way to know if this call has parameters is to analyze the calling field. *)
     (* To make matters a little worse, on both C# and Java only in some special cases that type parameters will be used *)
     (* Namely, when using reflection type parameters are useless, of course. This also includes anonymous types *)
@@ -5755,13 +5757,16 @@ struct
           (* infer arguments *)
           (* let called_t = TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype) in *)
           let called_t = match follow e1.etype with | TFun _ -> e1.etype | _ -> TFun(List.map (fun e -> "arg",false,e.etype) elist, ecall.etype)  in (* workaround for issue #1742 *)
-          let fparams = TypeParams.infer_params gen ecall.epos (get_fun (apply_params cl.cl_types params actual_t)) (get_fun called_t) cf.cf_params impossible_tparam_is_dynamic in
-          let real_params = gen.greal_type_param (TClassDecl cl) params in
-          let real_fparams = gen.greal_type_param (TClassDecl cl) fparams in
+          let fparams = TypeParams.infer_params gen ecall.epos (get_fun (apply_params cl.cl_types params actual_t)) (get_fun called_t) cf.cf_params calls_parameters_explicitly in
           (* get what the backend actually sees *)
           (* actual field's function *)
           let actual_t = get_real_fun gen actual_t in
+          let real_params = gen.greal_type_param (TClassDecl cl) params in
           let function_t = apply_params cl.cl_types real_params actual_t in
+          let real_fparams = if calls_parameters_explicitly then
+            gen.greal_type_param (TClassDecl cl) fparams
+          else
+            gen.greal_type_param (TClassDecl cl) (TypeParams.infer_params gen ecall.epos (get_fun function_t) (get_fun (get_real_fun gen called_t)) cf.cf_params calls_parameters_explicitly) in
           let function_t = get_real_fun gen (apply_params cf.cf_params real_fparams function_t) in
           let args_ft, ret_ft = get_fun function_t in
           (* applied function *)
@@ -5850,7 +5855,7 @@ struct
 
   (** overloads_cast_to_base argument will cast overloaded function types to the class that declared it. **)
   (**     This is necessary for C#, and if true, will require the target to implement __as__, as a `quicker` form of casting **)
-  let default_implementation gen ?(native_string_cast = true) ?(overloads_cast_to_base = false) maybe_empty_t impossible_tparam_is_dynamic =
+  let default_implementation gen ?(native_string_cast = true) ?(overloads_cast_to_base = false) maybe_empty_t calls_parameters_explicitly =
     let handle e t1 t2 = handle_cast gen e (gen.greal_type t1) (gen.greal_type t2) in
 
     let in_value = ref false in
@@ -5863,7 +5868,7 @@ struct
         | TBinop ( (Ast.OpAssign | Ast.OpAssignOp _ as op), e1, e2 ) ->
           { e with eexpr = TBinop(op, run ~just_type:true e1, run e2) }
         | TField(ef, f) ->
-          handle_type_parameter gen None e (run ef) ~clean_ef:ef ~overloads_cast_to_base:overloads_cast_to_base f [] impossible_tparam_is_dynamic
+          handle_type_parameter gen None e (run ef) ~clean_ef:ef ~overloads_cast_to_base:overloads_cast_to_base f [] calls_parameters_explicitly
         | TArrayDecl el ->
           let et = e.etype in
           let base_type = match follow et with
@@ -5872,12 +5877,10 @@ struct
           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 = TField({ eexpr = TLocal(v) },_) } as tf), params ) when String.get v.v_name 0 = '_' &&String.get v.v_name 1 = '_' && Hashtbl.mem gen.gspecial_vars v.v_name ->
-          { e with eexpr = TCall(tf, List.map run params) }
         | 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 ->
           { e with eexpr = TCall(local, List.map run 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) impossible_tparam_is_dynamic
+          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
 
         (* the TNew and TSuper code was modified at r6497 *)
         | TCall( { eexpr = TConst TSuper } as ef, eparams ) ->
@@ -8038,13 +8041,14 @@ struct
     let gen = ctx.rcf_gen in
     let basic = gen.gcon.basic in
     let closure_func eclosure e field is_static =
-      { eclosure with
+      mk_cast eclosure.etype { eclosure with
         eexpr = TNew(closure_cl, [], [
           e;
           { eexpr = TConst(TString field); etype = basic.tstring; epos = eclosure.epos }
         ] @ (
           if ctx.rcf_optimize then [ { eexpr = TConst(TInt (hash_field_i32 ctx eclosure.epos field)); etype = basic.tint; epos = eclosure.epos } ] else []
-        ))
+        ));
+        etype = TInst(closure_cl,[])
       }
     in
     closure_func

+ 2 - 2
gencs.ml

@@ -2181,7 +2181,7 @@ let configure gen =
         mk_field_access gen local "obj" pos
       )
       (fun rethrow ->
-        { rethrow with eexpr = TCall(mk_local (alloc_var "__rethrow__" t_dynamic) rethrow.epos, [rethrow]) }
+        { rethrow with eexpr = TCall(mk_local (alloc_var "__rethrow__" t_dynamic) rethrow.epos, [rethrow]); etype = gen.gcon.basic.tvoid }
       )
       (base_exception_t)
       (hx_exception_t)
@@ -2196,7 +2196,7 @@ let configure gen =
     get_typeof e
   ));
 
-  CastDetect.configure gen (CastDetect.default_implementation gen (Some (TEnum(empty_e, []))) false ~native_string_cast:false ~overloads_cast_to_base:true);
+  CastDetect.configure gen (CastDetect.default_implementation gen (Some (TEnum(empty_e, []))) true ~native_string_cast:false ~overloads_cast_to_base:true);
 
   (*FollowAll.configure gen;*)
 

+ 1 - 1
genjava.ml

@@ -2050,7 +2050,7 @@ let configure gen =
     { ecall with eexpr = TCall(efield, elist) }
   );
 
-  CastDetect.configure gen (CastDetect.default_implementation gen ~native_string_cast:false (Some (TEnum(empty_e, []))) true);
+  CastDetect.configure gen (CastDetect.default_implementation gen ~native_string_cast:false (Some (TEnum(empty_e, []))) false);
 
   (*FollowAll.configure gen;*)