You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since Swift 6.0 (at the latest – I think we were previously using 5.7 with SwiftWasm) all empty arrays seem to point to the same base address.
A simpler reproducer is as follows:
[Int]().withUnsafeBufferPointer { ptr in
print(Int(bitPattern: ptr.baseAddress!)) // same
print(Int(bitPattern: ptr.baseAddress!) % 8)
}
[Float]().withUnsafeBufferPointer { ptr in
print(Int(bitPattern: ptr.baseAddress!)) // same
print(Int(bitPattern: ptr.baseAddress!) % 8)
}
[Double]().withUnsafeBufferPointer { ptr in
print(Int(bitPattern: ptr.baseAddress!)) // same
print(Int(bitPattern: ptr.baseAddress!) % 8)
}
The base address is always the same value in my testing (6.0.2 release SDK and toolchain) and is always indivisible by 8 (MemoryLayout<Double>.alignment).
In theory this is probably fine, but it breaks invariants in JavaScriptKit. Specifically, JSTypedArray([Double]()) passes the base address to new Float64Array, which cannot have a base address indivisible by 8. Double arrays that actually contain values do not have this issue, presumably because there the invariant is upheld by Swift itself (aligning the first value with a memory address divisible by MemoryLayout<Double>.alignment).
This behaviour does not seem to be unique to SwiftWasm (the base address also appears stable for all empty array types, even across multiple runs of a program), but on my machine the address is divisible by 8. I guess it's because my Mac is on arm64, meaning all pointers will be aligned to the word size of 8 bytes. I'm assuming on wasm (being a 32bit platform) all pointers, at the base level, are simply required to be aligned to the word length – that doesn't appear to be enough in all cases.
To work around this, it'd probably be enough to ensure the default address is aligned to 8 instead of 4, but I'm not sure of the implications of doing that otherwise.
We have run into this problem in a number of different cases, hindering our adoption of Swift 6 so far.
Do you have any ideas on how to fix this?
The text was updated successfully, but these errors were encountered:
ephemer
changed the title
Base address of every empty array seems to be the same
Base address of every empty array seems to be the same: issues where type alignment > word size
Dec 5, 2024
The alignment requirement in TypedArray is based on its element type, (e.g. Float32Array -> 4 bytes alignment, Float64Array -> 8 bytes alignment). But as you noticed, Swift's empty array shares the same storage for all element types, so baseAddress can be unaligned. I made a change to create empty arrays without referencing Swift pointer swiftwasm/JavaScriptKit#278
Hi @kateinoigakukun,
Since Swift 6.0 (at the latest – I think we were previously using 5.7 with SwiftWasm) all empty arrays seem to point to the same base address.
A simpler reproducer is as follows:
The base address is always the same value in my testing (6.0.2 release SDK and toolchain) and is always indivisible by 8 (
MemoryLayout<Double>.alignment
).In theory this is probably fine, but it breaks invariants in
JavaScriptKit
. Specifically,JSTypedArray([Double]())
passes the base address tonew Float64Array
, which cannot have a base address indivisible by 8.Double
arrays that actually contain values do not have this issue, presumably because there the invariant is upheld by Swift itself (aligning the first value with a memory address divisible byMemoryLayout<Double>.alignment
).This behaviour does not seem to be unique to SwiftWasm (the base address also appears stable for all empty array types, even across multiple runs of a program), but on my machine the address is divisible by 8. I guess it's because my Mac is on arm64, meaning all pointers will be aligned to the word size of 8 bytes. I'm assuming on wasm (being a 32bit platform) all pointers, at the base level, are simply required to be aligned to the word length – that doesn't appear to be enough in all cases.
To work around this, it'd probably be enough to ensure the default address is aligned to 8 instead of 4, but I'm not sure of the implications of doing that otherwise.
We have run into this problem in a number of different cases, hindering our adoption of Swift 6 so far.
Do you have any ideas on how to fix this?
The text was updated successfully, but these errors were encountered: