@@ -159,27 +159,70 @@ package struct Run: AsyncParsableCommand {
159159
160160 log ( " Started parsing module " , verbose: true )
161161
162- // Detect file type (component vs module)
163162 let filePath = FilePath ( path)
164- let fileType = try detectWasmFileType ( filePath : filePath )
163+ let module : Module
165164
166- #if ComponentModel
167- if fileType == . component {
168- try runComponent ( filePath: filePath)
169- return
165+ if filePath. extension == " wat " {
166+ let fileHandle : FileDescriptor = try FileDescriptor . open ( filePath, Platform . readOnlyTextAccessMode)
167+ module = try withThrowing {
168+ let size = try fileHandle. seek ( offset: 0 , from: . end)
169+ _ = try fileHandle. seek ( offset: 0 , from: . start)
170+ let wat = try String ( unsafeUninitializedCapacity: Int ( size) ) {
171+ try fileHandle. read ( into: UnsafeMutableRawBufferPointer ( $0) )
172+ }
173+ return try WasmKit . parseWasm ( bytes: wat2wasm ( wat) )
174+ } defer: {
175+ try fileHandle. close ( )
170176 }
171- #endif
177+ } else {
178+ let fileHandle : FileDescriptor = try FileDescriptor . open ( filePath, Platform . readOnlyBinaryAccessMode)
179+ #if ComponentModel
180+ var parsedComponent : ParsedComponent ?
181+ #endif
182+ let parsedModule : Module ? = try withThrowing { ( ) throws -> Module ? in
183+ var magic : ( UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 ) = ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
184+ let bytesRead = try withUnsafeMutableBytes ( of: & magic) { buffer in
185+ try fileHandle. read ( into: buffer)
186+ }
172187
173- // Regular module execution
174- let module : Module
175- if verbose, #available( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , * ) {
176- let ( parsedModule, parseTime) = try measure {
177- try parseWasm ( filePath: filePath)
188+ // Detect file type (component vs module)
189+ let fileType : WasmFileType
190+ if bytesRead == MemoryLayout . size ( ofValue: magic) {
191+ fileType = detectWasmFileType ( magic)
192+ } else {
193+ fileType = . unknown
194+ }
195+
196+ #if ComponentModel
197+ if fileType == . component {
198+ log ( " Detected component binary, parsing component... " , verbose: true )
199+ _ = try fileHandle. seek ( offset: 0 , from: . start)
200+ parsedComponent = try parseComponent ( fileHandle: fileHandle)
201+ return nil
202+ }
203+ #endif
204+
205+ guard fileType == . coreModule else {
206+ fatalError ( " Unsupported WebAssembly file type: \( fileType) " )
207+ }
208+
209+ _ = try fileHandle. seek ( offset: 0 , from: . start)
210+ let ( parsedModule, parseTime) = try measure {
211+ try WasmKit . parseWasm ( fileHandle: fileHandle)
212+ }
213+ log ( " Finished parsing module: \( parseTime) " , verbose: true )
214+ return parsedModule
215+ } defer: {
216+ try fileHandle. close ( )
178217 }
179- log ( " Finished parsing module: \( parseTime) " , verbose: true )
218+ #if ComponentModel
219+ if let parsedComponent {
220+ try runComponent ( component: parsedComponent)
221+ return
222+ }
223+ #endif
224+ guard let parsedModule else { return }
180225 module = parsedModule
181- } else {
182- module = try parseWasm ( filePath: filePath)
183226 }
184227
185228 let ( interceptor, finalize) = try deriveInterceptor ( )
@@ -205,11 +248,7 @@ package struct Run: AsyncParsableCommand {
205248
206249 #if ComponentModel
207250 /// Run a WebAssembly component.
208- func runComponent( filePath: FilePath ) throws {
209- log ( " Detected component binary, parsing component... " , verbose: true )
210-
211- let component = try parseComponent ( filePath: filePath)
212-
251+ func runComponent( component: ParsedComponent ) throws {
213252 let engine = Engine ( configuration: deriveRuntimeConfiguration ( ) )
214253 let store = Store ( engine: engine)
215254 let loader = ComponentLoader ( store: store)
@@ -350,25 +389,6 @@ package struct Run: AsyncParsableCommand {
350389 }
351390}
352391
353- /// Parses a `.wasm` or `.wat` module.
354- func parseWasm( filePath: FilePath ) throws -> Module {
355- if filePath. extension == " wat " , #available( macOS 11 . 0 , iOS 14 . 0 , macCatalyst 14 . 0 , tvOS 14 . 0 , visionOS 1 . 0 , watchOS 7 . 0 , * ) {
356- let fileHandle = try FileDescriptor . open ( filePath, . readOnly)
357- return try withThrowing {
358- let size = try fileHandle. seek ( offset: 0 , from: . end)
359-
360- let wat = try String ( unsafeUninitializedCapacity: Int ( size) ) {
361- try fileHandle. read ( fromAbsoluteOffset: 0 , into: . init( $0) )
362- }
363- return try WasmKit . parseWasm ( bytes: wat2wasm ( wat) )
364- } defer: {
365- try fileHandle. close ( )
366- }
367- } else {
368- return try WasmKit . parseWasm ( filePath: filePath)
369- }
370- }
371-
372392extension Run {
373393 package static func parseInvocation( arguments: [ String ] ) -> ( functionName: String ? , parameters: [ Value ] ) {
374394 let functionName = arguments. first
0 commit comments