-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Description
I'm seeing some strange behaviour when using classes/ARC in WebAssembly/Embedded (might be unrelated):
In some cases calls to deinit
seem to be missing, and in some cases, deinit
seems to be called before a last use of the instance.
Reproduction
Missing deinit
@_extern(wasm, module: "foo", name: "a")
@_extern(c)
func foo_a()
@_extern(wasm, module: "foo", name: "b")
@_extern(c)
func foo_b()
@_extern(wasm, module: "foo", name: "c")
@_extern(c)
func foo_c()
class Foo {
init() {
foo_a()
}
func foo() {
foo_b()
}
deinit {
foo_c()
}
}
@_expose(wasm, "test1")
@_cdecl("test1")
func test1() {
let foo = Foo()
foo.foo()
}
gets compiled to (pseudo-code produced by wasm-decompile
):
export function test1() {
foo_a();
foo_b();
}
Why is the call to foo_c
in deinit
missing?
Deinit before last use
@_extern(wasm, module: "bar", name: "new")
@_extern(c)
func bar_new() -> UnsafeMutablePointer<Int>
@_extern(wasm, module: "bar", name: "use")
@_extern(c)
func bar_use(_ ptr: UnsafeMutablePointer<Int>)
@_extern(wasm, module: "bar", name: "free")
@_extern(c)
func bar_free(_ ptr: UnsafeMutablePointer<Int>)
class Bar {
let ptr: UnsafeMutablePointer<Int>
init() {
ptr = bar_new()
}
func use() {
bar_use(ptr)
}
deinit {
bar_free(ptr)
}
}
@_expose(wasm, "test2")
@_cdecl("test2")
func test2() {
let bar = Bar()
bar.use()
}
gets compiled to:
export function test2() {
var a:int = bar_new();
bar_free(a);
bar_use(a);
}
Note the order: Why is bar_free
called before bar_use
?
Is this expected? If so, how so? If not, are these bugs? They might not be related to WebAssembly or Embedded at all, it is just the combination I'm trying out and can easily reproduce locally.
Expected behavior
I had assumed that the results are:
export function test1() {
foo_a();
foo_b();
foo_c();
}
and
export function test2() {
var a:int = bar_new();
bar_use(a);
bar_free(a);
}
Environment
Swift version 6.0-dev (LLVM cef183591317ec7, Swift 66e311074bff491)
/ swift-DEVELOPMENT-SNAPSHOT-2024-05-15-a-ubuntu22.04
, and the following flags in the Package.swift
file:
cSettings: [
.unsafeFlags(["-fdeclspec"])
],
swiftSettings: [
.enableExperimentalFeature("Embedded"),
.interoperabilityMode(.C),
.unsafeFlags([
"-wmo",
"-disable-cmo",
"-Xfrontend", "-disable-stack-protector"
])
],
linkerSettings: [
.unsafeFlags([
"-Xclang-linker", "-nostdlib",
"-Xlinker", "--no-entry"
])
]
Additional information
Asked about this in the forum https://forums.swift.org/t/bug-in-embedded-arc-webassembly-combination/71967.
@kubamracek asked me to open a bug report