Skip to content

Commit 9045b73

Browse files
committed
Merge branch 'main' into jed/async-closure
2 parents 9f46135 + a5a980d commit 9045b73

28 files changed

+441
-320
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ node_modules
66
/*.xcodeproj
77
xcuserdata/
88
.swiftpm
9+
.vscode

.swift-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
wasm-5.5.0-RELEASE
1+
wasm-5.6.0-RELEASE

CHANGELOG.md

+42-23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
# 0.14.0 (8 April 2022)
2+
3+
This is a breaking release that enables full support for SwiftWasm 5.6 and lays groundwork for future updates to [DOMKit](https://github.com/swiftwasm/DOMKit/).
4+
5+
- The `ConvertibleToJSValue` conformance on `Array` and `Dictionary` has been swapped from the `== ConvertibleToJSValue` case to the `: ConvertibleToJSValue` case.
6+
- This means that e.g. `[String]` is now `ConvertibleToJSValue`, but `[ConvertibleToJSValue]` no longer conforms;
7+
- the `jsValue()` method still works in both cases;
8+
- to adapt existing code, use one of these approaches:
9+
- use generics where possible (for single-type arrays)
10+
- call `.map { $0.jsValue() }` (or `mapValues`) to get an array/dictionary of `JSValue` which you can then use as `ConvertibleToJSValue`
11+
- add `.jsValue` to the end of all of the values in the array/dictionary literal.
12+
13+
**Merged pull requests:**
14+
15+
- Reenable integration tests ([#180](https://github.com/swiftwasm/JavaScriptKit/pull/180)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
16+
- Updates for DOMKit ([#174](https://github.com/swiftwasm/JavaScriptKit/pull/174)) via [@j-f1](https://github.com/j-f1)
17+
- Add 5.6 release and macOS 12 with Xcode 13.3 to CI matrix ([#176](https://github.com/swiftwasm/JavaScriptKit/pull/176)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
18+
119
# 0.13.0 (31 March 2022)
220

321
This release improves handling of JavaScript exceptions and compatibility with Xcode.
@@ -21,7 +39,7 @@ Thanks to [@kateinoigakukun](https://github.com/kateinoigakukun), [@pedrovgs](ht
2139

2240
# 0.12.0 (08 February 2022)
2341

24-
This release introduces a [major refactor](https://github.com/swiftwasm/JavaScriptKit/pull/150) of the JavaScript runtime by [@j-f1] and several performance enhancements.
42+
This release introduces a [major refactor](https://github.com/swiftwasm/JavaScriptKit/pull/150) of the JavaScript runtime by [@j-f1] and several performance enhancements.
2543

2644
**Merged pull requests:**
2745

@@ -40,9 +58,10 @@ This is a bugfix release that removes a requirement for macOS Monterey in `Packa
4058
package. `README.md` was updated to explicitly specify that if you're building an app or a library
4159
that depends on JavaScriptKit for macOS (i.e. cross-platform code that supports both WebAssembly
4260
and macOS), you need either
43-
* macOS Monterey that has the new Swift concurrency runtime available, or
44-
* any version of macOS that supports Swift concurrency back-deployment with Xcode 13.2 or later, or
45-
* add `.unsafeFlags(["-Xfrontend", "-disable-availability-checking"])` in `Package.swift` manifest.
61+
62+
- macOS Monterey that has the new Swift concurrency runtime available, or
63+
- any version of macOS that supports Swift concurrency back-deployment with Xcode 13.2 or later, or
64+
- add `.unsafeFlags(["-Xfrontend", "-disable-availability-checking"])` in `Package.swift` manifest.
4665

4766
**Merged pull requests:**
4867

@@ -52,7 +71,7 @@ and macOS), you need either
5271

5372
This release adds support for `async`/`await` and SwiftWasm 5.5. Use the new `value` async property
5473
on a `JSPromise` instance to `await` for its result. You'll have to add a dependency on the new
55-
`JavaScriptEventLoop` target in your `Package.swift`, `import JavaScriptEventLoop`, and call
74+
`JavaScriptEventLoop` target in your `Package.swift`, `import JavaScriptEventLoop`, and call
5675
`JavaScriptEventLoop.installGlobalExecutor()` in your code before you start using `await` and `Task`
5776
APIs.
5877

@@ -64,12 +83,12 @@ compiler flags, see [`README.md`](./README.md) for more details.
6483
This new release of JavaScriptKit may work with SwiftWasm 5.4 and 5.3, but is no longer tested with
6584
those versions due to compatibility issues introduced on macOS by latest versions of Xcode.
6685

67-
Many thanks to [@j-f1], [@kateinoigakukun],
86+
Many thanks to [@j-f1], [@kateinoigakukun],
6887
and [@PatrickPijnappel] for their contributions to this release!
6988

7089
**Closed issues:**
7190

72-
- Enchancement: Add a link to the docs ([#136](https://github.com/swiftwasm/JavaScriptKit/issues/136))
91+
- Enchancement: Add a link to the docs ([#136](https://github.com/swiftwasm/JavaScriptKit/issues/136))
7392
- Use `FinalizationRegistry` to auto-deinit `JSClosure` ([#131](https://github.com/swiftwasm/JavaScriptKit/issues/131))
7493
- `make test` crashes due to `JSClosure` memory issues ([#129](https://github.com/swiftwasm/JavaScriptKit/issues/129))
7594
- Avoid manual memory management with `JSClosure` ([#106](https://github.com/swiftwasm/JavaScriptKit/issues/106))
@@ -97,7 +116,7 @@ tweaks.
97116

98117
**Merged pull requests:**
99118

100-
- Update JS dependencies in package-lock.json ([#126](https://github.com/swiftwasm/JavaScriptKit/pull/126)) via [@MaxDesiatov]
119+
- Update JS dependencies in package-lock.json ([#126](https://github.com/swiftwasm/JavaScriptKit/pull/126)) via [@MaxDesiatov]
101120
- Fix typo in method documentation ([#125](https://github.com/swiftwasm/JavaScriptKit/pull/125)) via [@revolter]
102121
- Update exported func name to match exported name ([#123](https://github.com/swiftwasm/JavaScriptKit/pull/123)) via [@kateinoigakukun]
103122
- Fix incorrect link in `JSDate` documentation ([#122](https://github.com/swiftwasm/JavaScriptKit/pull/122)) via [@revolter]
@@ -107,18 +126,18 @@ tweaks.
107126
This release contains multiple breaking changes in preparation for enabling `async`/`await`, when
108127
this feature is available in a stable SwiftWasm release. Namely:
109128

110-
* `JSClosure.init(_ body: @escaping ([JSValue]) -> ())` overload is deprecated to simplify type
111-
checking. Its presence requires explicit type signatures at the place of use. It will be removed
112-
in a future version of JavaScriptKit.
113-
* `JSClosure` is no longer a subclass of `JSFunction`. These classes are not related enough to keep
114-
them in the same class hierarchy.
115-
As a result, you can no longer call `JSClosure` objects directly from Swift.
116-
* Introduced `JSOneshotClosure` for closures that are going to be called only once. You don't need
117-
to manage references to these closures manually, as opposed to `JSClosure`.
118-
However, they can only be called a single time from the JS side. Subsequent invocation attempts will raise a fatal error on the Swift side.
119-
* Removed generic parameters on `JSPromise`, now both success and failure values are always assumed
120-
to be of `JSValue` type. This also significantly simplifies type checking and allows callers to
121-
fully control type casting if needed.
129+
- `JSClosure.init(_ body: @escaping ([JSValue]) -> ())` overload is deprecated to simplify type
130+
checking. Its presence requires explicit type signatures at the place of use. It will be removed
131+
in a future version of JavaScriptKit.
132+
- `JSClosure` is no longer a subclass of `JSFunction`. These classes are not related enough to keep
133+
them in the same class hierarchy.
134+
As a result, you can no longer call `JSClosure` objects directly from Swift.
135+
- Introduced `JSOneshotClosure` for closures that are going to be called only once. You don't need
136+
to manage references to these closures manually, as opposed to `JSClosure`.
137+
However, they can only be called a single time from the JS side. Subsequent invocation attempts will raise a fatal error on the Swift side.
138+
- Removed generic parameters on `JSPromise`, now both success and failure values are always assumed
139+
to be of `JSValue` type. This also significantly simplifies type checking and allows callers to
140+
fully control type casting if needed.
122141

123142
**Closed issues:**
124143

@@ -200,7 +219,7 @@ with idiomatic Swift code.
200219
- Update toolchain version, script, and `README.md` ([#96](https://github.com/swiftwasm/JavaScriptKit/pull/96)) via [@MaxDesiatov]
201220
- [Proposal] Add unsafe convenience methods for JSValue ([#98](https://github.com/swiftwasm/JavaScriptKit/pull/98)) via [@kateinoigakukun]
202221
- Remove all unsafe linker flags from Package.swift ([#91](https://github.com/swiftwasm/JavaScriptKit/pull/91)) via [@kateinoigakukun]
203-
- Sync package.json and package-lock.json ([#90](https://github.com/swiftwasm/JavaScriptKit/pull/90)) via [@kateinoigakukun]
222+
- Sync package.json and package-lock.json ([#90](https://github.com/swiftwasm/JavaScriptKit/pull/90)) via [@kateinoigakukun]
204223
- Rename JSValueConvertible/Constructible/Codable ([#88](https://github.com/swiftwasm/JavaScriptKit/pull/88)) via [@j-f1]
205224
- Bump @actions/core from 1.2.2 to 1.2.6 in /ci/perf-tester ([#89](https://github.com/swiftwasm/JavaScriptKit/pull/89)) via [@dependabot]
206225
- Make `JSError` conform to `JSBridgedClass` ([#86](https://github.com/swiftwasm/JavaScriptKit/pull/86)) via [@MaxDesiatov]
@@ -278,10 +297,10 @@ This release adds `JSTypedArray` generic type, renames `JSObjectRef` to `JSObjec
278297
- Clean up the `JSObjectRef` API ([#28](https://github.com/swiftwasm/JavaScriptKit/pull/28)) via [@j-f1]
279298
- Remove unused `Tests` directory ([#32](https://github.com/swiftwasm/JavaScriptKit/pull/32)) via [@MaxDesiatov]
280299

281-
[@MaxDesiatov]: https://github.com/MaxDesiatov
300+
[@maxdesiatov]: https://github.com/MaxDesiatov
282301
[@j-f1]: https://github.com/j-f1
283302
[@kateinoigakukun]: https://github.com/kateinoigakukun
284303
[@yonihemi]: https://github.com/yonihemi
285-
[@PatrickPijnappel]: https://github.com/PatrickPijnappel
304+
[@patrickpijnappel]: https://github.com/PatrickPijnappel
286305
[@revolter]: https://github.com/revolter
287306
[@dependabot]: https://github.com/dependabot

IntegrationTests/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ TestSuites/.build/$(CONFIGURATION)/%.wasm: FORCE
88
--triple wasm32-unknown-wasi \
99
--configuration $(CONFIGURATION) \
1010
-Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor \
11+
-Xlinker --export=main \
1112
$(SWIFT_BUILD_FLAGS)
1213

1314
dist/%.wasm: TestSuites/.build/$(CONFIGURATION)/%.wasm

IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift

+59-10
Original file line numberDiff line numberDiff line change
@@ -356,14 +356,14 @@ try test("Call Function With This") {
356356

357357
try test("Object Conversion") {
358358
let array1 = [1, 2, 3]
359-
let jsArray1 = array1.jsValue().object!
359+
let jsArray1 = array1.jsValue.object!
360360
try expectEqual(jsArray1.length, .number(3))
361361
try expectEqual(jsArray1[0], .number(1))
362362
try expectEqual(jsArray1[1], .number(2))
363363
try expectEqual(jsArray1[2], .number(3))
364364

365365
let array2: [ConvertibleToJSValue] = [1, "str", false]
366-
let jsArray2 = array2.jsValue().object!
366+
let jsArray2 = array2.jsValue.object!
367367
try expectEqual(jsArray2.length, .number(3))
368368
try expectEqual(jsArray2[0], .number(1))
369369
try expectEqual(jsArray2[1], .string("str"))
@@ -374,11 +374,11 @@ try test("Object Conversion") {
374374

375375
try expectEqual(jsArray2[4], .object(jsArray1))
376376

377-
let dict1: [String: ConvertibleToJSValue] = [
378-
"prop1": 1,
379-
"prop2": "foo",
377+
let dict1: [String: JSValue] = [
378+
"prop1": 1.jsValue,
379+
"prop2": "foo".jsValue,
380380
]
381-
let jsDict1 = dict1.jsValue().object!
381+
let jsDict1 = dict1.jsValue.object!
382382
try expectEqual(jsDict1.prop1, .number(1))
383383
try expectEqual(jsDict1.prop2, .string("foo"))
384384
}
@@ -425,7 +425,7 @@ try test("Closure Identifiers") {
425425
#endif
426426

427427
func checkArray<T>(_ array: [T]) throws where T: TypedArrayElement & Equatable {
428-
try expectEqual(toString(JSTypedArray(array).jsValue().object!), jsStringify(array))
428+
try expectEqual(toString(JSTypedArray(array).jsValue.object!), jsStringify(array))
429429
try checkArrayUnsafeBytes(array)
430430
}
431431

@@ -488,7 +488,7 @@ try test("TypedArray_Mutation") {
488488
for i in 0..<100 {
489489
try expectEqual(i, array[i])
490490
}
491-
try expectEqual(toString(array.jsValue().object!), jsStringify(Array(0..<100)))
491+
try expectEqual(toString(array.jsValue.object!), jsStringify(Array(0..<100)))
492492
}
493493

494494
try test("Date") {
@@ -797,11 +797,60 @@ try test("Hashable Conformance") {
797797

798798
let objectConstructor = JSObject.global.Object.function!
799799
let obj = objectConstructor.new()
800-
obj.a = 1.jsValue()
800+
obj.a = 1.jsValue
801801
let firstHash = obj.hashValue
802-
obj.b = 2.jsValue()
802+
obj.b = 2.jsValue
803803
let secondHash = obj.hashValue
804804
try expectEqual(firstHash, secondHash)
805805
}
806806

807+
try test("Symbols") {
808+
let symbol1 = JSSymbol("abc")
809+
let symbol2 = JSSymbol("abc")
810+
try expectNotEqual(symbol1, symbol2)
811+
try expectEqual(symbol1.name, symbol2.name)
812+
try expectEqual(symbol1.name, "abc")
813+
814+
try expectEqual(JSSymbol.iterator, JSSymbol.iterator)
815+
816+
// let hasInstanceClass = {
817+
// prop: function () {}
818+
// }.prop
819+
// Object.defineProperty(hasInstanceClass, Symbol.hasInstance, { value: () => true })
820+
let hasInstanceObject = JSObject.global.Object.function!.new()
821+
hasInstanceObject.prop = JSClosure { _ in .undefined }.jsValue
822+
let hasInstanceClass = hasInstanceObject.prop.function!
823+
let propertyDescriptor = JSObject.global.Object.function!.new()
824+
propertyDescriptor.value = JSClosure { _ in .boolean(true) }.jsValue
825+
_ = JSObject.global.Object.function!.defineProperty!(
826+
hasInstanceClass, JSSymbol.hasInstance,
827+
propertyDescriptor
828+
)
829+
try expectEqual(hasInstanceClass[JSSymbol.hasInstance].function!().boolean, true)
830+
try expectEqual(JSObject.global.Object.isInstanceOf(hasInstanceClass), true)
831+
}
832+
833+
struct AnimalStruct: Decodable {
834+
let name: String
835+
let age: Int
836+
let isCat: Bool
837+
}
838+
839+
try test("JSValueDecoder") {
840+
let Animal = JSObject.global.Animal.function!
841+
let tama = try Animal.throws.new("Tama", 3, true)
842+
let decoder = JSValueDecoder()
843+
let decodedTama = try decoder.decode(AnimalStruct.self, from: tama.jsValue)
844+
845+
try expectEqual(decodedTama.name, tama.name.string)
846+
try expectEqual(decodedTama.name, "Tama")
847+
848+
try expectEqual(decodedTama.age, tama.age.number.map(Int.init))
849+
try expectEqual(decodedTama.age, 3)
850+
851+
try expectEqual(decodedTama.isCat, tama.isCat.boolean)
852+
try expectEqual(decodedTama.isCat, true)
853+
}
854+
855+
807856
Expectation.wait(expectations)

IntegrationTests/lib.js

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const startWasiTask = async (wasmPath) => {
4545
swift.setInstance(instance);
4646
// Start the WebAssembly WASI instance!
4747
wasi.start(instance);
48+
instance.exports._initialize();
49+
instance.exports.main();
4850
};
4951

5052
module.exports = { startWasiTask };

0 commit comments

Comments
 (0)