@@ -220,6 +220,10 @@ extension RawJSValue: ConvertibleToJSValue {
220
220
221
221
extension JSValue {
222
222
func withRawJSValue< T> ( _ body: ( RawJSValue ) -> T ) -> T {
223
+ body ( convertToRawJSValue ( ) )
224
+ }
225
+
226
+ fileprivate func convertToRawJSValue( ) -> RawJSValue {
223
227
let kind : JavaScriptValueKind
224
228
let payload1 : JavaScriptPayload1
225
229
var payload2 : JavaScriptPayload2 = 0
@@ -232,7 +236,9 @@ extension JSValue {
232
236
payload1 = 0
233
237
payload2 = numberValue
234
238
case . string( let string) :
235
- return string. withRawJSValue ( body)
239
+ kind = . string
240
+ payload1 = string. asInternalJSRef ( )
241
+ payload2 = 0
236
242
case . object( let ref) :
237
243
kind = . object
238
244
payload1 = JavaScriptPayload1 ( ref. id)
@@ -252,53 +258,28 @@ extension JSValue {
252
258
kind = . bigInt
253
259
payload1 = JavaScriptPayload1 ( bigIntRef. id)
254
260
}
255
- let rawValue = RawJSValue ( kind: kind, payload1: payload1, payload2: payload2)
256
- return body ( rawValue)
261
+ return RawJSValue ( kind: kind, payload1: payload1, payload2: payload2)
257
262
}
258
263
}
259
264
260
265
extension Array where Element: ConvertibleToJSValue {
261
266
func withRawJSValues< T> ( _ body: ( [ RawJSValue ] ) -> T ) -> T {
262
- // fast path for empty array
263
- guard self . count != 0 else { return body ( [ ] ) }
264
-
265
- func _withRawJSValues(
266
- _ values: Self ,
267
- _ index: Int ,
268
- _ results: inout [ RawJSValue ] ,
269
- _ body: ( [ RawJSValue ] ) -> T
270
- ) -> T {
271
- if index == values. count { return body ( results) }
272
- return values [ index] . jsValue. withRawJSValue { ( rawValue) -> T in
273
- results. append ( rawValue)
274
- return _withRawJSValues ( values, index + 1 , & results, body)
275
- }
267
+ let jsValues = map { $0. jsValue }
268
+ // Ensure the jsValues live longer than the temporary raw JS values
269
+ return withExtendedLifetime ( jsValues) {
270
+ body ( jsValues. map { $0. convertToRawJSValue ( ) } )
276
271
}
277
- var _results = [ RawJSValue] ( )
278
- return _withRawJSValues ( self , 0 , & _results, body)
279
272
}
280
273
}
281
274
282
275
#if !hasFeature(Embedded)
283
276
extension Array where Element == ConvertibleToJSValue {
284
277
func withRawJSValues< T> ( _ body: ( [ RawJSValue ] ) -> T ) -> T {
285
- // fast path for empty array
286
- guard self . count != 0 else { return body ( [ ] ) }
287
-
288
- func _withRawJSValues(
289
- _ values: [ ConvertibleToJSValue ] ,
290
- _ index: Int ,
291
- _ results: inout [ RawJSValue ] ,
292
- _ body: ( [ RawJSValue ] ) -> T
293
- ) -> T {
294
- if index == values. count { return body ( results) }
295
- return values [ index] . jsValue. withRawJSValue { ( rawValue) -> T in
296
- results. append ( rawValue)
297
- return _withRawJSValues ( values, index + 1 , & results, body)
298
- }
278
+ let jsValues = map { $0. jsValue }
279
+ // Ensure the jsValues live longer than the temporary raw JS values
280
+ return withExtendedLifetime ( jsValues) {
281
+ body ( jsValues. map { $0. convertToRawJSValue ( ) } )
299
282
}
300
- var _results = [ RawJSValue] ( )
301
- return _withRawJSValues ( self , 0 , & _results, body)
302
283
}
303
284
}
304
285
#endif
0 commit comments