@@ -25,79 +25,86 @@ var caml_ephe_key_offset = 3;
2525//Provides: caml_ephe_data_offset
2626var caml_ephe_data_offset = 2 ;
2727
28+ //Provides: caml_ephe_none
29+ var caml_ephe_none = { caml_ephe_none : 0 } ;
30+
2831//Provides: caml_ephe_set_key
2932//Requires: caml_invalid_argument, caml_ephe_key_offset
33+ //Requires: caml_ephe_get_data
34+ //Requires: caml_ephe_set_data_opt
3035function caml_ephe_set_key ( x , i , v ) {
3136 if ( i < 0 || caml_ephe_key_offset + i >= x . length )
3237 caml_invalid_argument ( "Weak.set" ) ;
33- if ( v instanceof Object && globalThis . WeakRef ) {
34- if ( x [ 1 ] . register ) x [ 1 ] . register ( v , undefined , v ) ;
35- x [ caml_ephe_key_offset + i ] = new globalThis . WeakRef ( v ) ;
36- } else x [ caml_ephe_key_offset + i ] = v ;
38+ var old = caml_ephe_get_data ( x ) ;
39+ if ( v instanceof Object && globalThis . WeakRef ) v = new globalThis . WeakRef ( v ) ;
40+ x [ caml_ephe_key_offset + i ] = v ;
41+ caml_ephe_set_data_opt ( x , old ) ;
3742 return 0 ;
3843}
3944
4045//Provides: caml_ephe_unset_key
4146//Requires: caml_invalid_argument, caml_ephe_key_offset
47+ //Requires: caml_ephe_get_data
48+ //Requires: caml_ephe_set_data_opt
49+ //Requires: caml_ephe_none
4250function caml_ephe_unset_key ( x , i ) {
4351 if ( i < 0 || caml_ephe_key_offset + i >= x . length )
4452 caml_invalid_argument ( "Weak.set" ) ;
45- if (
46- globalThis . WeakRef &&
47- x [ caml_ephe_key_offset + i ] instanceof globalThis . WeakRef &&
48- x [ 1 ] . unregister
49- ) {
50- var old = x [ caml_ephe_key_offset + i ] . deref ( ) ;
51- if ( old !== undefined ) {
52- var count = 0 ;
53- for ( var j = caml_ephe_key_offset ; j < x . length ; j ++ ) {
54- var key = x [ j ] ;
55- if ( key instanceof globalThis . WeakRef ) {
56- key = key . deref ( ) ;
57- if ( key === old ) count ++ ;
58- }
59- }
60- if ( count === 1 ) x [ 1 ] . unregister ( old ) ;
61- }
62- }
63- x [ caml_ephe_key_offset + i ] = undefined ;
53+ var old = caml_ephe_get_data ( x ) ;
54+ x [ caml_ephe_key_offset + i ] = caml_ephe_none ;
55+ caml_ephe_set_data_opt ( x , old ) ;
6456 return 0 ;
6557}
6658
6759//Provides: caml_ephe_create
68- //Requires: caml_weak_create, caml_ephe_data_offset
60+ //Requires: caml_weak_create
6961function caml_ephe_create ( n ) {
7062 var x = caml_weak_create ( n ) ;
7163 return x ;
7264}
7365
7466//Provides: caml_weak_create
75- //Requires: caml_ephe_key_offset, caml_invalid_argument,caml_ephe_data_offset
67+ //Requires: caml_ephe_key_offset, caml_invalid_argument
68+ //Requires: caml_ephe_none
7669function caml_weak_create ( n ) {
7770 if ( n < 0 ) caml_invalid_argument ( "Weak.create" ) ;
78- var x = [ 251 , "caml_ephe_list_head" ] ;
79- x . length = caml_ephe_key_offset + n ;
71+ var alen = caml_ephe_key_offset + n ;
72+ var x = new Array ( alen ) ;
73+ x [ 0 ] = 251 ;
74+ x [ 1 ] = "caml_ephe_list_head" ;
75+ for ( var i = 2 ; i < alen ; i ++ ) {
76+ x [ i ] = caml_ephe_none ;
77+ }
8078 return x ;
8179}
8280
8381//Provides: caml_weak_set
84- //Requires: caml_invalid_argument
8582//Requires: caml_ephe_set_key, caml_ephe_unset_key
8683function caml_weak_set ( x , i , v ) {
8784 if ( v === 0 ) caml_ephe_unset_key ( x , i ) ;
8885 else caml_ephe_set_key ( x , i , v [ 1 ] ) ;
8986 return 0 ;
9087}
9188//Provides: caml_ephe_get_key
92- //Requires: caml_ephe_key_offset, caml_invalid_argument
89+ //Requires: caml_ephe_key_offset, caml_ephe_data_offset
90+ //Requires: caml_invalid_argument
91+ //Requires: caml_ephe_none
9392//Alias: caml_weak_get
93+
9494function caml_ephe_get_key ( x , i ) {
9595 if ( i < 0 || caml_ephe_key_offset + i >= x . length )
9696 caml_invalid_argument ( "Weak.get_key" ) ;
9797 var weak = x [ caml_ephe_key_offset + i ] ;
98- if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef )
98+ if ( weak === caml_ephe_none ) return 0 ;
99+ if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef ) {
99100 weak = weak . deref ( ) ;
100- return weak === undefined ? 0 : [ 0 , weak ] ;
101+ if ( weak === undefined ) {
102+ x [ caml_ephe_key_offset + i ] = caml_ephe_none ;
103+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
104+ return 0 ;
105+ }
106+ }
107+ return [ 0 , weak ] ;
101108}
102109//Provides: caml_ephe_get_key_copy
103110//Requires: caml_ephe_get_key,caml_ephe_key_offset
@@ -114,21 +121,34 @@ function caml_ephe_get_key_copy(x, i) {
114121}
115122
116123//Provides: caml_ephe_check_key mutable
117- //Requires: caml_ephe_key_offset
124+ //Requires: caml_ephe_key_offset, caml_ephe_data_offset
125+ //Requires: caml_invalid_argument
126+ //Requires: caml_ephe_none
118127//Alias: caml_weak_check
119128function caml_ephe_check_key ( x , i ) {
129+ if ( i < 0 || caml_ephe_key_offset + i >= x . length )
130+ caml_invalid_argument ( "Weak.check_key" ) ;
120131 var weak = x [ caml_ephe_key_offset + i ] ;
121- if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef )
132+ if ( weak === caml_ephe_none ) return 0 ;
133+ if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef ) {
122134 weak = weak . deref ( ) ;
123- if ( weak === undefined ) return 0 ;
124- else return 1 ;
135+ if ( weak === undefined ) {
136+ x [ caml_ephe_key_offset + i ] = caml_ephe_none ;
137+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
138+ return 0 ;
139+ }
140+ }
141+ return 1 ;
125142}
126143
127144//Provides: caml_ephe_blit_key
128145//Requires: caml_array_blit
129146//Requires: caml_ephe_key_offset
147+ //Requires: caml_ephe_get_data
148+ //Requires: caml_ephe_set_data_opt
130149//Alias: caml_weak_blit
131150function caml_ephe_blit_key ( a1 , i1 , a2 , i2 , len ) {
151+ var old = caml_ephe_get_data ( a1 ) ;
132152 // minus one because caml_array_blit works on ocaml array
133153 caml_array_blit (
134154 a1 ,
@@ -137,77 +157,96 @@ function caml_ephe_blit_key(a1, i1, a2, i2, len) {
137157 caml_ephe_key_offset + i2 - 1 ,
138158 len ,
139159 ) ;
160+ caml_ephe_set_data_opt ( a2 , old ) ;
140161 return 0 ;
141162}
142163
143164//Provides: caml_ephe_blit_data
144- //Requires: caml_ephe_data_offset, caml_ephe_set_data, caml_ephe_unset_data
165+ //Requires: caml_ephe_get_data, caml_ephe_set_data_opt
145166function caml_ephe_blit_data ( src , dst ) {
146- var n = src [ caml_ephe_data_offset ] ;
147- if ( n === undefined ) caml_ephe_unset_data ( dst ) ;
148- else caml_ephe_set_data ( dst , n ) ;
167+ var old = caml_ephe_get_data ( src ) ;
168+ caml_ephe_set_data_opt ( dst , old ) ;
149169 return 0 ;
150170}
151171
152172//Provides: caml_ephe_get_data
153- //Requires: caml_ephe_data_offset
173+ //Requires: caml_ephe_data_offset, caml_ephe_key_offset
174+ //Requires: caml_ephe_none
154175function caml_ephe_get_data ( x ) {
155- if ( x [ caml_ephe_data_offset ] === undefined ) return 0 ;
156- else return [ 0 , x [ caml_ephe_data_offset ] ] ;
176+ var data = x [ caml_ephe_data_offset ] ;
177+ if ( data === caml_ephe_none ) return 0 ;
178+ for ( var i = caml_ephe_key_offset ; i < x . length ; i ++ ) {
179+ var k = x [ i ] ;
180+ if ( k === caml_ephe_none ) continue ;
181+ if ( ! ( globalThis . WeakRef && k instanceof globalThis . WeakRef ) ) continue ;
182+ var d = k . deref ( ) ;
183+ if ( d === undefined ) {
184+ x [ i ] = caml_ephe_none ;
185+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
186+ return 0 ;
187+ }
188+ data = data . get ( d ) ;
189+ if ( data === undefined ) {
190+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
191+ return 0 ;
192+ }
193+ }
194+ return [ 0 , data ] ;
157195}
158196
159197//Provides: caml_ephe_get_data_copy
160- //Requires: caml_ephe_data_offset
198+ //Requires: caml_ephe_get_data
161199//Requires: caml_obj_dup
162200function caml_ephe_get_data_copy ( x ) {
163- if ( x [ caml_ephe_data_offset ] === undefined ) return 0 ;
164- else return [ 0 , caml_obj_dup ( x [ caml_ephe_data_offset ] ) ] ;
201+ var r = caml_ephe_get_data ( x ) ;
202+ if ( r === 0 ) return 0 ;
203+ else return [ 0 , caml_obj_dup ( r [ 1 ] ) ] ;
165204}
166205
167206//Provides: caml_ephe_set_data
168- //Requires: caml_ephe_data_offset, caml_ephe_key_offset, caml_ephe_unset_data
207+ //Requires: caml_ephe_data_offset, caml_ephe_key_offset
208+ //Requires: caml_ephe_none
169209function caml_ephe_set_data ( x , data ) {
170- if ( globalThis . FinalizationRegistry && globalThis . WeakRef ) {
171- if ( ! ( x [ 1 ] instanceof globalThis . FinalizationRegistry ) ) {
172- x [ 1 ] = new globalThis . FinalizationRegistry ( function ( ) {
173- caml_ephe_unset_data ( x ) ;
174- } ) ;
175- //register all keys
176- for ( var j = caml_ephe_key_offset ; j < x . length ; j ++ ) {
177- var key = x [ j ] ;
178- if ( key instanceof globalThis . WeakRef ) {
179- key = key . deref ( ) ;
180- if ( key ) x [ 1 ] . register ( key , undefined , key ) ;
181- }
182- }
210+ for ( var i = caml_ephe_key_offset ; i < x . length ; i ++ ) {
211+ var k = x [ i ] ;
212+ if ( k === caml_ephe_none ) continue ;
213+ if ( ! ( globalThis . WeakRef && k instanceof globalThis . WeakRef ) ) continue ;
214+ var d = k . deref ( ) ;
215+ if ( d === undefined ) {
216+ x [ i ] = caml_ephe_none ;
217+ continue ;
218+ }
219+ if ( globalThis . WeakMap ) {
220+ var data2 = new globalThis . WeakMap ( ) ;
221+ data2 . set ( k , data ) ;
222+ data = data2 ;
183223 }
184224 }
185225 x [ caml_ephe_data_offset ] = data ;
186226 return 0 ;
187227}
188228
229+ //Provides: caml_ephe_set_data_opt
230+ //Requires: caml_ephe_set_data
231+ //Requires: caml_ephe_unset_data
232+ function caml_ephe_set_data_opt ( x , data_opt ) {
233+ if ( data_opt === 0 ) caml_ephe_unset_data ( x ) ;
234+ else caml_ephe_set_data ( x , data_opt [ 1 ] ) ;
235+ return 0 ;
236+ }
237+
189238//Provides: caml_ephe_unset_data
190- //Requires: caml_ephe_data_offset, caml_ephe_key_offset
239+ //Requires: caml_ephe_data_offset
240+ //Requires: caml_ephe_none
191241function caml_ephe_unset_data ( x ) {
192- if ( globalThis . FinalizationRegistry && globalThis . WeakRef ) {
193- if ( x [ 1 ] instanceof globalThis . FinalizationRegistry ) {
194- //unregister all keys
195- for ( var j = caml_ephe_key_offset ; j < x . length ; j ++ ) {
196- var key = x [ j ] ;
197- if ( key instanceof globalThis . WeakRef ) {
198- key = key . deref ( ) ;
199- if ( key ) x [ 1 ] . unregister ( key ) ;
200- }
201- }
202- }
203- }
204- x [ caml_ephe_data_offset ] = undefined ;
242+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
205243 return 0 ;
206244}
207245
208246//Provides: caml_ephe_check_data
209- //Requires: caml_ephe_data_offset
247+ //Requires: caml_ephe_get_data
210248function caml_ephe_check_data ( x ) {
211- if ( x [ caml_ephe_data_offset ] === undefined ) return 0 ;
249+ var data = caml_ephe_get_data ( x ) ;
250+ if ( data === 0 ) return 0 ;
212251 else return 1 ;
213252}
0 commit comments