|
1 | 1 | import _CJavaScriptKit |
2 | 2 |
|
3 | | -@dynamicCallable |
4 | 3 | public class JSFunctionRef: JSObjectRef { |
5 | 4 | @discardableResult |
6 | | - public func dynamicallyCall(withArguments arguments: [JSValueConvertible]) -> JSValue { |
7 | | - let result = arguments.withRawJSValues { rawValues -> RawJSValue in |
| 5 | + public func callAsFunction(this: JSObjectRef? = nil, arguments: [JSValueConvertible]) -> JSValue { |
| 6 | + let result = arguments.withRawJSValues { rawValues in |
8 | 7 | rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in |
9 | 8 | let argv = bufferPointer.baseAddress |
10 | 9 | let argc = bufferPointer.count |
11 | 10 | var result = RawJSValue() |
12 | | - _call_function( |
13 | | - self.id, argv, Int32(argc), |
14 | | - &result.kind, &result.payload1, &result.payload2, &result.payload3 |
15 | | - ) |
| 11 | + if let thisId = this?.id { |
| 12 | + _call_function_with_this(thisId, |
| 13 | + self.id, argv, Int32(argc), |
| 14 | + &result.kind, &result.payload1, &result.payload2, &result.payload3) |
| 15 | + } else { |
| 16 | + _call_function( |
| 17 | + self.id, argv, Int32(argc), |
| 18 | + &result.kind, &result.payload1, &result.payload2, &result.payload3 |
| 19 | + ) |
| 20 | + } |
16 | 21 | return result |
17 | 22 | } |
18 | 23 | } |
19 | 24 | return result.jsValue() |
20 | 25 | } |
21 | 26 |
|
22 | | - public func apply(this: JSObjectRef, arguments: JSValueConvertible...) -> JSValue { |
23 | | - apply(this: this, argumentList: arguments) |
| 27 | + @discardableResult |
| 28 | + public func callAsFunction(this: JSObjectRef? = nil, _ arguments: JSValueConvertible...) -> JSValue { |
| 29 | + self(this: this, arguments: arguments) |
24 | 30 | } |
25 | 31 |
|
26 | | - public func apply(this: JSObjectRef, argumentList: [JSValueConvertible]) -> JSValue { |
27 | | - let result = argumentList.withRawJSValues { rawValues in |
28 | | - rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in |
29 | | - let argv = bufferPointer.baseAddress |
30 | | - let argc = bufferPointer.count |
31 | | - var result = RawJSValue() |
32 | | - _call_function_with_this(this.id, |
33 | | - self.id, argv, Int32(argc), |
34 | | - &result.kind, &result.payload1, &result.payload2, &result.payload3) |
35 | | - return result |
36 | | - } |
37 | | - } |
38 | | - return result.jsValue() |
| 32 | + public func new(_ arguments: JSValueConvertible...) -> JSObjectRef { |
| 33 | + new(arguments: arguments) |
39 | 34 | } |
40 | 35 |
|
41 | | - public func new(_ arguments: JSValueConvertible...) -> JSObjectRef { |
42 | | - return arguments.withRawJSValues { rawValues in |
| 36 | + // Guaranteed to return an object because either: |
| 37 | + // a) the constructor explicitly returns an object, or |
| 38 | + // b) the constructor returns nothing, which causes JS to return the `this` value, or |
| 39 | + // c) the constructor returns undefined, null or a non-object, in which case JS also returns `this`. |
| 40 | + public func new(arguments: [JSValueConvertible]) -> JSObjectRef { |
| 41 | + arguments.withRawJSValues { rawValues in |
43 | 42 | rawValues.withUnsafeBufferPointer { bufferPointer in |
44 | 43 | let argv = bufferPointer.baseAddress |
45 | 44 | let argc = bufferPointer.count |
@@ -106,10 +105,10 @@ public func _call_host_function( |
106 | 105 | guard let hostFunc = JSClosure.sharedFunctions[hostFuncRef] else { |
107 | 106 | fatalError("The function was already released") |
108 | 107 | } |
109 | | - let args = UnsafeBufferPointer(start: argv, count: Int(argc)).map { |
| 108 | + let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map { |
110 | 109 | $0.jsValue() |
111 | 110 | } |
112 | | - let result = hostFunc(args) |
| 111 | + let result = hostFunc(arguments) |
113 | 112 | let callbackFuncRef = JSFunctionRef(id: callbackFuncRef) |
114 | 113 | _ = callbackFuncRef(result) |
115 | 114 | } |
0 commit comments