@@ -10,20 +10,29 @@ use crate::wrappers::object::NativeObject;
1010use crate :: wrappers:: object_handle:: NativeObjectHandle ;
1111use cubesql:: CubeError ;
1212use neon:: prelude:: * ;
13- use std:: cell:: { RefCell , RefMut } ;
14- use std:: marker :: PhantomData ;
13+ use std:: cell:: RefCell ;
14+ use std:: panic :: { catch_unwind , resume_unwind , AssertUnwindSafe } ;
1515use std:: rc:: { Rc , Weak } ;
16- pub struct ContextWrapper < ' cx , C : Context < ' cx > > {
16+
17+ pub trait NoenContextLifetimeExpand < ' cx > {
18+ type ExpandedResult : Context < ' static > ;
19+ fn expand_lifetime ( self ) -> Self :: ExpandedResult ;
20+ }
21+
22+ impl < ' cx > NoenContextLifetimeExpand < ' cx > for FunctionContext < ' cx > {
23+ type ExpandedResult = FunctionContext < ' static > ;
24+ fn expand_lifetime ( self ) -> Self :: ExpandedResult {
25+ unsafe { std:: mem:: transmute :: < FunctionContext < ' cx > , FunctionContext < ' static > > ( self ) }
26+ }
27+ }
28+
29+ pub struct ContextWrapper < C : Context < ' static > > {
1730 cx : C ,
18- lifetime : PhantomData < & ' cx ( ) > ,
1931}
2032
21- impl < ' cx , C : Context < ' cx > > ContextWrapper < ' cx , C > {
33+ impl < C : Context < ' static > > ContextWrapper < C > {
2234 pub fn new ( cx : C ) -> Rc < RefCell < Self > > {
23- Rc :: new ( RefCell :: new ( Self {
24- cx,
25- lifetime : Default :: default ( ) ,
26- } ) )
35+ Rc :: new ( RefCell :: new ( Self { cx } ) )
2736 }
2837
2938 pub fn with_context < T , F > ( & mut self , f : F ) -> T
@@ -38,125 +47,105 @@ impl<'cx, C: Context<'cx>> ContextWrapper<'cx, C> {
3847 }
3948}
4049
41- pub struct ContextHolder < ' cx , C : Context < ' cx > > {
42- context : Rc < RefCell < ContextWrapper < ' cx , C > > > ,
50+ pub fn neon_run_with_guarded_lifetime < ' cx , C , T , F > ( cx : C , func : F ) -> T
51+ where
52+ C : Context < ' cx > + NoenContextLifetimeExpand < ' cx > ,
53+ F : FnOnce ( ContextHolder < C :: ExpandedResult > ) -> T ,
54+ {
55+ let context = ContextWrapper :: new ( cx. expand_lifetime ( ) ) ;
56+ let context_holder = ContextHolder :: new ( Rc :: downgrade ( & context) ) ;
57+ let res = catch_unwind ( AssertUnwindSafe ( || func ( context_holder) ) ) ;
58+ match Rc :: try_unwrap ( context) {
59+ Ok ( _) => { }
60+ Err ( _) => panic ! ( "Guarded context have more then one reference" ) ,
61+ } ;
62+
63+ match res {
64+ Ok ( res) => res,
65+ Err ( e) => resume_unwind ( e) ,
66+ }
4367}
4468
45- impl < ' cx , C : Context < ' cx > + ' cx > ContextHolder < ' cx , C > {
46- pub fn new ( cx : C ) -> Self {
47- Self {
48- context : ContextWrapper :: new ( cx) ,
49- }
50- }
69+ pub struct ContextHolder < C : Context < ' static > > {
70+ context : Weak < RefCell < ContextWrapper < C > > > ,
71+ }
5172
52- pub fn borrow_mut ( & self ) -> RefMut < ContextWrapper < ' cx , C > > {
53- self . context . borrow_mut ( )
73+ impl < C : Context < ' static > > ContextHolder < C > {
74+ fn new ( context : Weak < RefCell < ContextWrapper < C > > > ) -> Self {
75+ Self { context }
5476 }
5577
56- pub fn with_context < T , F > ( & self , f : F ) -> T
78+ pub fn with_context < T , F > ( & self , f : F ) -> Result < T , CubeError >
5779 where
5880 F : FnOnce ( & mut C ) -> T ,
5981 {
60- let mut context = self . context . borrow_mut ( ) ;
61- context. with_context ( f)
62- }
63-
64- pub fn weak ( & self ) -> WeakContextHolder < ' cx , C > {
65- WeakContextHolder {
66- context : Rc :: downgrade ( & self . context ) ,
82+ if let Some ( context) = self . context . upgrade ( ) {
83+ let mut cx = context. borrow_mut ( ) ;
84+ let res = cx. with_context ( f) ;
85+ Ok ( res)
86+ } else {
87+ Err ( CubeError :: internal ( format ! (
88+ "Call to neon context outside of its lifetime"
89+ ) ) )
6790 }
6891 }
6992}
7093
71- impl < ' cx , C : Context < ' cx > + ' cx > NativeContext < NeonInnerTypes < ' cx , C > > for ContextHolder < ' cx , C > {
72- fn boolean ( & self , v : bool ) -> NeonBoolean < ' cx , C > {
73- let obj = NeonObject :: new ( self . clone ( ) , self . with_context ( |cx| cx. boolean ( v) . upcast ( ) ) ) ;
74- obj. into_boolean ( ) . unwrap ( )
94+ impl < C : Context < ' static > + ' static > NativeContext < NeonInnerTypes < C > > for ContextHolder < C > {
95+ fn boolean ( & self , v : bool ) -> Result < NeonBoolean < C > , CubeError > {
96+ let obj = NeonObject :: new (
97+ self . clone ( ) ,
98+ self . with_context ( |cx| cx. boolean ( v) . upcast ( ) ) ?,
99+ ) ;
100+ obj. into_boolean ( )
75101 }
76102
77- fn string ( & self , v : String ) -> NeonString < ' cx , C > {
78- let obj = NeonObject :: new ( self . clone ( ) , self . with_context ( |cx| cx. string ( v) . upcast ( ) ) ) ;
79- obj. into_string ( ) . unwrap ( )
103+ fn string ( & self , v : String ) -> Result < NeonString < C > , CubeError > {
104+ let obj = NeonObject :: new ( self . clone ( ) , self . with_context ( |cx| cx. string ( v) . upcast ( ) ) ? ) ;
105+ obj. into_string ( )
80106 }
81107
82- fn number ( & self , v : f64 ) -> NeonNumber < ' cx , C > {
83- let obj = NeonObject :: new ( self . clone ( ) , self . with_context ( |cx| cx. number ( v) . upcast ( ) ) ) ;
84- obj. into_number ( ) . unwrap ( )
108+ fn number ( & self , v : f64 ) -> Result < NeonNumber < C > , CubeError > {
109+ let obj = NeonObject :: new ( self . clone ( ) , self . with_context ( |cx| cx. number ( v) . upcast ( ) ) ? ) ;
110+ obj. into_number ( )
85111 }
86112
87- fn undefined ( & self ) -> NativeObjectHandle < NeonInnerTypes < ' cx , C > > {
88- NativeObjectHandle :: new ( NeonObject :: new (
113+ fn undefined ( & self ) -> Result < NativeObjectHandle < NeonInnerTypes < C > > , CubeError > {
114+ Ok ( NativeObjectHandle :: new ( NeonObject :: new (
89115 self . clone ( ) ,
90- self . with_context ( |cx| cx. undefined ( ) . upcast ( ) ) ,
91- ) )
116+ self . with_context ( |cx| cx. undefined ( ) . upcast ( ) ) ? ,
117+ ) ) )
92118 }
93119
94- fn empty_array ( & self ) -> NeonArray < ' cx , C > {
120+ fn empty_array ( & self ) -> Result < NeonArray < C > , CubeError > {
95121 let obj = NeonObject :: new (
96122 self . clone ( ) ,
97- self . with_context ( |cx| cx. empty_array ( ) . upcast ( ) ) ,
123+ self . with_context ( |cx| cx. empty_array ( ) . upcast ( ) ) ? ,
98124 ) ;
99- obj. into_array ( ) . unwrap ( )
125+ obj. into_array ( )
100126 }
101127
102- fn empty_struct ( & self ) -> NeonStruct < ' cx , C > {
128+ fn empty_struct ( & self ) -> Result < NeonStruct < C > , CubeError > {
103129 let obj = NeonObject :: new (
104130 self . clone ( ) ,
105- self . with_context ( |cx| cx. empty_object ( ) . upcast ( ) ) ,
131+ self . with_context ( |cx| cx. empty_object ( ) . upcast ( ) ) ? ,
106132 ) ;
107- obj. into_struct ( ) . unwrap ( )
133+ obj. into_struct ( )
108134 }
109- fn to_string_fn ( & self , result : String ) -> NeonFunction < ' cx , C > {
135+ fn to_string_fn ( & self , result : String ) -> Result < NeonFunction < C > , CubeError > {
110136 let obj = NeonObject :: new (
111137 self . clone ( ) ,
112138 self . with_context ( |cx| {
113139 JsFunction :: new ( cx, move |mut c| Ok ( c. string ( result. clone ( ) ) ) )
114140 . unwrap ( )
115141 . upcast ( )
116- } ) ,
142+ } ) ? ,
117143 ) ;
118- obj. into_function ( ) . unwrap ( )
119- }
120- }
121-
122- impl < ' cx , C : Context < ' cx > > Clone for ContextHolder < ' cx , C > {
123- fn clone ( & self ) -> Self {
124- Self {
125- context : self . context . clone ( ) ,
126- }
127- }
128- }
129-
130- pub struct WeakContextHolder < ' cx , C : Context < ' cx > > {
131- context : Weak < RefCell < ContextWrapper < ' cx , C > > > ,
132- }
133-
134- impl < ' cx , C : Context < ' cx > > WeakContextHolder < ' cx , C > {
135- pub fn try_upgrade < ' a > ( & ' a self ) -> Result < ContextHolder < ' a , C > , CubeError >
136- where
137- ' a : ' cx ,
138- {
139- if let Some ( context) = self . context . upgrade ( ) {
140- Ok ( ContextHolder { context } )
141- } else {
142- Err ( CubeError :: internal ( format ! ( "Neon context is not alive" ) ) )
143- }
144- }
145- pub fn with_context < T , F > ( & self , f : F ) -> Result < T , CubeError >
146- where
147- F : FnOnce ( & mut C ) -> T ,
148- {
149- if let Some ( context) = self . context . upgrade ( ) {
150- let mut cx = context. borrow_mut ( ) ;
151- let res = cx. with_context ( f) ;
152- Ok ( res)
153- } else {
154- Err ( CubeError :: internal ( format ! ( "Neon context is not alive" ) ) )
155- }
144+ obj. into_function ( )
156145 }
157146}
158147
159- impl < ' cx , C : Context < ' cx > > Clone for WeakContextHolder < ' cx , C > {
148+ impl < C : Context < ' static > > Clone for ContextHolder < C > {
160149 fn clone ( & self ) -> Self {
161150 Self {
162151 context : self . context . clone ( ) ,
0 commit comments