Skip to content

Commit 0f53ca5

Browse files
Reduce retain/release dance caused by Optional<this>
1 parent e66296f commit 0f53ca5

File tree

2 files changed

+51
-24
lines changed

2 files changed

+51
-24
lines changed

Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,31 @@ public class JSFunction: JSObject {
1717
/// - arguments: Arguments to be passed to this function.
1818
/// - Returns: The result of this call.
1919
@discardableResult
20-
public func callAsFunction(this: JSObject? = nil, arguments: [ConvertibleToJSValue]) -> JSValue {
21-
invokeNonThrowingJSFunction(self, arguments: arguments, this: this).jsValue
20+
public func callAsFunction(this: JSObject, arguments: [ConvertibleToJSValue]) -> JSValue {
21+
invokeNonThrowingJSFunction(arguments: arguments, this: this).jsValue
22+
}
23+
24+
/// Call this function with given `arguments`.
25+
/// - Parameters:
26+
/// - arguments: Arguments to be passed to this function.
27+
/// - Returns: The result of this call.
28+
@discardableResult
29+
public func callAsFunction(arguments: [ConvertibleToJSValue]) -> JSValue {
30+
invokeNonThrowingJSFunction(arguments: arguments).jsValue
2231
}
2332

2433
/// A variadic arguments version of `callAsFunction`.
2534
@discardableResult
26-
public func callAsFunction(this: JSObject? = nil, _ arguments: ConvertibleToJSValue...) -> JSValue {
35+
public func callAsFunction(this: JSObject, _ arguments: ConvertibleToJSValue...) -> JSValue {
2736
self(this: this, arguments: arguments)
2837
}
2938

39+
/// A variadic arguments version of `callAsFunction`.
40+
@discardableResult
41+
public func callAsFunction(_ arguments: ConvertibleToJSValue...) -> JSValue {
42+
self(arguments: arguments)
43+
}
44+
3045
/// Instantiate an object from this function as a constructor.
3146
///
3247
/// Guaranteed to return an object because either:
@@ -81,30 +96,42 @@ public class JSFunction: JSObject {
8196
override public var jsValue: JSValue {
8297
.function(self)
8398
}
84-
}
8599

86-
func invokeNonThrowingJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSValue], this: JSObject?) -> RawJSValue {
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-
let result = _call_function_no_catch(
100-
jsFunc.id, argv, Int32(argc),
100+
final func invokeNonThrowingJSFunction(arguments: [ConvertibleToJSValue]) -> RawJSValue {
101+
arguments.withRawJSValues { rawValues in
102+
rawValues.withUnsafeBufferPointer { bufferPointer in
103+
let argv = bufferPointer.baseAddress
104+
let argc = bufferPointer.count
105+
var kindAndFlags = JavaScriptValueKindAndFlags()
106+
var payload1 = JavaScriptPayload1()
107+
var payload2 = JavaScriptPayload2()
108+
let resultBitPattern = _call_function_no_catch(
109+
id, argv, Int32(argc),
101110
&payload1, &payload2
102111
)
103-
kindAndFlags = unsafeBitCast(result, to: JavaScriptValueKindAndFlags.self)
112+
kindAndFlags = unsafeBitCast(resultBitPattern, to: JavaScriptValueKindAndFlags.self)
113+
assert(!kindAndFlags.isException)
114+
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
115+
return result
116+
}
117+
}
118+
}
119+
120+
final func invokeNonThrowingJSFunction(arguments: [ConvertibleToJSValue], this: JSObject) -> RawJSValue {
121+
arguments.withRawJSValues { rawValues in
122+
rawValues.withUnsafeBufferPointer { bufferPointer in
123+
let argv = bufferPointer.baseAddress
124+
let argc = bufferPointer.count
125+
var kindAndFlags = JavaScriptValueKindAndFlags()
126+
var payload1 = JavaScriptPayload1()
127+
var payload2 = JavaScriptPayload2()
128+
_call_function_with_this_no_catch(this.id,
129+
id, argv, Int32(argc),
130+
&kindAndFlags, &payload1, &payload2)
131+
assert(!kindAndFlags.isException)
132+
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
133+
return result
104134
}
105-
assert(!kindAndFlags.isException)
106-
let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2)
107-
return result
108135
}
109136
}
110137
}

Sources/JavaScriptKit/FundamentalObjects/JSSymbol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class JSSymbol: JSObject {
77

88
public init(_ description: JSString) {
99
// can’t do `self =` so we have to get the ID manually
10-
let result = invokeNonThrowingJSFunction(Symbol, arguments: [description], this: nil)
10+
let result = Symbol.invokeNonThrowingJSFunction(arguments: [description])
1111
precondition(result.kind == .symbol)
1212
super.init(id: UInt32(result.payload1))
1313
}

0 commit comments

Comments
 (0)