From ec37bdfe2275eb8c70aba87351385dd39a73b244 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 4 Feb 2023 17:04:01 +0900 Subject: [PATCH 1/3] Add fast-path for ConstructibleFromJSValue.Type --- Sources/JavaScriptKit/JSValueDecoder.swift | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Sources/JavaScriptKit/JSValueDecoder.swift b/Sources/JavaScriptKit/JSValueDecoder.swift index b1d59af63..dcd7a7f24 100644 --- a/Sources/JavaScriptKit/JSValueDecoder.swift +++ b/Sources/JavaScriptKit/JSValueDecoder.swift @@ -118,7 +118,12 @@ private struct _KeyedDecodingContainer: KeyedDecodingContainerPr } func decode(_: T.Type, forKey key: Key) throws -> T where T: Decodable { - return try T(from: _decoder(forKey: key)) + let jsValue = try _decode(forKey: key) + if let jsType = T.self as? ConstructibleFromJSValue.Type { + let maybeValue = jsType.construct(from: jsValue) + if let value = maybeValue { return value as! T } + } + return try T(from: _decoder(forKey: key, value: jsValue)) } func nestedContainer(keyedBy _: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { @@ -139,6 +144,10 @@ private struct _KeyedDecodingContainer: KeyedDecodingContainerPr func _decoder(forKey key: CodingKey) throws -> Decoder { let value = try _decode(forKey: key) + return _decoder(forKey: key, value: value) + } + + func _decoder(forKey key: CodingKey, value: JSValue) -> Decoder { return decoder.decoder(referencing: value, with: key) } } @@ -182,7 +191,12 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer { } mutating func decode(_: T.Type) throws -> T where T: Decodable { - return try T(from: _decoder()) + let jsValue = _currentValue() + if let jsType = T.self as? ConstructibleFromJSValue.Type { + let maybeValue = jsType.construct(from: jsValue) + if let value = maybeValue { return value as! T } + } + return try T(from: _decoder(value: jsValue)) } mutating func nestedContainer(keyedBy _: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { @@ -198,7 +212,11 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer { } mutating func _decoder() -> Decoder { - decoder.decoder(referencing: _currentValue(), with: currentKey) + _decoder(value: _currentValue()) + } + + func _decoder(value: JSValue) -> Decoder { + decoder.decoder(referencing: value, with: currentKey) } } From d361080edc8dc5e2f8235167405b9ac2f110b887 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 14 Feb 2023 14:24:52 +0900 Subject: [PATCH 2/3] Decode ConstructibleFromJSValue directly if possible --- Sources/JavaScriptKit/JSValueDecoder.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/JavaScriptKit/JSValueDecoder.swift b/Sources/JavaScriptKit/JSValueDecoder.swift index dcd7a7f24..24517c063 100644 --- a/Sources/JavaScriptKit/JSValueDecoder.swift +++ b/Sources/JavaScriptKit/JSValueDecoder.swift @@ -262,6 +262,10 @@ public class JSValueDecoder { from value: JSValue, userInfo: [CodingUserInfoKey: Any] = [:] ) throws -> T where T: Decodable { + if let jsType = T.self as? ConstructibleFromJSValue.Type { + let maybeValue = jsType.construct(from: value) + if let value = maybeValue { return value as! T } + } let decoder = _Decoder(referencing: value, userInfo: userInfo) return try T(from: decoder) } From 12739e644ee3834798147ebc729a72f9c7ec7e35 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 14 Feb 2023 14:25:16 +0900 Subject: [PATCH 3/3] Add JSTypedArray(bufffer: UnsafeBufferPointer) --- Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index c22e6c8cc..52b5f0b20 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -52,6 +52,14 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh self.init(unsafelyWrapping: JSObject(id: jsArrayRef)) } + /// Initialize a new instance of TypedArray in JavaScript environment with given buffer elements. + /// + /// - Parameter buffer: The buffer that will be copied to create a new instance of TypedArray + public convenience init(buffer: UnsafeBufferPointer) { + let jsArrayRef = _create_typed_array(Self.constructor!.id, buffer.baseAddress!, Int32(buffer.count)) + self.init(unsafelyWrapping: JSObject(id: jsArrayRef)) + } + /// Convenience initializer for `Sequence`. public convenience init(_ sequence: S) where S.Element == Element { self.init(Array(sequence))