Skip to content

Commit b224999

Browse files
authored
[js] rework exception handling (closes #6458) (#6713)
* [js] rework exception handling (closes #6458) * [js] add js.Lib.getOriginalException * [js] adjust optimization tests for try/catch * [js] add tests for generated code for getOriginalException and rethrow * minor improvements * inject haxe.CallStack.lastException assignment in a separate post-DCE filter, so it doesn't interfere with purity inference and can make more informed decision whether it's actually needed * don't forget to recurse into try/catch expressions
1 parent 530ddc5 commit b224999

File tree

8 files changed

+321
-198
lines changed

8 files changed

+321
-198
lines changed

src/filters/filters.ml

+4-78
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ open Type
2323
open Typecore
2424
open Error
2525
open Globals
26+
open FiltersCommon
2627

2728
(** retrieve string from @:native metadata or raise Not_found *)
2829
let get_native_name meta =
@@ -81,33 +82,6 @@ let rec add_final_return e =
8182
{ e with eexpr = TFunction f }
8283
| _ -> e
8384

84-
let rec wrap_js_exceptions com e =
85-
let rec is_error t =
86-
match follow t with
87-
| TInst ({cl_path = (["js"],"Error")},_) -> true
88-
| TInst ({cl_super = Some (csup,tl)}, _) -> is_error (TInst (csup,tl))
89-
| _ -> false
90-
in
91-
let rec loop e =
92-
match e.eexpr with
93-
| TThrow eerr when not (is_error eerr.etype) ->
94-
let terr = List.find (fun mt -> match mt with TClassDecl {cl_path = ["js";"_Boot"],"HaxeError"} -> true | _ -> false) com.types in
95-
let cerr = match terr with TClassDecl c -> c | _ -> assert false in
96-
(match eerr.etype with
97-
| TDynamic _ ->
98-
let eterr = Texpr.Builder.make_static_this cerr e.epos in
99-
let ewrap = Texpr.Builder.fcall eterr "wrap" [eerr] t_dynamic e.epos in
100-
{ e with eexpr = TThrow ewrap }
101-
| _ ->
102-
let ewrap = { eerr with eexpr = TNew (cerr,[],[eerr]); etype = TInst (cerr,[]) } in
103-
{ e with eexpr = TThrow ewrap }
104-
)
105-
| _ ->
106-
Type.map_expr loop e
107-
in
108-
109-
loop e
110-
11185
(* -------------------------------------------------------------------------- *)
11286
(* CHECK LOCAL VARS INIT *)
11387

@@ -441,25 +415,6 @@ let save_class_state ctx t = match t with
441415

442416
(* PASS 2 begin *)
443417

444-
let rec is_removable_class c =
445-
match c.cl_kind with
446-
| KGeneric ->
447-
(Meta.has Meta.Remove c.cl_meta ||
448-
(match c.cl_super with
449-
| Some (c,_) -> is_removable_class c
450-
| _ -> false) ||
451-
List.exists (fun (_,t) -> match follow t with
452-
| TInst(c,_) ->
453-
has_ctor_constraint c || Meta.has Meta.Const c.cl_meta
454-
| _ ->
455-
false
456-
) c.cl_params)
457-
| KTypeParameter _ ->
458-
(* this shouldn't happen, have to investigate (see #4092) *)
459-
true
460-
| _ ->
461-
false
462-
463418
let remove_generic_base ctx t = match t with
464419
| TClassDecl c when is_removable_class c ->
465420
c.cl_extern <- true
@@ -776,37 +731,6 @@ let check_reserved_type_paths ctx t =
776731

777732
(* PASS 3 end *)
778733

779-
let run_expression_filters ctx filters t =
780-
let run e =
781-
List.fold_left (fun e f -> f e) e filters
782-
in
783-
match t with
784-
| TClassDecl c when is_removable_class c -> ()
785-
| TClassDecl c ->
786-
ctx.curclass <- c;
787-
let rec process_field f =
788-
ctx.curfield <- f;
789-
(match f.cf_expr with
790-
| Some e when not (is_removable_field ctx f) ->
791-
AbstractCast.cast_stack := f :: !AbstractCast.cast_stack;
792-
f.cf_expr <- Some (run e);
793-
AbstractCast.cast_stack := List.tl !AbstractCast.cast_stack;
794-
| _ -> ());
795-
List.iter process_field f.cf_overloads
796-
in
797-
List.iter process_field c.cl_ordered_fields;
798-
List.iter process_field c.cl_ordered_statics;
799-
(match c.cl_constructor with
800-
| None -> ()
801-
| Some f -> process_field f);
802-
(match c.cl_init with
803-
| None -> ()
804-
| Some e ->
805-
c.cl_init <- Some (run e));
806-
| TEnumDecl _ -> ()
807-
| TTypeDecl _ -> ()
808-
| TAbstractDecl _ -> ()
809-
810734
let pp_counter = ref 1
811735

812736
let is_cached t =
@@ -869,6 +793,8 @@ let run com tctx main =
869793
filters @ [
870794
TryCatchWrapper.configure_java com
871795
]
796+
| Js ->
797+
filters @ [JsExceptions.init tctx];
872798
| _ -> filters
873799
in
874800
let t = filter_timer detail_times ["expr 1"] in
@@ -897,7 +823,6 @@ let run com tctx main =
897823
let filters = [
898824
Optimizer.sanitize com;
899825
if com.config.pf_add_final_return then add_final_return else (fun e -> e);
900-
if com.platform = Js then wrap_js_exceptions com else (fun e -> e);
901826
rename_local_vars tctx reserved;
902827
mark_switch_break_loops;
903828
] in
@@ -949,6 +874,7 @@ let run com tctx main =
949874
] in
950875
let type_filters = match com.platform with
951876
| Cs -> type_filters @ [ fun _ t -> InterfaceProps.run t ]
877+
| Js -> JsExceptions.inject_callstack com type_filters
952878
| _ -> type_filters
953879
in
954880
let t = filter_timer detail_times ["type 3"] in

src/filters/filtersCommon.ml

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
(*
2+
The Haxe Compiler
3+
Copyright (C) 2005-2017 Haxe Foundation
4+
5+
This program is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU General Public License
7+
as published by the Free Software Foundation; either version 2
8+
of the License, or (at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*)
19+
open Type
20+
open Typecore
21+
22+
let rec is_removable_class c =
23+
match c.cl_kind with
24+
| KGeneric ->
25+
(Meta.has Meta.Remove c.cl_meta ||
26+
(match c.cl_super with
27+
| Some (c,_) -> is_removable_class c
28+
| _ -> false) ||
29+
List.exists (fun (_,t) -> match follow t with
30+
| TInst(c,_) ->
31+
has_ctor_constraint c || Meta.has Meta.Const c.cl_meta
32+
| _ ->
33+
false
34+
) c.cl_params)
35+
| KTypeParameter _ ->
36+
(* this shouldn't happen, have to investigate (see #4092) *)
37+
true
38+
| _ ->
39+
false
40+
41+
let run_expression_filters ctx filters t =
42+
let run e =
43+
List.fold_left (fun e f -> f e) e filters
44+
in
45+
match t with
46+
| TClassDecl c when is_removable_class c -> ()
47+
| TClassDecl c ->
48+
ctx.curclass <- c;
49+
let rec process_field f =
50+
ctx.curfield <- f;
51+
(match f.cf_expr with
52+
| Some e when not (is_removable_field ctx f) ->
53+
AbstractCast.cast_stack := f :: !AbstractCast.cast_stack;
54+
f.cf_expr <- Some (run e);
55+
AbstractCast.cast_stack := List.tl !AbstractCast.cast_stack;
56+
| _ -> ());
57+
List.iter process_field f.cf_overloads
58+
in
59+
List.iter process_field c.cl_ordered_fields;
60+
List.iter process_field c.cl_ordered_statics;
61+
(match c.cl_constructor with
62+
| None -> ()
63+
| Some f -> process_field f);
64+
(match c.cl_init with
65+
| None -> ()
66+
| Some e ->
67+
c.cl_init <- Some (run e));
68+
| TEnumDecl _ -> ()
69+
| TTypeDecl _ -> ()
70+
| TAbstractDecl _ -> ()

0 commit comments

Comments
 (0)