@@ -220,6 +220,10 @@ extension RawJSValue: ConvertibleToJSValue {
220220
221221extension JSValue {
222222 func withRawJSValue< T> ( _ body: ( RawJSValue ) -> T ) -> T {
223+ body ( convertToRawJSValue ( ) )
224+ }
225+
226+ fileprivate func convertToRawJSValue( ) -> RawJSValue {
223227 let kind : JavaScriptValueKind
224228 let payload1 : JavaScriptPayload1
225229 var payload2 : JavaScriptPayload2 = 0
@@ -232,7 +236,9 @@ extension JSValue {
232236 payload1 = 0
233237 payload2 = numberValue
234238 case . string( let string) :
235- return string. withRawJSValue ( body)
239+ kind = . string
240+ payload1 = string. asInternalJSRef ( )
241+ payload2 = 0
236242 case . object( let ref) :
237243 kind = . object
238244 payload1 = JavaScriptPayload1 ( ref. id)
@@ -252,53 +258,28 @@ extension JSValue {
252258 kind = . bigInt
253259 payload1 = JavaScriptPayload1 ( bigIntRef. id)
254260 }
255- let rawValue = RawJSValue ( kind: kind, payload1: payload1, payload2: payload2)
256- return body ( rawValue)
261+ return RawJSValue ( kind: kind, payload1: payload1, payload2: payload2)
257262 }
258263}
259264
260265extension Array where Element: ConvertibleToJSValue {
261266 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 ( ) } )
276271 }
277- var _results = [ RawJSValue] ( )
278- return _withRawJSValues ( self , 0 , & _results, body)
279272 }
280273}
281274
282275#if !hasFeature(Embedded)
283276extension Array where Element == ConvertibleToJSValue {
284277 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 ( ) } )
299282 }
300- var _results = [ RawJSValue] ( )
301- return _withRawJSValues ( self , 0 , & _results, body)
302283 }
303284}
304285#endif
0 commit comments