Skip to content

Commit d65a9e2

Browse files
Stop using higher-order functions to convert JSValues to RawJSValues
1 parent d3b26d3 commit d65a9e2

File tree

2 files changed

+16
-44
lines changed

2 files changed

+16
-44
lines changed

Sources/JavaScriptKit/ConvertibleToJSValue.swift

+16-35
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ extension RawJSValue: ConvertibleToJSValue {
220220

221221
extension 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

260265
extension 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)
283276
extension 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

Sources/JavaScriptKit/FundamentalObjects/JSString.swift

-9
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,4 @@ extension JSString {
9797
func asInternalJSRef() -> JavaScriptObjectRef {
9898
guts.jsRef
9999
}
100-
101-
func withRawJSValue<T>(_ body: (RawJSValue) -> T) -> T {
102-
let rawValue = RawJSValue(
103-
kind: .string,
104-
payload1: guts.jsRef,
105-
payload2: 0
106-
)
107-
return body(rawValue)
108-
}
109100
}

0 commit comments

Comments
 (0)