@@ -25,79 +25,85 @@ var caml_ephe_key_offset = 3;
25
25
//Provides: caml_ephe_data_offset
26
26
var caml_ephe_data_offset = 2 ;
27
27
28
+ //Provides: caml_ephe_none
29
+ var caml_ephe_none = { caml_ephe_none : 0 } ;
30
+
28
31
//Provides: caml_ephe_set_key
29
32
//Requires: caml_invalid_argument, caml_ephe_key_offset
33
+ //Requires: caml_ephe_get_data
34
+ //Requires: caml_ephe_set_data_opt
30
35
function caml_ephe_set_key ( x , i , v ) {
31
36
if ( i < 0 || caml_ephe_key_offset + i >= x . length )
32
37
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 ( globalThis . WeakRef && v instanceof Object ) v = new globalThis . WeakRef ( v ) ;
40
+ x [ caml_ephe_key_offset + i ] = v ;
41
+ caml_ephe_set_data_opt ( x , old ) ;
37
42
return 0 ;
38
43
}
39
44
40
45
//Provides: caml_ephe_unset_key
41
46
//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
42
50
function caml_ephe_unset_key ( x , i ) {
43
51
if ( i < 0 || caml_ephe_key_offset + i >= x . length )
44
- 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 ;
52
+ caml_invalid_argument ( "Weak.unset" ) ;
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 ) ;
64
56
return 0 ;
65
57
}
66
58
67
59
//Provides: caml_ephe_create
68
- //Requires: caml_weak_create, caml_ephe_data_offset
60
+ //Requires: caml_weak_create
69
61
function caml_ephe_create ( n ) {
70
- var x = caml_weak_create ( n ) ;
71
- return x ;
62
+ return caml_weak_create ( n ) ;
72
63
}
73
64
74
65
//Provides: caml_weak_create
75
- //Requires: caml_ephe_key_offset, caml_invalid_argument,caml_ephe_data_offset
66
+ //Requires: caml_ephe_key_offset, caml_invalid_argument
67
+ //Requires: caml_ephe_none
76
68
function caml_weak_create ( n ) {
77
69
if ( n < 0 ) caml_invalid_argument ( "Weak.create" ) ;
78
- var x = [ 251 , "caml_ephe_list_head" ] ;
79
- x . length = caml_ephe_key_offset + n ;
70
+ var alen = caml_ephe_key_offset + n ;
71
+ var x = new Array ( alen ) ;
72
+ x [ 0 ] = 251 ;
73
+ x [ 1 ] = "caml_ephe_list_head" ;
74
+ for ( var i = 2 ; i < alen ; i ++ ) {
75
+ x [ i ] = caml_ephe_none ;
76
+ }
80
77
return x ;
81
78
}
82
79
83
80
//Provides: caml_weak_set
84
- //Requires: caml_invalid_argument
85
81
//Requires: caml_ephe_set_key, caml_ephe_unset_key
86
82
function caml_weak_set ( x , i , v ) {
87
83
if ( v === 0 ) caml_ephe_unset_key ( x , i ) ;
88
84
else caml_ephe_set_key ( x , i , v [ 1 ] ) ;
89
85
return 0 ;
90
86
}
91
87
//Provides: caml_ephe_get_key
92
- //Requires: caml_ephe_key_offset, caml_invalid_argument
88
+ //Requires: caml_ephe_key_offset, caml_ephe_data_offset
89
+ //Requires: caml_invalid_argument
90
+ //Requires: caml_ephe_none
93
91
//Alias: caml_weak_get
92
+
94
93
function caml_ephe_get_key ( x , i ) {
95
94
if ( i < 0 || caml_ephe_key_offset + i >= x . length )
96
- caml_invalid_argument ( "Weak.get_key " ) ;
95
+ caml_invalid_argument ( "Weak.get " ) ;
97
96
var weak = x [ caml_ephe_key_offset + i ] ;
98
- if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef )
97
+ if ( weak === caml_ephe_none ) return 0 ;
98
+ if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef ) {
99
99
weak = weak . deref ( ) ;
100
- return weak === undefined ? 0 : [ 0 , weak ] ;
100
+ if ( weak === undefined ) {
101
+ x [ caml_ephe_key_offset + i ] = caml_ephe_none ;
102
+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
103
+ return 0 ;
104
+ }
105
+ }
106
+ return [ 0 , weak ] ;
101
107
}
102
108
//Provides: caml_ephe_get_key_copy
103
109
//Requires: caml_ephe_get_key,caml_ephe_key_offset
@@ -114,21 +120,34 @@ function caml_ephe_get_key_copy(x, i) {
114
120
}
115
121
116
122
//Provides: caml_ephe_check_key mutable
117
- //Requires: caml_ephe_key_offset
123
+ //Requires: caml_ephe_key_offset, caml_ephe_data_offset
124
+ //Requires: caml_invalid_argument
125
+ //Requires: caml_ephe_none
118
126
//Alias: caml_weak_check
119
127
function caml_ephe_check_key ( x , i ) {
128
+ if ( i < 0 || caml_ephe_key_offset + i >= x . length )
129
+ caml_invalid_argument ( "Weak.check" ) ;
120
130
var weak = x [ caml_ephe_key_offset + i ] ;
121
- if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef )
131
+ if ( weak === caml_ephe_none ) return 0 ;
132
+ if ( globalThis . WeakRef && weak instanceof globalThis . WeakRef ) {
122
133
weak = weak . deref ( ) ;
123
- if ( weak === undefined ) return 0 ;
124
- else return 1 ;
134
+ if ( weak === undefined ) {
135
+ x [ caml_ephe_key_offset + i ] = caml_ephe_none ;
136
+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
137
+ return 0 ;
138
+ }
139
+ }
140
+ return 1 ;
125
141
}
126
142
127
143
//Provides: caml_ephe_blit_key
128
144
//Requires: caml_array_blit
129
145
//Requires: caml_ephe_key_offset
146
+ //Requires: caml_ephe_get_data
147
+ //Requires: caml_ephe_set_data_opt
130
148
//Alias: caml_weak_blit
131
149
function caml_ephe_blit_key ( a1 , i1 , a2 , i2 , len ) {
150
+ var old = caml_ephe_get_data ( a1 ) ;
132
151
// minus one because caml_array_blit works on ocaml array
133
152
caml_array_blit (
134
153
a1 ,
@@ -137,77 +156,100 @@ function caml_ephe_blit_key(a1, i1, a2, i2, len) {
137
156
caml_ephe_key_offset + i2 - 1 ,
138
157
len ,
139
158
) ;
159
+ caml_ephe_set_data_opt ( a2 , old ) ;
140
160
return 0 ;
141
161
}
142
162
143
163
//Provides: caml_ephe_blit_data
144
- //Requires: caml_ephe_data_offset, caml_ephe_set_data, caml_ephe_unset_data
164
+ //Requires: caml_ephe_get_data, caml_ephe_set_data_opt
145
165
function 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 ) ;
166
+ var old = caml_ephe_get_data ( src ) ;
167
+ caml_ephe_set_data_opt ( dst , old ) ;
149
168
return 0 ;
150
169
}
151
170
152
171
//Provides: caml_ephe_get_data
153
- //Requires: caml_ephe_data_offset
172
+ //Requires: caml_ephe_data_offset, caml_ephe_key_offset
173
+ //Requires: caml_ephe_none
154
174
function caml_ephe_get_data ( x ) {
155
- if ( x [ caml_ephe_data_offset ] === undefined ) return 0 ;
156
- else return [ 0 , x [ caml_ephe_data_offset ] ] ;
175
+ var data = x [ caml_ephe_data_offset ] ;
176
+ if ( data === caml_ephe_none ) return 0 ;
177
+ for ( var i = caml_ephe_key_offset ; i < x . length ; i ++ ) {
178
+ var k = x [ i ] ;
179
+ if ( globalThis . WeakRef && k instanceof globalThis . WeakRef ) {
180
+ var d = k . deref ( ) ;
181
+ if ( d === undefined ) {
182
+ x [ i ] = caml_ephe_none ;
183
+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
184
+ return 0 ;
185
+ }
186
+ if ( globalThis . WeakMap ) {
187
+ data = data . get ( k ) ;
188
+ if ( data === undefined ) {
189
+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
190
+ return 0 ;
191
+ }
192
+ }
193
+ }
194
+ }
195
+ return [ 0 , data ] ;
157
196
}
158
197
159
198
//Provides: caml_ephe_get_data_copy
160
- //Requires: caml_ephe_data_offset
199
+ //Requires: caml_ephe_get_data
161
200
//Requires: caml_obj_dup
162
201
function 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 ] ) ] ;
202
+ var r = caml_ephe_get_data ( x ) ;
203
+ if ( r === 0 ) return 0 ;
204
+ var z = r [ 1 ] ;
205
+ if ( Array . isArray ( z ) ) return [ 0 , caml_obj_dup ( z ) ] ;
206
+ return z ;
165
207
}
166
208
167
209
//Provides: caml_ephe_set_data
168
- //Requires: caml_ephe_data_offset, caml_ephe_key_offset, caml_ephe_unset_data
210
+ //Requires: caml_ephe_data_offset, caml_ephe_key_offset
211
+ //Requires: caml_ephe_none
169
212
function 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
- }
213
+ for ( var i = x . length - 1 ; i >= caml_ephe_key_offset ; i -- ) {
214
+ var k = x [ i ] ;
215
+ if ( globalThis . WeakRef && k instanceof globalThis . WeakRef ) {
216
+ var d = k . deref ( ) ;
217
+ if ( d === undefined ) {
218
+ x [ i ] = caml_ephe_none ;
219
+ continue ;
220
+ }
221
+ if ( globalThis . WeakMap ) {
222
+ var data2 = new globalThis . WeakMap ( ) ;
223
+ data2 . set ( k , data ) ;
224
+ data = data2 ;
182
225
}
183
226
}
184
227
}
185
228
x [ caml_ephe_data_offset ] = data ;
186
229
return 0 ;
187
230
}
188
231
232
+ //Provides: caml_ephe_set_data_opt
233
+ //Requires: caml_ephe_set_data
234
+ //Requires: caml_ephe_unset_data
235
+ function caml_ephe_set_data_opt ( x , data_opt ) {
236
+ if ( data_opt === 0 ) caml_ephe_unset_data ( x ) ;
237
+ else caml_ephe_set_data ( x , data_opt [ 1 ] ) ;
238
+ return 0 ;
239
+ }
240
+
189
241
//Provides: caml_ephe_unset_data
190
- //Requires: caml_ephe_data_offset, caml_ephe_key_offset
242
+ //Requires: caml_ephe_data_offset
243
+ //Requires: caml_ephe_none
191
244
function 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 ;
245
+ x [ caml_ephe_data_offset ] = caml_ephe_none ;
205
246
return 0 ;
206
247
}
207
248
208
249
//Provides: caml_ephe_check_data
209
- //Requires: caml_ephe_data_offset
250
+ //Requires: caml_ephe_get_data
210
251
function caml_ephe_check_data ( x ) {
211
- if ( x [ caml_ephe_data_offset ] === undefined ) return 0 ;
252
+ var data = caml_ephe_get_data ( x ) ;
253
+ if ( data === 0 ) return 0 ;
212
254
else return 1 ;
213
255
}
0 commit comments