1+ import WasmParser
12/// > Note:
23/// <https://webassembly.github.io/spec/core/exec/instructions.html#memory-instructions>
3- import WasmParser
4+ import _CWasmKit
45
56extension Execution {
67 @inline ( never) func throwOutOfBoundsMemoryAccess( ) throws -> Never {
@@ -118,11 +119,16 @@ extension Execution {
118119 }
119120 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( length &+ loadOperand. offset)
120121 if _fastPath ( !isEndOverflow && endAddress <= ms) {
121- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
122- . bindMemory ( to: T . self, capacity: 1 )
123- // Use atomic load with acquire ordering (sequentially consistent)
124- let loaded = ptr. pointee
125- sp [ loadOperand. result] = castToValue ( loaded. littleEndian)
122+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
123+ let loaded : T
124+ switch T . bitWidth {
125+ case 8 : loaded = T ( wasmkit_atomic_load_8 ( rawPtr) )
126+ case 16 : loaded = T ( wasmkit_atomic_load_16 ( rawPtr) )
127+ case 32 : loaded = T ( wasmkit_atomic_load_32 ( rawPtr) )
128+ case 64 : loaded = T ( wasmkit_atomic_load_64 ( rawPtr) )
129+ default : fatalError ( )
130+ }
131+ sp [ loadOperand. result] = castToValue ( loaded)
126132 } else {
127133 try throwOutOfBoundsMemoryAccess ( )
128134 }
@@ -143,10 +149,14 @@ extension Execution {
143149 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( length &+ storeOperand. offset)
144150 if _fastPath ( !isEndOverflow && endAddress <= ms) {
145151 let toStore = castFromValue ( value)
146- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
147- . bindMemory ( to: T . self, capacity: 1 )
148- // Atomic store
149- ptr. pointee = toStore. littleEndian
152+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
153+ switch T . bitWidth {
154+ case 8 : wasmkit_atomic_store_8 ( rawPtr, UInt8 ( truncatingIfNeeded: toStore) )
155+ case 16 : wasmkit_atomic_store_16 ( rawPtr, UInt16 ( truncatingIfNeeded: toStore) )
156+ case 32 : wasmkit_atomic_store_32 ( rawPtr, UInt32 ( truncatingIfNeeded: toStore) )
157+ case 64 : wasmkit_atomic_store_64 ( rawPtr, UInt64 ( truncatingIfNeeded: toStore) )
158+ default : fatalError ( )
159+ }
150160 } else {
151161 try throwOutOfBoundsMemoryAccess ( )
152162 }
@@ -158,7 +168,7 @@ extension Execution {
158168 mutating func atomicRmw< T: FixedWidthInteger > (
159169 sp: Sp , md: Md , ms: Ms , rmwOperand: Instruction . RmwOperand ,
160170 loadAs _: T . Type = T . self,
161- operation : ( T , T ) -> T ,
171+ atomicOp : ( UnsafeMutableRawPointer , T ) -> T ,
162172 castFromValue: ( UntypedValue ) -> T ,
163173 castToValue: ( T ) -> UntypedValue
164174 ) throws {
@@ -171,13 +181,9 @@ extension Execution {
171181 }
172182 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( length &+ rmwOperand. offset)
173183 if _fastPath ( !isEndOverflow && endAddress <= ms) {
174- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
175- . bindMemory ( to: T . self, capacity: 1 )
184+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
176185 let value = castFromValue ( sp [ rmwOperand. value] )
177- // Atomic read-modify-write
178- let oldValue = ptr. pointee. littleEndian
179- let newValue = operation ( oldValue, value)
180- ptr. pointee = newValue. littleEndian
186+ let oldValue = atomicOp ( rawPtr, value)
181187 sp [ rmwOperand. result] = castToValue ( oldValue)
182188 } else {
183189 try throwOutOfBoundsMemoryAccess ( )
@@ -188,6 +194,7 @@ extension Execution {
188194 mutating func atomicCmpxchg< T: FixedWidthInteger > (
189195 sp: Sp , md: Md , ms: Ms , cmpxchgOperand: Instruction . CmpxchgOperand ,
190196 loadAs _: T . Type = T . self,
197+ atomicCmpxchg: ( UnsafeMutableRawPointer , T , T ) -> T ,
191198 castFromValue: ( UntypedValue ) -> T ,
192199 castToValue: ( T ) -> UntypedValue
193200 ) throws {
@@ -200,15 +207,11 @@ extension Execution {
200207 }
201208 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( length &+ cmpxchgOperand. offset)
202209 if _fastPath ( !isEndOverflow && endAddress <= ms) {
203- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
204- . bindMemory ( to: T . self, capacity: 1 )
210+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
205211 let expectedValue = castFromValue ( sp [ cmpxchgOperand. expected] )
206212 let replacementValue = castFromValue ( sp [ cmpxchgOperand. replacement] )
207- let currentValue = ptr. pointee. littleEndian
208- if currentValue == expectedValue {
209- ptr. pointee = replacementValue. littleEndian
210- }
211- sp [ cmpxchgOperand. result] = castToValue ( currentValue)
213+ let resultValue = atomicCmpxchg ( rawPtr, expectedValue, replacementValue)
214+ sp [ cmpxchgOperand. result] = castToValue ( resultValue)
212215 } else {
213216 try throwOutOfBoundsMemoryAccess ( )
214217 }
@@ -226,9 +229,8 @@ extension Execution {
226229 }
227230 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( 4 &+ waitOperand. offset)
228231 if _fastPath ( !isEndOverflow && endAddress <= ms) {
229- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
230- . bindMemory ( to: UInt32 . self, capacity: 1 )
231- let currentValue = ptr. pointee. littleEndian
232+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
233+ let currentValue = wasmkit_atomic_load_32 ( rawPtr)
232234 let expectedValue = sp [ waitOperand. expected] . i32
233235 let timeout = sp [ waitOperand. timeout] . i64
234236
@@ -257,7 +259,7 @@ extension Execution {
257259 address: UInt64 ( address) ,
258260 validate: {
259261 // Re-check the value atomically
260- let currentValue = ptr . pointee . littleEndian
262+ let currentValue = wasmkit_atomic_load_32 ( rawPtr )
261263 return currentValue == expectedValue
262264 } ,
263265 deadline: deadline,
@@ -286,9 +288,8 @@ extension Execution {
286288 }
287289 let ( endAddress, isEndOverflow) = i. addingReportingOverflow ( 8 &+ waitOperand. offset)
288290 if _fastPath ( !isEndOverflow && endAddress <= ms) {
289- let ptr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
290- . bindMemory ( to: UInt64 . self, capacity: 1 )
291- let currentValue = ptr. pointee. littleEndian
291+ let rawPtr = md. unsafelyUnwrapped. advanced ( by: Int ( address) )
292+ let currentValue = wasmkit_atomic_load_64 ( rawPtr)
292293 let expectedValue = sp [ waitOperand. expected] . i64
293294 let timeout = sp [ waitOperand. timeout] . i64
294295
@@ -317,7 +318,7 @@ extension Execution {
317318 address: UInt64 ( address) ,
318319 validate: {
319320 // Re-check the value atomically
320- let currentValue = ptr . pointee . littleEndian
321+ let currentValue = wasmkit_atomic_load_64 ( rawPtr )
321322 return currentValue == expectedValue
322323 } ,
323324 deadline: deadline,
@@ -350,4 +351,9 @@ extension Execution {
350351 try throwOutOfBoundsMemoryAccess ( )
351352 }
352353 }
354+
355+ /// Atomic fence - sequential consistency barrier
356+ mutating func atomicFence( sp: Sp ) {
357+ wasmkit_atomic_fence ( )
358+ }
353359}
0 commit comments