Skip to content

Commit 85b8617

Browse files
Implement Closure release method
1 parent 11e1b3c commit 85b8617

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

IntegrationTests/JavaScriptKitExec/Sources/JavaScriptKitExec/main.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ Host_Function_Registration: do {
184184
let prop_6Ref = try expectObject(prop_6)
185185

186186
var isHostFunc1Called = false
187-
let hostFunc1 = JSFunctionRef.from { (arguments) -> JSValue in
187+
let hostFunc1 = JSClosure { (arguments) -> JSValue in
188188
isHostFunc1Called = true
189189
return .number(1)
190190
}
@@ -196,7 +196,9 @@ Host_Function_Registration: do {
196196
try expectEqual(call_host_1Func(), .number(1))
197197
try expectEqual(isHostFunc1Called, true)
198198

199-
let hostFunc2 = JSFunctionRef.from { (arguments) -> JSValue in
199+
hostFunc1.release()
200+
201+
let hostFunc2 = JSClosure { (arguments) -> JSValue in
200202
do {
201203
let input = try expectNumber(arguments[0])
202204
return .number(input * 2)
@@ -207,7 +209,7 @@ Host_Function_Registration: do {
207209

208210
try expectEqual(hostFunc2(3), .number(6))
209211
_ = try expectString(hostFunc2(true))
210-
212+
hostFunc2.release()
211213
} catch {
212214
print(error)
213215
}

Sources/JavaScriptKit/JSFunction.swift

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,40 @@ public class JSFunctionRef: JSObjectRef {
5454
}
5555
}
5656

57-
static var sharedFunctions: [([JSValue]) -> JSValue] = []
57+
@available(*, unavailable, message: "Please use JSClosure instead")
5858
public static func from(_ body: @escaping ([JSValue]) -> JSValue) -> JSFunctionRef {
59-
let id = JavaScriptHostFuncRef(sharedFunctions.count)
60-
sharedFunctions.append(body)
61-
var funcRef: JavaScriptObjectRef = 0
62-
_create_function(id, &funcRef)
63-
64-
return JSFunctionRef(id: funcRef)
59+
fatalError("unavailable")
6560
}
6661

6762
public override func jsValue() -> JSValue {
6863
.function(self)
6964
}
7065
}
7166

67+
public class JSClosure: JSFunctionRef {
68+
69+
static var sharedFunctions: [JavaScriptHostFuncRef: ([JSValue]) -> JSValue] = [:]
70+
71+
private var hostFuncRef: JavaScriptHostFuncRef = 0
72+
73+
public init(_ body: @escaping ([JSValue]) -> JSValue) {
74+
super.init(id: 0)
75+
let objectId = ObjectIdentifier(self)
76+
let funcRef = JavaScriptHostFuncRef(bitPattern: Int32(objectId.hashValue))
77+
Self.sharedFunctions[funcRef] = body
78+
79+
var objectRef: JavaScriptObjectRef = 0
80+
_create_function(funcRef, &objectRef)
81+
82+
self.hostFuncRef = funcRef
83+
self.id = objectRef
84+
}
85+
86+
public func release() {
87+
Self.sharedFunctions[hostFuncRef] = nil
88+
}
89+
}
90+
7291

7392
@_cdecl("swjs_prepare_host_function_call")
7493
public func _prepare_host_function_call(_ argc: Int32) -> UnsafeMutableRawPointer {
@@ -86,7 +105,9 @@ public func _call_host_function(
86105
_ hostFuncRef: JavaScriptHostFuncRef,
87106
_ argv: UnsafePointer<RawJSValue>, _ argc: Int32,
88107
_ callbackFuncRef: JavaScriptObjectRef) {
89-
let hostFunc = JSFunctionRef.sharedFunctions[Int(hostFuncRef)]
108+
guard let hostFunc = JSClosure.sharedFunctions[hostFuncRef] else {
109+
fatalError("The function was already released")
110+
}
90111
let args = UnsafeBufferPointer(start: argv, count: Int(argc)).map {
91112
$0.jsValue()
92113
}

Sources/JavaScriptKit/JSObject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import _CJavaScriptKit
22

33
@dynamicMemberLookup
44
public class JSObjectRef: Equatable {
5-
let id: UInt32
5+
internal var id: UInt32
66
init(id: UInt32) {
77
self.id = id
88
}

Sources/JavaScriptKit/JSValue.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public enum JSValue: Equatable {
4949

5050
extension JSValue {
5151
public static func function(_ body: @escaping ([JSValue]) -> JSValue) -> JSValue {
52-
.function(JSFunctionRef.from(body))
52+
.function(JSClosure(body))
5353
}
5454
}
5555

0 commit comments

Comments
 (0)