Skip to content

Commit ff3f3ef

Browse files
authored
[filters] Add AtomicLazy, use it for exceptions (#12340)
* Add AtomicLazy, use it for exceptions * Use a mutex * Whoops, partial update is bad.. * Simplify * Match again inside mutex
1 parent 8d19bc5 commit ff3f3ef

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

src/core/ds/atomicLazy.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
open Atomic
2+
3+
type 'a t = {
4+
mutable value: 'a option;
5+
mutex: Mutex.t;
6+
compute: unit->'a
7+
}
8+
9+
let from_fun f =
10+
{ value = None; mutex = Mutex.create (); compute = (fun () -> f()) }
11+
12+
let force lazy_val =
13+
match lazy_val.value with
14+
| None ->
15+
Mutex.protect lazy_val.mutex (fun () ->
16+
match lazy_val.value with
17+
| None ->
18+
let result = lazy_val.compute () in
19+
lazy_val.value <- Some result;
20+
result
21+
| Some result -> result
22+
)
23+
| Some v -> v
24+

src/filters/exception/exceptionInit.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ open Exceptions
66
open Type
77
open Typecore
88
open ExceptionFunctions
9+
open AtomicLazy
910

1011
let create_exception_context tctx =
1112
match tctx.com.platform with (* TODO: implement for all targets *)
@@ -28,15 +29,15 @@ let create_exception_context tctx =
2829
let t = Typeload.load_instance tctx (tp config.ec_base_throw) ParamSpawnMonos LoadNormal in
2930
if is_dynamic t then t_dynamic
3031
else t
31-
and haxe_exception = Lazy.from_fun (fun () ->
32+
and haxe_exception = AtomicLazy.from_fun (fun () ->
3233
match Typeload.load_instance tctx (tp haxe_exception_type_path) ParamSpawnMonos LoadNormal with
3334
| TInst(cls,_) as t -> t,cls
3435
| _ -> raise_typing_error "haxe.Exception is expected to be a class" null_pos)
35-
and value_exception = Lazy.from_fun (fun () ->
36+
and value_exception = AtomicLazy.from_fun (fun () ->
3637
match Typeload.load_instance tctx (tp value_exception_type_path) ParamSpawnMonos LoadNormal with
3738
| TInst(cls,_) as t -> t,cls
3839
| _ -> raise_typing_error "haxe.ValueException is expected to be a class" null_pos)
39-
and haxe_native_stack_trace = Lazy.from_fun (fun () ->
40+
and haxe_native_stack_trace = AtomicLazy.from_fun (fun () ->
4041
match Typeload.load_instance tctx (tp (["haxe"],"NativeStackTrace")) ParamSpawnMonos LoadNormal with
4142
| TInst(cls,_) -> cls
4243
| TAbstract({ a_impl = Some cls },_) -> cls

src/filters/exception/exceptions.ml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ open Type
33
open PlatformConfig
44
open Error
55
open ExceptionFunctions
6+
open AtomicLazy
67

78
type context = {
89
scom : SafeCom.t;
@@ -12,32 +13,32 @@ type context = {
1213
base_throw_type : Type.t;
1314
throws_anything : bool;
1415
catches_anything : bool;
15-
haxe_exception : (Type.t * tclass) Lazy.t;
16-
haxe_native_stack_trace : tclass Lazy.t;
17-
value_exception : (Type.t * tclass) Lazy.t;
16+
haxe_exception : (Type.t * tclass) AtomicLazy.t;
17+
haxe_native_stack_trace : tclass AtomicLazy.t;
18+
value_exception : (Type.t * tclass) AtomicLazy.t;
1819
is_of_type : (tclass * tclass_field * Type.t);
1920
}
2021

2122
let haxe_exception_class ctx =
22-
let cls = snd (Lazy.force ctx.haxe_exception) in
23+
let cls = snd (AtomicLazy.force ctx.haxe_exception) in
2324
assert (ctx.scom.curclass != null_class);
2425
add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
2526
cls
2627

2728
let haxe_exception_type ctx =
28-
let t,cls = Lazy.force ctx.haxe_exception in
29+
let t,cls = AtomicLazy.force ctx.haxe_exception in
2930
assert (ctx.scom.curclass != null_class);
3031
add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
3132
t
3233

3334
let value_exception_class ctx =
34-
let cls = snd (Lazy.force ctx.value_exception) in
35+
let cls = snd (AtomicLazy.force ctx.value_exception) in
3536
assert (ctx.scom.curclass != null_class);
3637
add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
3738
cls
3839

3940
let value_exception_type ctx =
40-
let t,cls = Lazy.force ctx.value_exception in
41+
let t,cls = AtomicLazy.force ctx.value_exception in
4142
assert (ctx.scom.curclass != null_class);
4243
add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
4344
t

src/filters/exception/saveStacks.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ open Type
44
open Error
55
open ExceptionFunctions
66
open Exceptions
7+
open AtomicLazy
78

89
(**
910
Inserts `haxe.NativeStackTrace.saveStack(e)` in non-haxe.Exception catches.
@@ -20,7 +21,7 @@ let insert_save_stacks ectx scom =
2021
check_expr contains_insertion_points e
2122
in
2223
let save_exception_stack catch_var =
23-
let native_stack_trace_cls = Lazy.force ectx.haxe_native_stack_trace in
24+
let native_stack_trace_cls = AtomicLazy.force ectx.haxe_native_stack_trace in
2425
let method_field =
2526
try PMap.find "saveStack" native_stack_trace_cls.cl_statics
2627
with Not_found -> raise_typing_error ("haxe.NativeStackTrace has no field saveStack") catch_var.v_pos
@@ -65,7 +66,7 @@ let insert_save_stacks ectx scom =
6566
Adds `this.__shiftStack()` calls to constructors of classes which extend `haxe.Exception`
6667
*)
6768
let patch_constructors ectx =
68-
match fst (Lazy.force ectx.haxe_exception) with
69+
match fst (AtomicLazy.force ectx.haxe_exception) with
6970
(* Add only if `__shiftStack` method exists *)
7071
| TInst(cls,_) when PMap.mem "__shiftStack" cls.cl_fields ->
7172
(fun mt ->

0 commit comments

Comments
 (0)