11use crate :: {
2- error:: Error :: * , map:: LayeredHashMap , resolved_lazy_val , FutureWrapper , LazyBinding , LazyVal ,
3- ObjValue , Result , Val ,
2+ error:: Error :: * , map:: LayeredHashMap , FutureWrapper , LazyBinding , LazyVal , ObjValue , Result ,
3+ Val ,
44} ;
5+ use gc:: { Finalize , Gc , Trace } ;
56use jrsonnet_interner:: IStr ;
67use rustc_hash:: FxHashMap ;
8+ use std:: fmt:: Debug ;
79use std:: hash:: BuildHasherDefault ;
8- use std:: { fmt:: Debug , rc:: Rc } ;
910
10- #[ derive( Clone ) ]
11+ #[ derive( Clone , Trace , Finalize ) ]
1112pub struct ContextCreator ( pub Context , pub FutureWrapper < FxHashMap < IStr , LazyBinding > > ) ;
1213impl ContextCreator {
1314 pub fn create ( & self , this : Option < ObjValue > , super_obj : Option < ObjValue > ) -> Result < Context > {
@@ -20,6 +21,7 @@ impl ContextCreator {
2021 }
2122}
2223
24+ #[ derive( Trace , Finalize ) ]
2325struct ContextInternals {
2426 dollar : Option < ObjValue > ,
2527 this : Option < ObjValue > ,
@@ -28,15 +30,12 @@ struct ContextInternals {
2830}
2931impl Debug for ContextInternals {
3032 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
31- f. debug_struct ( "Context" )
32- . field ( "this" , & self . this . as_ref ( ) . map ( |e| Rc :: as_ptr ( & e. 0 ) ) )
33- . field ( "bindings" , & self . bindings )
34- . finish ( )
33+ f. debug_struct ( "Context" ) . finish ( )
3534 }
3635}
3736
38- #[ derive( Debug , Clone ) ]
39- pub struct Context ( Rc < ContextInternals > ) ;
37+ #[ derive( Debug , Clone , Trace , Finalize ) ]
38+ pub struct Context ( Gc < ContextInternals > ) ;
4039impl Context {
4140 pub fn new_future ( ) -> FutureWrapper < Self > {
4241 FutureWrapper :: new ( )
@@ -55,7 +54,7 @@ impl Context {
5554 }
5655
5756 pub fn new ( ) -> Self {
58- Self ( Rc :: new ( ContextInternals {
57+ Self ( Gc :: new ( ContextInternals {
5958 dollar : None ,
6059 this : None ,
6160 super_obj : None ,
@@ -81,7 +80,7 @@ impl Context {
8180 pub fn with_var ( self , name : IStr , value : Val ) -> Self {
8281 let mut new_bindings =
8382 FxHashMap :: with_capacity_and_hasher ( 1 , BuildHasherDefault :: default ( ) ) ;
84- new_bindings. insert ( name, resolved_lazy_val ! ( value) ) ;
83+ new_bindings. insert ( name, LazyVal :: new_resolved ( value) ) ;
8584 self . extend ( new_bindings, None , None , None )
8685 }
8786
@@ -96,40 +95,21 @@ impl Context {
9695 new_this : Option < ObjValue > ,
9796 new_super_obj : Option < ObjValue > ,
9897 ) -> Self {
99- match Rc :: try_unwrap ( self . 0 ) {
100- Ok ( mut ctx) => {
101- // Extended context aren't used by anything else, we can freely mutate it without cloning
102- if let Some ( dollar) = new_dollar {
103- ctx. dollar = Some ( dollar) ;
104- }
105- if let Some ( this) = new_this {
106- ctx. this = Some ( this) ;
107- }
108- if let Some ( super_obj) = new_super_obj {
109- ctx. super_obj = Some ( super_obj) ;
110- }
111- if !new_bindings. is_empty ( ) {
112- ctx. bindings = ctx. bindings . extend ( new_bindings) ;
113- }
114- Self ( Rc :: new ( ctx) )
115- }
116- Err ( ctx) => {
117- let dollar = new_dollar. or_else ( || ctx. dollar . clone ( ) ) ;
118- let this = new_this. or_else ( || ctx. this . clone ( ) ) ;
119- let super_obj = new_super_obj. or_else ( || ctx. super_obj . clone ( ) ) ;
120- let bindings = if new_bindings. is_empty ( ) {
121- ctx. bindings . clone ( )
122- } else {
123- ctx. bindings . clone ( ) . extend ( new_bindings)
124- } ;
125- Self ( Rc :: new ( ContextInternals {
126- dollar,
127- this,
128- super_obj,
129- bindings,
130- } ) )
131- }
132- }
98+ let ctx = & self . 0 ;
99+ let dollar = new_dollar. or_else ( || ctx. dollar . clone ( ) ) ;
100+ let this = new_this. or_else ( || ctx. this . clone ( ) ) ;
101+ let super_obj = new_super_obj. or_else ( || ctx. super_obj . clone ( ) ) ;
102+ let bindings = if new_bindings. is_empty ( ) {
103+ ctx. bindings . clone ( )
104+ } else {
105+ ctx. bindings . clone ( ) . extend ( new_bindings)
106+ } ;
107+ Self ( Gc :: new ( ContextInternals {
108+ dollar,
109+ this,
110+ super_obj,
111+ bindings,
112+ } ) )
133113 }
134114 pub fn extend_bound ( self , new_bindings : FxHashMap < IStr , LazyVal > ) -> Self {
135115 let new_this = self . 0 . this . clone ( ) ;
@@ -166,22 +146,6 @@ impl Default for Context {
166146
167147impl PartialEq for Context {
168148 fn eq ( & self , other : & Self ) -> bool {
169- Rc :: ptr_eq ( & self . 0 , & other. 0 )
170- }
171- }
172-
173- #[ cfg( feature = "unstable" ) ]
174- #[ derive( Debug , Clone ) ]
175- pub struct WeakContext ( std:: rc:: Weak < ContextInternals > ) ;
176- #[ cfg( feature = "unstable" ) ]
177- impl WeakContext {
178- pub fn upgrade ( & self ) -> Context {
179- Context ( self . 0 . upgrade ( ) . expect ( "context is removed" ) )
180- }
181- }
182- #[ cfg( feature = "unstable" ) ]
183- impl PartialEq for WeakContext {
184- fn eq ( & self , other : & Self ) -> bool {
185- self . 0 . ptr_eq ( & other. 0 )
149+ Gc :: ptr_eq ( & self . 0 , & other. 0 )
186150 }
187151}
0 commit comments