Skip to content

Commit d684978

Browse files
Revert "Allocate function call argument buffer on stack"
This reverts commit 8d17f5c.
1 parent 8d17f5c commit d684978

File tree

5 files changed

+91
-79
lines changed

5 files changed

+91
-79
lines changed

Diff for: Sources/JavaScriptKit/ConvertibleToJSValue.swift

+18-18
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ extension RawJSValue: ConvertibleToJSValue {
213213
}
214214

215215
extension JSValue {
216-
func toRawJSValue() -> RawJSValue {
216+
func withRawJSValue<T>(_ body: (RawJSValue) -> T) -> T {
217217
let kind: JavaScriptValueKind
218218
let payload1: JavaScriptPayload1
219219
var payload2: JavaScriptPayload2 = 0
@@ -226,7 +226,7 @@ extension JSValue {
226226
payload1 = 0
227227
payload2 = numberValue
228228
case let .string(string):
229-
return string.toRawJSValue()
229+
return string.withRawJSValue(body)
230230
case let .object(ref):
231231
kind = .object
232232
payload1 = JavaScriptPayload1(ref.id)
@@ -246,30 +246,30 @@ extension JSValue {
246246
kind = .bigInt
247247
payload1 = JavaScriptPayload1(bigIntRef.id)
248248
}
249-
return RawJSValue(kind: kind, payload1: payload1, payload2: payload2)
249+
let rawValue = RawJSValue(kind: kind, payload1: payload1, payload2: payload2)
250+
return body(rawValue)
250251
}
251252
}
252253

253-
extension Array where Element == JSValue {
254-
func withRawJSValues<T>(_ body: (UnsafeBufferPointer<RawJSValue>) -> T) -> T {
255-
withUnsafeTemporaryAllocation(of: RawJSValue.self, capacity: self.count) { buffer in
256-
for (index, value) in self.enumerated() {
257-
buffer[index] = value.toRawJSValue()
254+
extension Array where Element == ConvertibleToJSValue {
255+
func withRawJSValues<T>(_ body: ([RawJSValue]) -> T) -> T {
256+
func _withRawJSValues<T>(
257+
_ values: [ConvertibleToJSValue], _ index: Int,
258+
_ results: inout [RawJSValue], _ body: ([RawJSValue]) -> T
259+
) -> T {
260+
if index == values.count { return body(results) }
261+
return values[index].jsValue.withRawJSValue { (rawValue) -> T in
262+
results.append(rawValue)
263+
return _withRawJSValues(values, index + 1, &results, body)
258264
}
259-
return body(UnsafeBufferPointer(buffer))
260265
}
266+
var _results = [RawJSValue]()
267+
return _withRawJSValues(self, 0, &_results, body)
261268
}
262269
}
263270

264-
extension Array where Element == ConvertibleToJSValue {
265-
func withRawJSValues<T>(_ body: (UnsafeBufferPointer<RawJSValue>) -> T) -> T {
266-
map { $0.jsValue }.withRawJSValues(body)
267-
}
268-
}
269-
270-
271271
extension Array where Element: ConvertibleToJSValue {
272-
func withRawJSValues<T>(_ body: (UnsafeBufferPointer<RawJSValue>) -> T) -> T {
273-
map { $0.jsValue }.withRawJSValues(body)
272+
func withRawJSValues<T>(_ body: ([RawJSValue]) -> T) -> T {
273+
[ConvertibleToJSValue].withRawJSValues(self)(body)
274274
}
275275
}

Diff for: Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift

+24-20
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ public class JSFunction: JSObject {
3838
/// - Parameter arguments: Arguments to be passed to this constructor function.
3939
/// - Returns: A new instance of this constructor.
4040
public func new(arguments: [ConvertibleToJSValue]) -> JSObject {
41-
arguments.withRawJSValues { bufferPointer in
42-
JSObject(id: _call_new(self.id, bufferPointer.baseAddress!, Int32(bufferPointer.count)))
41+
arguments.withRawJSValues { rawValues in
42+
rawValues.withUnsafeBufferPointer { bufferPointer in
43+
JSObject(id: _call_new(self.id, bufferPointer.baseAddress!, Int32(bufferPointer.count)))
44+
}
4345
}
4446
}
4547

@@ -82,24 +84,26 @@ public class JSFunction: JSObject {
8284
}
8385

8486
func invokeNonThrowingJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSValue], this: JSObject?) -> RawJSValue {
85-
arguments.withRawJSValues { bufferPointer in
86-
let argv = bufferPointer.baseAddress
87-
let argc = bufferPointer.count
88-
var kindAndFlags = JavaScriptValueKindAndFlags()
89-
var payload1 = JavaScriptPayload1()
90-
var payload2 = JavaScriptPayload2()
91-
if let thisId = this?.id {
92-
_call_function_with_this_no_catch(thisId,
93-
jsFunc.id, argv, Int32(argc),
94-
&kindAndFlags, &payload1, &payload2)
95-
} else {
96-
_call_function_no_catch(
97-
jsFunc.id, argv, Int32(argc),
98-
&kindAndFlags, &payload1, &payload2
99-
)
87+
arguments.withRawJSValues { rawValues in
88+
rawValues.withUnsafeBufferPointer { bufferPointer in
89+
let argv = bufferPointer.baseAddress
90+
let argc = bufferPointer.count
91+
var kindAndFlags = JavaScriptValueKindAndFlags()
92+
var payload1 = JavaScriptPayload1()
93+
var payload2 = JavaScriptPayload2()
94+
if let thisId = this?.id {
95+
_call_function_with_this_no_catch(thisId,
96+
jsFunc.id, argv, Int32(argc),
97+
&kindAndFlags, &payload1, &payload2)
98+
} else {
99+
_call_function_no_catch(
100+
jsFunc.id, argv, Int32(argc),
101+
&kindAndFlags, &payload1, &payload2
102+
)
103+
}
104+
assert(!kindAndFlags.isException)
105+
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
106+
return result
100107
}
101-
assert(!kindAndFlags.isException)
102-
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
103-
return result
104108
}
105109
}

Diff for: Sources/JavaScriptKit/FundamentalObjects/JSString.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ extension JSString {
9595
guts.jsRef
9696
}
9797

98-
func toRawJSValue() -> RawJSValue {
99-
return RawJSValue(
98+
func withRawJSValue<T>(_ body: (RawJSValue) -> T) -> T {
99+
let rawValue = RawJSValue(
100100
kind: .string, payload1: guts.jsRef, payload2: 0
101101
)
102+
return body(rawValue)
102103
}
103104
}

Diff for: Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift

+35-31
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,24 @@ public class JSThrowingFunction {
3636
/// - Parameter arguments: Arguments to be passed to this constructor function.
3737
/// - Returns: A new instance of this constructor.
3838
public func new(arguments: [ConvertibleToJSValue]) throws -> JSObject {
39-
try arguments.withRawJSValues { bufferPointer -> Result<JSObject, JSValue> in
40-
let argv = bufferPointer.baseAddress
41-
let argc = bufferPointer.count
39+
try arguments.withRawJSValues { rawValues -> Result<JSObject, JSValue> in
40+
rawValues.withUnsafeBufferPointer { bufferPointer in
41+
let argv = bufferPointer.baseAddress
42+
let argc = bufferPointer.count
4243

43-
var exceptionKind = JavaScriptValueKindAndFlags()
44-
var exceptionPayload1 = JavaScriptPayload1()
45-
var exceptionPayload2 = JavaScriptPayload2()
46-
let resultObj = _call_throwing_new(
47-
self.base.id, argv, Int32(argc),
48-
&exceptionKind, &exceptionPayload1, &exceptionPayload2
49-
)
50-
if exceptionKind.isException {
51-
let exception = RawJSValue(kind: exceptionKind.kind, payload1: exceptionPayload1, payload2: exceptionPayload2)
52-
return .failure(exception.jsValue)
44+
var exceptionKind = JavaScriptValueKindAndFlags()
45+
var exceptionPayload1 = JavaScriptPayload1()
46+
var exceptionPayload2 = JavaScriptPayload2()
47+
let resultObj = _call_throwing_new(
48+
self.base.id, argv, Int32(argc),
49+
&exceptionKind, &exceptionPayload1, &exceptionPayload2
50+
)
51+
if exceptionKind.isException {
52+
let exception = RawJSValue(kind: exceptionKind.kind, payload1: exceptionPayload1, payload2: exceptionPayload2)
53+
return .failure(exception.jsValue)
54+
}
55+
return .success(JSObject(id: resultObj))
5356
}
54-
return .success(JSObject(id: resultObj))
5557
}.get()
5658
}
5759

@@ -62,24 +64,26 @@ public class JSThrowingFunction {
6264
}
6365

6466
private func invokeJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSValue], this: JSObject?) throws -> JSValue {
65-
let (result, isException): (JSValue, Bool) = arguments.withRawJSValues { bufferPointer in
66-
let argv = bufferPointer.baseAddress
67-
let argc = bufferPointer.count
68-
var kindAndFlags = JavaScriptValueKindAndFlags()
69-
var payload1 = JavaScriptPayload1()
70-
var payload2 = JavaScriptPayload2()
71-
if let thisId = this?.id {
72-
_call_function_with_this(thisId,
73-
jsFunc.id, argv, Int32(argc),
74-
&kindAndFlags, &payload1, &payload2)
75-
} else {
76-
_call_function(
77-
jsFunc.id, argv, Int32(argc),
78-
&kindAndFlags, &payload1, &payload2
79-
)
67+
let (result, isException) = arguments.withRawJSValues { rawValues in
68+
rawValues.withUnsafeBufferPointer { bufferPointer -> (JSValue, Bool) in
69+
let argv = bufferPointer.baseAddress
70+
let argc = bufferPointer.count
71+
var kindAndFlags = JavaScriptValueKindAndFlags()
72+
var payload1 = JavaScriptPayload1()
73+
var payload2 = JavaScriptPayload2()
74+
if let thisId = this?.id {
75+
_call_function_with_this(thisId,
76+
jsFunc.id, argv, Int32(argc),
77+
&kindAndFlags, &payload1, &payload2)
78+
} else {
79+
_call_function(
80+
jsFunc.id, argv, Int32(argc),
81+
&kindAndFlags, &payload1, &payload2
82+
)
83+
}
84+
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
85+
return (result.jsValue, kindAndFlags.isException)
8086
}
81-
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
82-
return (result.jsValue, kindAndFlags.isException)
8387
}
8488
if isException {
8589
throw result

Diff for: Sources/JavaScriptKit/JSValue.swift

+11-8
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@ public func getJSValue(this: JSObject, name: JSString) -> JSValue {
203203
}
204204

205205
public func setJSValue(this: JSObject, name: JSString, value: JSValue) {
206-
let rawValue = value.toRawJSValue()
207-
_set_prop(this.id, name.asInternalJSRef(), rawValue.kind, rawValue.payload1, rawValue.payload2)
206+
value.withRawJSValue { rawValue in
207+
_set_prop(this.id, name.asInternalJSRef(), rawValue.kind, rawValue.payload1, rawValue.payload2)
208+
}
208209
}
209210

210211
public func getJSValue(this: JSObject, index: Int32) -> JSValue {
@@ -216,10 +217,11 @@ public func getJSValue(this: JSObject, index: Int32) -> JSValue {
216217
}
217218

218219
public func setJSValue(this: JSObject, index: Int32, value: JSValue) {
219-
let rawValue = value.toRawJSValue()
220-
_set_subscript(this.id, index,
221-
rawValue.kind,
222-
rawValue.payload1, rawValue.payload2)
220+
value.withRawJSValue { rawValue in
221+
_set_subscript(this.id, index,
222+
rawValue.kind,
223+
rawValue.payload1, rawValue.payload2)
224+
}
223225
}
224226

225227
public func getJSValue(this: JSObject, symbol: JSSymbol) -> JSValue {
@@ -231,8 +233,9 @@ public func getJSValue(this: JSObject, symbol: JSSymbol) -> JSValue {
231233
}
232234

233235
public func setJSValue(this: JSObject, symbol: JSSymbol, value: JSValue) {
234-
let rawValue = value.toRawJSValue()
235-
_set_prop(this.id, symbol.id, rawValue.kind, rawValue.payload1, rawValue.payload2)
236+
value.withRawJSValue { rawValue in
237+
_set_prop(this.id, symbol.id, rawValue.kind, rawValue.payload1, rawValue.payload2)
238+
}
236239
}
237240

238241
public extension JSValue {

0 commit comments

Comments
 (0)