From bd878f44bb70dc15233470a761ce8bbd22268b83 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 29 Mar 2022 20:43:40 -0400 Subject: [PATCH 01/18] Make JSObject an open class --- Sources/JavaScriptKit/FundamentalObjects/JSObject.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 3bafe60b5..ebc541490 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -15,7 +15,7 @@ import _CJavaScriptKit /// The lifetime of this object is managed by the JavaScript and Swift runtime bridge library with /// reference counting system. @dynamicMemberLookup -public class JSObject: Equatable { +public open class JSObject: Equatable { internal var id: JavaScriptObjectRef init(id: JavaScriptObjectRef) { self.id = id From d547ef6f6a39a34c26c5e173c3dba91bba3cec41 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 29 Mar 2022 20:49:39 -0400 Subject: [PATCH 02/18] Add swjs_retain and an JSObject(cloning:) initializer --- Runtime/src/index.ts | 10 ++++++---- Runtime/src/types.ts | 1 + .../JavaScriptKit/FundamentalObjects/JSObject.swift | 5 +++++ Sources/JavaScriptKit/XcodeSupport.swift | 1 + Sources/_CJavaScriptKit/include/_CJavaScriptKit.h | 10 ++++++++++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index baf9ffd17..d401655fd 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -177,10 +177,9 @@ export class SwiftRuntime { }, swjs_decode_string: (bytes_ptr: pointer, length: number) => { - const bytes = this.memory.bytes().subarray( - bytes_ptr, - bytes_ptr + length - ); + const bytes = this.memory + .bytes() + .subarray(bytes_ptr, bytes_ptr + length); const string = this.textDecoder.decode(bytes); return this.memory.retain(string); }, @@ -347,6 +346,9 @@ export class SwiftRuntime { this.memory.writeBytes(buffer, bytes); }, + swjs_retain: (ref: ref) => { + this.memory.retain(this.memory.getObject(ref)); + }, swjs_release: (ref: ref) => { this.memory.release(ref); }, diff --git a/Runtime/src/types.ts b/Runtime/src/types.ts index 4f613cc6a..81c81a4db 100644 --- a/Runtime/src/types.ts +++ b/Runtime/src/types.ts @@ -84,6 +84,7 @@ export interface ImportedFunctions { length: number ): number; swjs_load_typed_array(ref: ref, buffer: pointer): void; + swjs_retain(ref: number): void; swjs_release(ref: number): void; } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index ebc541490..bf165f1b8 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -21,6 +21,11 @@ public open class JSObject: Equatable { self.id = id } + public init(cloning object: JSObject) { + _retain(object.id) + self.id = object.id + } + /// Returns the `name` member method binding this object as `this` context. /// /// e.g. diff --git a/Sources/JavaScriptKit/XcodeSupport.swift b/Sources/JavaScriptKit/XcodeSupport.swift index 5bb02e3a3..f58d603d5 100644 --- a/Sources/JavaScriptKit/XcodeSupport.swift +++ b/Sources/JavaScriptKit/XcodeSupport.swift @@ -86,6 +86,7 @@ import _CJavaScriptKit _: JavaScriptObjectRef, _: UnsafeMutablePointer! ) { fatalError() } + func _retain(_: JavaScriptObjectRef) { fatalError() } func _release(_: JavaScriptObjectRef) { fatalError() } #endif diff --git a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h index 8979cee56..7487fe966 100644 --- a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h +++ b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h @@ -255,6 +255,16 @@ __attribute__((__import_module__("javascript_kit"), __import_name__("swjs_load_typed_array"))) extern void _load_typed_array(const JavaScriptObjectRef ref, unsigned char *buffer); +/// Increments reference count of `ref` retained by `SwiftRuntimeHeap` in JavaScript side. +/// +/// This is only necessary when copying a JavaScript object to a new JSObject. +/// All swjs_* APIs return already-retained objects. +/// +/// @param ref The target JavaScript object. +__attribute__((__import_module__("javascript_kit"), + __import_name__("swjs_retain"))) +extern void _retain(const JavaScriptObjectRef ref); + /// Decrements reference count of `ref` retained by `SwiftRuntimeHeap` in JavaScript side. /// /// @param ref The target JavaScript object. From 0729e5f7f24b2d979a2c865a7297230a36cb90cb Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 29 Mar 2022 20:50:18 -0400 Subject: [PATCH 03/18] bump swjs_library_version --- Runtime/src/index.ts | 2 +- Sources/_CJavaScriptKit/_CJavaScriptKit.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index d401655fd..321d4fa9d 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -14,7 +14,7 @@ export class SwiftRuntime { private _instance: WebAssembly.Instance | null; private _memory: Memory | null; private _closureDeallocator: SwiftClosureDeallocator | null; - private version: number = 705; + private version: number = 706; private textDecoder = new TextDecoder("utf-8"); private textEncoder = new TextEncoder(); // Only support utf-8 diff --git a/Sources/_CJavaScriptKit/_CJavaScriptKit.c b/Sources/_CJavaScriptKit/_CJavaScriptKit.c index 38329ff14..c263b8f71 100644 --- a/Sources/_CJavaScriptKit/_CJavaScriptKit.c +++ b/Sources/_CJavaScriptKit/_CJavaScriptKit.c @@ -36,7 +36,7 @@ void swjs_cleanup_host_function_call(void *argv_buffer) { /// this and `SwiftRuntime.version` in `./Runtime/src/index.ts`. __attribute__((export_name("swjs_library_version"))) int swjs_library_version(void) { - return 705; + return 706; } int _library_features(void); From 0f9b0fbfb4004cbfb335a81416bd6658ece750c7 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 29 Mar 2022 20:53:32 -0400 Subject: [PATCH 04/18] oops --- Sources/JavaScriptKit/FundamentalObjects/JSObject.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index bf165f1b8..9dd06bcda 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -15,7 +15,7 @@ import _CJavaScriptKit /// The lifetime of this object is managed by the JavaScript and Swift runtime bridge library with /// reference counting system. @dynamicMemberLookup -public open class JSObject: Equatable { +open class JSObject: Equatable { internal var id: JavaScriptObjectRef init(id: JavaScriptObjectRef) { self.id = id From 8273ee6b2af781984c20033d7e372137951f3f51 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Tue, 29 Mar 2022 22:28:19 -0400 Subject: [PATCH 05/18] [breaking] remove ConvertibleToJSValue conformance from Array --- .../JavaScriptKit/ConvertibleToJSValue.swift | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Sources/JavaScriptKit/ConvertibleToJSValue.swift b/Sources/JavaScriptKit/ConvertibleToJSValue.swift index 7917c32cb..f40fb04d8 100644 --- a/Sources/JavaScriptKit/ConvertibleToJSValue.swift +++ b/Sources/JavaScriptKit/ConvertibleToJSValue.swift @@ -84,13 +84,17 @@ extension JSObject: JSValueCompatible { private let objectConstructor = JSObject.global.Object.function! private let arrayConstructor = JSObject.global.Array.function! -extension Dictionary where Value: ConvertibleToJSValue, Key == String { +extension Dictionary where Value == ConvertibleToJSValue, Key == String { public func jsValue() -> JSValue { - Swift.Dictionary.jsValue(self)() + let object = objectConstructor.new() + for (key, value) in self { + object[key] = value.jsValue() + } + return .object(object) } } -extension Dictionary: ConvertibleToJSValue where Value == ConvertibleToJSValue, Key == String { +extension Dictionary: ConvertibleToJSValue where Value: ConvertibleToJSValue, Key == String { public func jsValue() -> JSValue { let object = objectConstructor.new() for (key, value) in self { @@ -139,13 +143,17 @@ extension Optional: ConvertibleToJSValue where Wrapped: ConvertibleToJSValue { } } -extension Array where Element: ConvertibleToJSValue { +extension Array: ConvertibleToJSValue where Element: ConvertibleToJSValue { public func jsValue() -> JSValue { - Array.jsValue(self)() + let array = arrayConstructor.new(count) + for (index, element) in enumerated() { + array[index] = element.jsValue() + } + return .object(array) } } -extension Array: ConvertibleToJSValue where Element == ConvertibleToJSValue { +extension Array where Element == ConvertibleToJSValue { public func jsValue() -> JSValue { let array = arrayConstructor.new(count) for (index, element) in enumerated() { From c097bf5276c8b44919729a4ba9ee0fae9b234ee4 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 07:47:38 -0400 Subject: [PATCH 06/18] Make JSTypedArray open too --- Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index e073d7c29..9422ecf0c 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -12,8 +12,8 @@ public protocol TypedArrayElement: ConvertibleToJSValue, ConstructibleFromJSValu /// A wrapper around all JavaScript [TypedArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) classes that exposes their properties in a type-safe way. /// FIXME: [BigInt-based TypedArrays are currently not supported](https://github.com/swiftwasm/JavaScriptKit/issues/56). -public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral where Element: TypedArrayElement { - public static var constructor: JSFunction { Element.typedArrayClass } +open class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral where Element: TypedArrayElement { + open static var constructor: JSFunction { Element.typedArrayClass } public var jsObject: JSObject public subscript(_ index: Int) -> Element { @@ -30,7 +30,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh /// /// - Parameter length: The number of elements that will be allocated. public init(length: Int) { - jsObject = Element.typedArrayClass.new(length) + jsObject = Self.constructor.new(length) } required public init(unsafelyWrapping jsObject: JSObject) { @@ -45,7 +45,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh /// - Parameter array: The array that will be copied to create a new instance of TypedArray public convenience init(_ array: [Element]) { let jsArrayRef = array.withUnsafeBufferPointer { ptr in - _create_typed_array(Element.typedArrayClass.id, ptr.baseAddress!, Int32(array.count)) + _create_typed_array(Self.constructor.id, ptr.baseAddress!, Int32(array.count)) } self.init(unsafelyWrapping: JSObject(id: jsArrayRef)) } From 038e1d18ce315e35804a3068eb1bf3fb28f6aba9 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 08:01:18 -0400 Subject: [PATCH 07/18] Uint8ClampedArray --- Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index 9422ecf0c..22c57eb8b 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -12,8 +12,8 @@ public protocol TypedArrayElement: ConvertibleToJSValue, ConstructibleFromJSValu /// A wrapper around all JavaScript [TypedArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) classes that exposes their properties in a type-safe way. /// FIXME: [BigInt-based TypedArrays are currently not supported](https://github.com/swiftwasm/JavaScriptKit/issues/56). -open class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral where Element: TypedArrayElement { - open static var constructor: JSFunction { Element.typedArrayClass } +public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral where Element: TypedArrayElement { + public class var constructor: JSFunction { Element.typedArrayClass } public var jsObject: JSObject public subscript(_ index: Int) -> Element { @@ -116,7 +116,10 @@ extension Int8: TypedArrayElement { extension UInt8: TypedArrayElement { public static var typedArrayClass = JSObject.global.Uint8Array.function! } -// TODO: Support Uint8ClampedArray? + +public class Uint8ClampedArray: JSTypedArray { + public class override var constructor: JSFunction { JSObject.global.Uint8ClampedArray.function! } +} extension Int16: TypedArrayElement { public static var typedArrayClass = JSObject.global.Int16Array.function! From 40178501fc7a153e38268ac8025c541510a22881 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 08:03:05 -0400 Subject: [PATCH 08/18] rename --- Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index 22c57eb8b..99f2cf352 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -117,7 +117,7 @@ extension UInt8: TypedArrayElement { public static var typedArrayClass = JSObject.global.Uint8Array.function! } -public class Uint8ClampedArray: JSTypedArray { +public class JSUInt8ClampedArray: JSTypedArray { public class override var constructor: JSFunction { JSObject.global.Uint8ClampedArray.function! } } From 6095b45ae1addda01f34dadddb3550affeeb61d6 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 14:25:47 -0400 Subject: [PATCH 09/18] Make the JSPromise async helper actually accessible --- .../JavaScriptEventLoop.swift | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index b68889c42..5b597192e 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -100,20 +100,18 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) public extension JSPromise { /// Wait for the promise to complete, returning (or throwing) its result. - var value: JSValue { - get async throws { - try await withUnsafeThrowingContinuation { [self] continuation in - self.then( - success: { - continuation.resume(returning: $0) - return JSValue.undefined - }, - failure: { - continuation.resume(throwing: $0) - return JSValue.undefined - } - ) - } + func get() async throws -> JSValue { + try await withUnsafeThrowingContinuation { [self] continuation in + self.then( + success: { + continuation.resume(returning: $0) + return .undefined + }, + failure: { + continuation.resume(throwing: $0) + return .undefined + } + ) } } } From b31ccd802d1fe4c6c7c8359818515c24116d3860 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 14:27:10 -0400 Subject: [PATCH 10/18] lower concurrency requirements --- Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift | 4 ++-- Sources/JavaScriptEventLoop/JobQueue.swift | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index 5b597192e..5c6f240f5 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -5,7 +5,7 @@ import _CJavaScriptEventLoop #if compiler(>=5.5) -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { /// A function that queues a given closure as a microtask into JavaScript event loop. @@ -97,7 +97,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { } } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public extension JSPromise { /// Wait for the promise to complete, returning (or throwing) its result. func get() async throws -> JSValue { diff --git a/Sources/JavaScriptEventLoop/JobQueue.swift b/Sources/JavaScriptEventLoop/JobQueue.swift index 56090d120..44b2f7249 100644 --- a/Sources/JavaScriptEventLoop/JobQueue.swift +++ b/Sources/JavaScriptEventLoop/JobQueue.swift @@ -6,13 +6,13 @@ import _CJavaScriptEventLoop #if compiler(>=5.5) -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) struct QueueState: Sendable { fileprivate var headJob: UnownedJob? = nil fileprivate var isSpinning: Bool = false } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) extension JavaScriptEventLoop { func insertJobQueue(job newJob: UnownedJob) { @@ -58,7 +58,7 @@ extension JavaScriptEventLoop { } } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) fileprivate extension UnownedJob { private func asImpl() -> UnsafeMutablePointer<_CJavaScriptEventLoop.Job> { unsafeBitCast(self, to: UnsafeMutablePointer<_CJavaScriptEventLoop.Job>.self) From c03c6f9442bd023610988a819e3e830618c55cd5 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 30 Mar 2022 14:28:04 -0400 Subject: [PATCH 11/18] oops! --- Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index 5c6f240f5..03d1e1b3e 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -105,11 +105,11 @@ public extension JSPromise { self.then( success: { continuation.resume(returning: $0) - return .undefined + return JSValue.undefined }, failure: { continuation.resume(throwing: $0) - return .undefined + return JSValue.undefined } ) } From 0da0301fde271f4bb194a105cfd8756bd6b4953f Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 1 Apr 2022 08:08:11 -0400 Subject: [PATCH 12/18] Revert "Add swjs_retain and an JSObject(cloning:) initializer" This reverts commit d547ef6f6a39a34c26c5e173c3dba91bba3cec41. --- Runtime/src/index.ts | 10 ++++------ Runtime/src/types.ts | 1 - .../JavaScriptKit/FundamentalObjects/JSObject.swift | 5 ----- Sources/JavaScriptKit/XcodeSupport.swift | 1 - Sources/_CJavaScriptKit/include/_CJavaScriptKit.h | 10 ---------- 5 files changed, 4 insertions(+), 23 deletions(-) diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index 321d4fa9d..07af18d1d 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -177,9 +177,10 @@ export class SwiftRuntime { }, swjs_decode_string: (bytes_ptr: pointer, length: number) => { - const bytes = this.memory - .bytes() - .subarray(bytes_ptr, bytes_ptr + length); + const bytes = this.memory.bytes().subarray( + bytes_ptr, + bytes_ptr + length + ); const string = this.textDecoder.decode(bytes); return this.memory.retain(string); }, @@ -346,9 +347,6 @@ export class SwiftRuntime { this.memory.writeBytes(buffer, bytes); }, - swjs_retain: (ref: ref) => { - this.memory.retain(this.memory.getObject(ref)); - }, swjs_release: (ref: ref) => { this.memory.release(ref); }, diff --git a/Runtime/src/types.ts b/Runtime/src/types.ts index 81c81a4db..4f613cc6a 100644 --- a/Runtime/src/types.ts +++ b/Runtime/src/types.ts @@ -84,7 +84,6 @@ export interface ImportedFunctions { length: number ): number; swjs_load_typed_array(ref: ref, buffer: pointer): void; - swjs_retain(ref: number): void; swjs_release(ref: number): void; } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 9dd06bcda..cc6515438 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -21,11 +21,6 @@ open class JSObject: Equatable { self.id = id } - public init(cloning object: JSObject) { - _retain(object.id) - self.id = object.id - } - /// Returns the `name` member method binding this object as `this` context. /// /// e.g. diff --git a/Sources/JavaScriptKit/XcodeSupport.swift b/Sources/JavaScriptKit/XcodeSupport.swift index f58d603d5..5bb02e3a3 100644 --- a/Sources/JavaScriptKit/XcodeSupport.swift +++ b/Sources/JavaScriptKit/XcodeSupport.swift @@ -86,7 +86,6 @@ import _CJavaScriptKit _: JavaScriptObjectRef, _: UnsafeMutablePointer! ) { fatalError() } - func _retain(_: JavaScriptObjectRef) { fatalError() } func _release(_: JavaScriptObjectRef) { fatalError() } #endif diff --git a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h index 7487fe966..8979cee56 100644 --- a/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h +++ b/Sources/_CJavaScriptKit/include/_CJavaScriptKit.h @@ -255,16 +255,6 @@ __attribute__((__import_module__("javascript_kit"), __import_name__("swjs_load_typed_array"))) extern void _load_typed_array(const JavaScriptObjectRef ref, unsigned char *buffer); -/// Increments reference count of `ref` retained by `SwiftRuntimeHeap` in JavaScript side. -/// -/// This is only necessary when copying a JavaScript object to a new JSObject. -/// All swjs_* APIs return already-retained objects. -/// -/// @param ref The target JavaScript object. -__attribute__((__import_module__("javascript_kit"), - __import_name__("swjs_retain"))) -extern void _retain(const JavaScriptObjectRef ref); - /// Decrements reference count of `ref` retained by `SwiftRuntimeHeap` in JavaScript side. /// /// @param ref The target JavaScript object. From 19545a9e3ee22c64914400a453a2fc630624e6ed Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 1 Apr 2022 08:09:00 -0400 Subject: [PATCH 13/18] Revert "Make JSObject an open class" This reverts commit bd878f44bb70dc15233470a761ce8bbd22268b83 --- Sources/JavaScriptKit/FundamentalObjects/JSObject.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index cc6515438..6ecd8e1ef 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -14,8 +14,7 @@ import _CJavaScriptKit /// /// The lifetime of this object is managed by the JavaScript and Swift runtime bridge library with /// reference counting system. -@dynamicMemberLookup -open class JSObject: Equatable { +public class JSObject: Equatable { internal var id: JavaScriptObjectRef init(id: JavaScriptObjectRef) { self.id = id From 68c814f60ebfa49496a43c60f8f0fc00f85bf180 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 1 Apr 2022 08:09:19 -0400 Subject: [PATCH 14/18] Revert "bump swjs_library_version" This reverts commit 0729e5f7f24b2d979a2c865a7297230a36cb90cb. --- Runtime/src/index.ts | 2 +- Sources/_CJavaScriptKit/_CJavaScriptKit.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/src/index.ts b/Runtime/src/index.ts index 07af18d1d..baf9ffd17 100644 --- a/Runtime/src/index.ts +++ b/Runtime/src/index.ts @@ -14,7 +14,7 @@ export class SwiftRuntime { private _instance: WebAssembly.Instance | null; private _memory: Memory | null; private _closureDeallocator: SwiftClosureDeallocator | null; - private version: number = 706; + private version: number = 705; private textDecoder = new TextDecoder("utf-8"); private textEncoder = new TextEncoder(); // Only support utf-8 diff --git a/Sources/_CJavaScriptKit/_CJavaScriptKit.c b/Sources/_CJavaScriptKit/_CJavaScriptKit.c index c263b8f71..38329ff14 100644 --- a/Sources/_CJavaScriptKit/_CJavaScriptKit.c +++ b/Sources/_CJavaScriptKit/_CJavaScriptKit.c @@ -36,7 +36,7 @@ void swjs_cleanup_host_function_call(void *argv_buffer) { /// this and `SwiftRuntime.version` in `./Runtime/src/index.ts`. __attribute__((export_name("swjs_library_version"))) int swjs_library_version(void) { - return 706; + return 705; } int _library_features(void); From 92d0a47321ced2fa6a65b5e9edd4c9480e0a073d Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 1 Apr 2022 09:10:10 -0400 Subject: [PATCH 15/18] Add JSString overload for JSObject method subscript --- .../FundamentalObjects/JSObject.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 6ecd8e1ef..5c366bb02 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -38,6 +38,24 @@ public class JSObject: Equatable { } } + /// Returns the `name` member method binding this object as `this` context. + /// + /// e.g. + /// ```swift + /// let document = JSObject.global.document.object! + /// let divElement = document.createElement!("div") + /// ``` + /// + /// - Parameter name: The name of this object's member to access. + /// - Returns: The `name` member method binding this object as `this` context. + @_disfavoredOverload + public subscript(_ name: JSString) -> ((ConvertibleToJSValue...) -> JSValue)? { + guard let function = self[name].function else { return nil } + return { (arguments: ConvertibleToJSValue...) in + function(this: self, arguments: arguments) + } + } + /// A convenience method of `subscript(_ name: String) -> ((ConvertibleToJSValue...) -> JSValue)?` /// to access the member through Dynamic Member Lookup. @_disfavoredOverload From 0b6656eec8fd381e3742882b48a04d9a98569e6a Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Fri, 1 Apr 2022 09:14:25 -0400 Subject: [PATCH 16/18] Restore dynamicMemberLookup --- Sources/JavaScriptKit/FundamentalObjects/JSObject.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 5c366bb02..851859252 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -14,6 +14,7 @@ import _CJavaScriptKit /// /// The lifetime of this object is managed by the JavaScript and Swift runtime bridge library with /// reference counting system. +@dynamicMemberLookup public class JSObject: Equatable { internal var id: JavaScriptObjectRef init(id: JavaScriptObjectRef) { From 2209afc61e204f9e25f579c7025d85e18a13f766 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sun, 3 Apr 2022 12:21:34 -0400 Subject: [PATCH 17/18] Update ConvertibleToJSValue API, restore JSPromise/value --- .../Sources/PrimaryTests/main.swift | 24 +++---- .../JavaScriptEventLoop.swift | 26 ++++---- .../JavaScriptKit/BasicObjects/JSError.swift | 2 +- .../BasicObjects/JSPromise.swift | 8 +-- .../BasicObjects/JSTypedArray.swift | 2 +- .../JavaScriptKit/ConvertibleToJSValue.swift | 65 ++++++++++--------- .../FundamentalObjects/JSClosure.swift | 2 +- .../FundamentalObjects/JSFunction.swift | 4 +- .../FundamentalObjects/JSObject.swift | 2 +- .../JSThrowingFunction.swift | 4 +- Sources/JavaScriptKit/JSBridgedType.swift | 12 ++-- Sources/JavaScriptKit/JSValue.swift | 6 +- 12 files changed, 80 insertions(+), 77 deletions(-) diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift index 07937b01a..bf4c9bc4f 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift @@ -356,14 +356,14 @@ try test("Call Function With This") { try test("Object Conversion") { let array1 = [1, 2, 3] - let jsArray1 = array1.jsValue().object! + let jsArray1 = array1.jsValue.object! try expectEqual(jsArray1.length, .number(3)) try expectEqual(jsArray1[0], .number(1)) try expectEqual(jsArray1[1], .number(2)) try expectEqual(jsArray1[2], .number(3)) let array2: [ConvertibleToJSValue] = [1, "str", false] - let jsArray2 = array2.jsValue().object! + let jsArray2 = array2.jsValue.object! try expectEqual(jsArray2.length, .number(3)) try expectEqual(jsArray2[0], .number(1)) try expectEqual(jsArray2[1], .string("str")) @@ -374,11 +374,11 @@ try test("Object Conversion") { try expectEqual(jsArray2[4], .object(jsArray1)) - let dict1: [String: ConvertibleToJSValue] = [ - "prop1": 1, - "prop2": "foo", + let dict1: [String: JSValue] = [ + "prop1": 1.jsValue, + "prop2": "foo".jsValue, ] - let jsDict1 = dict1.jsValue().object! + let jsDict1 = dict1.jsValue.object! try expectEqual(jsDict1.prop1, .number(1)) try expectEqual(jsDict1.prop2, .string("foo")) } @@ -425,7 +425,7 @@ try test("Closure Identifiers") { #endif func checkArray(_ array: [T]) throws where T: TypedArrayElement & Equatable { - try expectEqual(toString(JSTypedArray(array).jsValue().object!), jsStringify(array)) + try expectEqual(toString(JSTypedArray(array).jsValue.object!), jsStringify(array)) try checkArrayUnsafeBytes(array) } @@ -488,7 +488,7 @@ try test("TypedArray_Mutation") { for i in 0..<100 { try expectEqual(i, array[i]) } - try expectEqual(toString(array.jsValue().object!), jsStringify(Array(0..<100))) + try expectEqual(toString(array.jsValue.object!), jsStringify(Array(0..<100))) } try test("Date") { @@ -797,9 +797,9 @@ try test("Hashable Conformance") { let objectConstructor = JSObject.global.Object.function! let obj = objectConstructor.new() - obj.a = 1.jsValue() + obj.a = 1.jsValue let firstHash = obj.hashValue - obj.b = 2.jsValue() + obj.b = 2.jsValue let secondHash = obj.hashValue try expectEqual(firstHash, secondHash) } @@ -819,11 +819,11 @@ try test("Symbols") { // }) // }.prop let hasInstanceObject = JSObject.global.Object.function!.new() - hasInstanceObject.prop = JSClosure { _ in .undefined }.jsValue() + hasInstanceObject.prop = JSClosure { _ in .undefined }.jsValue let hasInstanceClass = hasInstanceObject.prop.function! hasInstanceClass[JSSymbol.hasInstance] = JSClosure { _ in return .boolean(true) - }.jsValue() + }.jsValue try expectEqual(hasInstanceClass[JSSymbol.hasInstance].function!().boolean, true) try expectEqual(JSObject.global.Object.isInstanceOf(hasInstanceClass), true) } diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index 03d1e1b3e..8ff30c8aa 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -100,18 +100,20 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public extension JSPromise { /// Wait for the promise to complete, returning (or throwing) its result. - func get() async throws -> JSValue { - try await withUnsafeThrowingContinuation { [self] continuation in - self.then( - success: { - continuation.resume(returning: $0) - return JSValue.undefined - }, - failure: { - continuation.resume(throwing: $0) - return JSValue.undefined - } - ) + var value: JSValue { + get async throws { + try await withUnsafeThrowingContinuation { [self] continuation in + self.then( + success: { + continuation.resume(returning: $0) + return JSValue.undefined + }, + failure: { + continuation.resume(throwing: $0) + return JSValue.undefined + } + ) + } } } } diff --git a/Sources/JavaScriptKit/BasicObjects/JSError.swift b/Sources/JavaScriptKit/BasicObjects/JSError.swift index 305f1d9d5..cbdac8d6e 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSError.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSError.swift @@ -34,7 +34,7 @@ public final class JSError: Error, JSBridgedClass { } /// Creates a new `JSValue` from this `JSError` instance. - public func jsValue() -> JSValue { + public var jsValue: JSValue { .object(jsObject) } } diff --git a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift index 5b0d47dd4..0aa44cadd 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift @@ -79,7 +79,7 @@ public final class JSPromise: JSBridgedClass { @discardableResult public func then(success: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let closure = JSOneshotClosure { - return success($0[0]).jsValue() + success($0[0]).jsValue } return JSPromise(unsafelyWrapping: jsObject.then!(closure).object!) } @@ -90,10 +90,10 @@ public final class JSPromise: JSBridgedClass { public func then(success: @escaping (JSValue) -> ConvertibleToJSValue, failure: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let successClosure = JSOneshotClosure { - return success($0[0]).jsValue() + success($0[0]).jsValue } let failureClosure = JSOneshotClosure { - return failure($0[0]).jsValue() + failure($0[0]).jsValue } return JSPromise(unsafelyWrapping: jsObject.then!(successClosure, failureClosure).object!) } @@ -103,7 +103,7 @@ public final class JSPromise: JSBridgedClass { @discardableResult public func `catch`(failure: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let closure = JSOneshotClosure { - return failure($0[0]).jsValue() + failure($0[0]).jsValue } return .init(unsafelyWrapping: jsObject.catch!(closure).object!) } diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index 99f2cf352..ebcf35959 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -21,7 +21,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh return Element.construct(from: jsObject[index])! } set { - self.jsObject[index] = newValue.jsValue() + self.jsObject[index] = newValue.jsValue } } diff --git a/Sources/JavaScriptKit/ConvertibleToJSValue.swift b/Sources/JavaScriptKit/ConvertibleToJSValue.swift index ec4a33e45..83680ad02 100644 --- a/Sources/JavaScriptKit/ConvertibleToJSValue.swift +++ b/Sources/JavaScriptKit/ConvertibleToJSValue.swift @@ -3,7 +3,12 @@ import _CJavaScriptKit /// Objects that can be converted to a JavaScript value, preferably in a lossless manner. public protocol ConvertibleToJSValue { /// Create a JSValue that represents this object - func jsValue() -> JSValue + var jsValue: JSValue { get } +} + +extension ConvertibleToJSValue { + @available(*, deprecated, message: "Use the .jsValue property instead") + public func jsValue() -> JSValue { jsValue } } public typealias JSValueCompatible = ConvertibleToJSValue & ConstructibleFromJSValue @@ -13,67 +18,67 @@ extension JSValue: JSValueCompatible { return value } - public func jsValue() -> JSValue { self } + public var jsValue: JSValue { self } } extension Bool: ConvertibleToJSValue { - public func jsValue() -> JSValue { .boolean(self) } + public var jsValue: JSValue { .boolean(self) } } extension Int: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Float: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Double: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(self) } + public var jsValue: JSValue { .number(self) } } extension String: ConvertibleToJSValue { - public func jsValue() -> JSValue { .string(JSString(self)) } + public var jsValue: JSValue { .string(JSString(self)) } } extension UInt8: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt16: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt32: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt64: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int8: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int16: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int32: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int64: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension JSString: ConvertibleToJSValue { - public func jsValue() -> JSValue { .string(self) } + public var jsValue: JSValue { .string(self) } } extension JSObject: JSValueCompatible { @@ -85,20 +90,20 @@ private let objectConstructor = JSObject.global.Object.function! private let arrayConstructor = JSObject.global.Array.function! extension Dictionary where Value == ConvertibleToJSValue, Key == String { - public func jsValue() -> JSValue { + public var jsValue: JSValue { let object = objectConstructor.new() for (key, value) in self { - object[key] = value.jsValue() + object[key] = value.jsValue } return .object(object) } } extension Dictionary: ConvertibleToJSValue where Value: ConvertibleToJSValue, Key == String { - public func jsValue() -> JSValue { + public var jsValue: JSValue { let object = objectConstructor.new() for (key, value) in self { - object[key] = value.jsValue() + object[key] = value.jsValue } return .object(object) } @@ -108,7 +113,7 @@ extension Dictionary: ConstructibleFromJSValue where Value: ConstructibleFromJSV public static func construct(from value: JSValue) -> Self? { guard let objectRef = value.object, - let keys: [String] = objectConstructor.keys!(objectRef.jsValue()).fromJSValue() + let keys: [String] = objectConstructor.keys!(objectRef.jsValue).fromJSValue() else { return nil } var entries = [(String, Value)]() @@ -135,29 +140,29 @@ extension Optional: ConstructibleFromJSValue where Wrapped: ConstructibleFromJSV } extension Optional: ConvertibleToJSValue where Wrapped: ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { switch self { case .none: return .null - case let .some(wrapped): return wrapped.jsValue() + case let .some(wrapped): return wrapped.jsValue } } } extension Array: ConvertibleToJSValue where Element: ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { let array = arrayConstructor.new(count) for (index, element) in enumerated() { - array[index] = element.jsValue() + array[index] = element.jsValue } return .object(array) } } extension Array where Element == ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { let array = arrayConstructor.new(count) for (index, element) in enumerated() { - array[index] = element.jsValue() + array[index] = element.jsValue } return .object(array) } @@ -184,7 +189,7 @@ extension Array: ConstructibleFromJSValue where Element: ConstructibleFromJSValu } extension RawJSValue: ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { switch kind { case .invalid: fatalError() @@ -251,7 +256,7 @@ extension Array where Element == ConvertibleToJSValue { _ results: inout [RawJSValue], _ body: ([RawJSValue]) -> T ) -> T { if index == values.count { return body(results) } - return values[index].jsValue().withRawJSValue { (rawValue) -> T in + return values[index].jsValue.withRawJSValue { (rawValue) -> T in results.append(rawValue) return _withRawJSValues(values, index + 1, &results, body) } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index f8c2632c9..c942b9b5e 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -138,7 +138,7 @@ func _call_host_function_impl( fatalError("The function was already released") } let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map { - $0.jsValue() + $0.jsValue } let result = hostFunc(arguments) let callbackFuncRef = JSFunction(id: callbackFuncRef) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift index 6a05a8de2..9cec5dad0 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift @@ -18,7 +18,7 @@ public class JSFunction: JSObject { /// - Returns: The result of this call. @discardableResult public func callAsFunction(this: JSObject? = nil, arguments: [ConvertibleToJSValue]) -> JSValue { - invokeNonThrowingJSFunction(self, arguments: arguments, this: this).jsValue() + invokeNonThrowingJSFunction(self, arguments: arguments, this: this).jsValue } /// A variadic arguments version of `callAsFunction`. @@ -78,7 +78,7 @@ public class JSFunction: JSObject { return value.function as? Self } - override public func jsValue() -> JSValue { + override public var jsValue: JSValue { .function(self) } } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index c26d00b7d..427648bcc 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -152,7 +152,7 @@ public class JSObject: Equatable { return value.object as? Self } - public func jsValue() -> JSValue { + public var jsValue: JSValue { .object(self) } } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift index adcd82a63..3e21f0e1b 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift @@ -50,7 +50,7 @@ public class JSThrowingFunction { ) if exceptionKind.isException { let exception = RawJSValue(kind: exceptionKind.kind, payload1: exceptionPayload1, payload2: exceptionPayload2) - return .failure(exception.jsValue()) + return .failure(exception.jsValue) } return .success(JSObject(id: resultObj)) } @@ -82,7 +82,7 @@ private func invokeJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSV ) } let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2) - return (result.jsValue(), kindAndFlags.isException) + return (result.jsValue, kindAndFlags.isException) } } if isException { diff --git a/Sources/JavaScriptKit/JSBridgedType.swift b/Sources/JavaScriptKit/JSBridgedType.swift index acd1fa6ef..235d78331 100644 --- a/Sources/JavaScriptKit/JSBridgedType.swift +++ b/Sources/JavaScriptKit/JSBridgedType.swift @@ -1,21 +1,16 @@ /// Use this protocol when your type has no single JavaScript class. /// For example, a union type of multiple classes or primitive values. public protocol JSBridgedType: JSValueCompatible, CustomStringConvertible { - /// This is the value your class wraps. - var value: JSValue { get } - /// If your class is incompatible with the provided value, return `nil`. init?(from value: JSValue) } extension JSBridgedType { public static func construct(from value: JSValue) -> Self? { - return Self.init(from: value) + Self.init(from: value) } - public func jsValue() -> JSValue { value } - - public var description: String { value.description } + public var description: String { jsValue.description } } /// Conform to this protocol when your Swift class wraps a JavaScript class. @@ -33,7 +28,8 @@ public protocol JSBridgedClass: JSBridgedType { } extension JSBridgedClass { - public var value: JSValue { jsObject.jsValue() } + public var jsValue: JSValue { jsObject.jsValue } + public init?(from value: JSValue) { guard let object = value.object else { return nil } self.init(from: object) diff --git a/Sources/JavaScriptKit/JSValue.swift b/Sources/JavaScriptKit/JSValue.swift index b363db679..b001dc7ab 100644 --- a/Sources/JavaScriptKit/JSValue.swift +++ b/Sources/JavaScriptKit/JSValue.swift @@ -187,7 +187,7 @@ public func getJSValue(this: JSObject, name: JSString) -> JSValue { _get_prop(this.id, name.asInternalJSRef(), &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, name: JSString, value: JSValue) { @@ -201,7 +201,7 @@ public func getJSValue(this: JSObject, index: Int32) -> JSValue { _get_subscript(this.id, index, &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, index: Int32, value: JSValue) { @@ -217,7 +217,7 @@ public func getJSValue(this: JSObject, symbol: JSSymbol) -> JSValue { _get_prop(this.id, symbol.id, &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, symbol: JSSymbol, value: JSValue) { From e6dbd0b4738fe52d7135310a918ced77b62f2e0e Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Sun, 3 Apr 2022 12:40:38 -0400 Subject: [PATCH 18/18] Use key path shorthand --- Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index c942b9b5e..cbd44bd6e 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -137,9 +137,7 @@ func _call_host_function_impl( guard let (_, hostFunc) = JSClosure.sharedClosures[hostFuncRef] else { fatalError("The function was already released") } - let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map { - $0.jsValue - } + let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map(\.jsValue) let result = hostFunc(arguments) let callbackFuncRef = JSFunction(id: callbackFuncRef) _ = callbackFuncRef(result)