From 6ee67721a33c67f635fcd6efd4b2ab2c6b83b84c Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 7 Apr 2024 12:20:46 +0900 Subject: [PATCH] Inherit JSFunction from JSClosure There is no reason not to make JSClosure to be compatible with JSFunction. We can treat JSClosure as a JSFunction and call it from not only JavaScript but also Swift. --- .../Sources/PrimaryTests/UnitTestUtils.swift | 1 + .../Sources/PrimaryTests/main.swift | 25 ++++++++----------- .../FundamentalObjects/JSClosure.swift | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift index 571e0d6a3..199a4cbdf 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift @@ -14,6 +14,7 @@ func test(_ name: String, testBlock: () throws -> Void) throws { print(error) throw error } + print("✅ \(name)") } struct MessageError: Error { diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift index aede07ced..a3e27573a 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift @@ -251,6 +251,16 @@ try test("Closure Lifetime") { } #endif + do { + let c1 = JSClosure { _ in .number(4) } + try expectEqual(c1(), .number(4)) + } + + do { + let c1 = JSClosure { _ in fatalError("Crash while closure evaluation") } + let error = try expectThrow(try evalClosure.throws(c1)) as! JSValue + try expectEqual(error.description, "RuntimeError: unreachable") + } } try test("Host Function Registration") { @@ -420,21 +430,6 @@ try test("ObjectRef Lifetime") { #endif } -#if JAVASCRIPTKIT_WITHOUT_WEAKREFS -func closureScope() -> ObjectIdentifier { - let closure = JSClosure { _ in .undefined } - let result = ObjectIdentifier(closure) - closure.release() - return result -} - -try test("Closure Identifiers") { - let oid1 = closureScope() - let oid2 = closureScope() - try expectEqual(oid1, oid2) -} -#endif - func checkArray(_ array: [T]) throws where T: TypedArrayElement & Equatable { try expectEqual(toString(JSTypedArray(array).jsValue.object!), jsStringify(array)) try checkArrayUnsafeBytes(array) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index ea15c6d28..441dd2a6c 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -61,7 +61,7 @@ public class JSOneshotClosure: JSObject, JSClosureProtocol { /// button.removeEventListener!("click", JSValue.function(eventListenter)) /// ``` /// -public class JSClosure: JSObject, JSClosureProtocol { +public class JSClosure: JSFunction, JSClosureProtocol { // Note: Retain the closure object itself also to avoid funcRef conflicts fileprivate static var sharedClosures: [JavaScriptHostFuncRef: (object: JSObject, body: ([JSValue]) -> JSValue)] = [:]