Skip to content

Commit

Permalink
Consume CWasm3 as XCFramework (#16)
Browse files Browse the repository at this point in the history
This pull request consumes CWasm3 as an XCFramework in order to dramatically improve the library's speed because the XCFramework was compiled with optimizations enabled.

This pull request also formats all of the code according to Shareup's standards, removes support tvOS and watchOS, and increments iOS support to iOS 14.
  • Loading branch information
atdrendel authored Jul 24, 2022
1 parent 3dab007 commit c736641
Show file tree
Hide file tree
Showing 21 changed files with 1,126 additions and 740 deletions.
2 changes: 2 additions & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
5.3.0

7 changes: 7 additions & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--funcattributes prev-line
--minversion 0.47.2
--maxwidth 96
--typeattributes prev-line
--wraparguments before-first
--wrapparameters before-first
--wrapcollections before-first
13 changes: 2 additions & 11 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
{
"object": {
"pins": [
{
"package": "CWasm3",
"repositoryURL": "https://github.com/shareup/cwasm3.git",
"state": {
"branch": null,
"revision": "38335527c3ae87017d2c8993816d0e9612d18fc7",
"version": "0.5.1"
}
},
{
"package": "Synchronized",
"repositoryURL": "https://github.com/shareup/synchronized.git",
"state": {
"branch": null,
"revision": "f01e4a1ee5fbf586d612a8dc0bc068603f6b9450",
"version": "3.0.0"
"revision": "ab58ad52ede004d65ee11b07aebb76392d9c0cec",
"version": "3.1.0"
}
}
]
Expand Down
31 changes: 20 additions & 11 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
// swift-tools-version:5.3
// swift-tools-version:5.5

import PackageDescription

let package = Package(
name: "WasmInterpreter",
platforms: [
.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v5),
.macOS(.v10_15), .iOS(.v14),
],
products: [
.library(
name: "WasmInterpreter",
targets: ["WasmInterpreter"]),
targets: ["WasmInterpreter"]
),
],
dependencies: [
.package(
name: "CWasm3",
url: "https://github.com/shareup/cwasm3.git",
from: "0.5.1"),
.package(
name: "Synchronized",
url: "https://github.com/shareup/synchronized.git",
from: "3.0.0"),
from: "3.1.0"
),
],
targets: [
.target(
name: "WasmInterpreter",
dependencies: ["CWasm3", "Synchronized"],
cSettings: [.define("APPLICATION_EXTENSION_API_ONLY", to: "YES")]),
dependencies: [ "CWasm3", "Synchronized" ],
cSettings: [
.define("APPLICATION_EXTENSION_API_ONLY", to: "YES"),
]
),
.binaryTarget(
name: "CWasm3",
url: "https://github.com/shareup/cwasm3/releases/download/v0.5.2/CWasm3-0.5.0.xcframework.zip",
checksum: "a2b0785be1221767d926cee76b087f168384ec9735b4f46daf26e12fae2109a3"
),
.testTarget(
name: "WasmInterpreterTests",
dependencies: ["WasmInterpreter"],
Expand All @@ -34,6 +41,8 @@ let package = Package(
"Resources/memory.wat",
"Resources/fib64.wat",
"Resources/imported-add.wat",
"Resources/add.wat"]),
"Resources/add.wat",
]
),
]
)
5 changes: 3 additions & 2 deletions Sources/WasmInterpreter/ImportedFunctionCache.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import CWasm3
import Foundation
import Synchronized
import CWasm3

// MARK: - Managing imported functions

Expand Down Expand Up @@ -85,4 +85,5 @@ func makeRawPointer(for id: UInt64) -> UnsafeMutableRawPointer {

private let lock = Lock()
private var lastInstanceIdentifier: UInt64 = 0
private var importedFunctionCache = [UInt64: [UnsafeMutableRawPointer: ImportedFunctionSignature]]()
private var importedFunctionCache =
[UInt64: [UnsafeMutableRawPointer: ImportedFunctionSignature]]()
27 changes: 17 additions & 10 deletions Sources/WasmInterpreter/NativeFunction.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Foundation
import CWasm3
import Foundation

struct NativeFunction {
static func argument<Arg: WasmTypeProtocol>(
from stack: UnsafeMutablePointer<UInt64>?,
at index: Int
) throws -> Arg {
guard let stack = UnsafeMutableRawPointer(stack) else { throw WasmInterpreterError.invalidStackPointer }
guard let stack = UnsafeMutableRawPointer(stack)
else { throw WasmInterpreterError.invalidStackPointer }
guard isValidWasmType(Arg.self) else {
throw WasmInterpreterError.unsupportedWasmType(String(describing: Arg.self))
}
Expand All @@ -30,7 +31,8 @@ struct NativeFunction {
withTypes types: [WasmType],
from stack: UnsafeMutablePointer<UInt64>?
) throws -> [WasmValue] {
guard let stack = UnsafeMutableRawPointer(stack) else { throw WasmInterpreterError.invalidStackPointer }
guard let stack = UnsafeMutableRawPointer(stack)
else { throw WasmInterpreterError.invalidStackPointer }

var values = [WasmValue]()
for (index, type) in types.enumerated() {
Expand Down Expand Up @@ -77,7 +79,8 @@ struct NativeFunction {
_ ret: Ret,
to stack: UnsafeMutablePointer<UInt64>?
) throws {
guard let stack = UnsafeMutableRawPointer(stack) else { throw WasmInterpreterError.invalidStackPointer }
guard let stack = UnsafeMutableRawPointer(stack)
else { throw WasmInterpreterError.invalidStackPointer }
guard isValidWasmType(Ret.self) else {
throw WasmInterpreterError.unsupportedWasmType(String(describing: Ret.self))
}
Expand All @@ -92,17 +95,21 @@ struct NativeFunction {
/// - Parameters:
/// - ret: The value to return from the imported function.
/// - stack: The stack pointer.
static func pushReturnValue(_ ret: WasmValue, to stack: UnsafeMutablePointer<UInt64>?) throws {
guard let stack = UnsafeMutableRawPointer(stack) else { throw WasmInterpreterError.invalidStackPointer }
static func pushReturnValue(
_ ret: WasmValue,
to stack: UnsafeMutablePointer<UInt64>?
) throws {
guard let stack = UnsafeMutableRawPointer(stack)
else { throw WasmInterpreterError.invalidStackPointer }

switch ret {
case .int32(let value):
case let .int32(value):
stack.storeBytes(of: value, as: Int32.self)
case .int64(let value):
case let .int64(value):
stack.storeBytes(of: value, as: Int64.self)
case .float32(let value):
case let .float32(value):
stack.storeBytes(of: value, as: Float32.self)
case .float64(let value):
case let .float64(value):
stack.storeBytes(of: value, as: Float64.self)
}
}
Expand Down
32 changes: 21 additions & 11 deletions Sources/WasmInterpreter/NativeFunctionSignature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ func signature<Arg1, Arg2, Arg3, Ret>(
arg3: Arg3.Type,
ret: Ret.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Ret: WasmTypeProtocol
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Ret: WasmTypeProtocol
{
var signature = ""
signature += try signatureIdentifier(for: ret.self)
Expand All @@ -100,7 +101,8 @@ func signature<Arg1, Arg2, Arg3, Arg4>(
arg3: Arg3.Type,
arg4: Arg4.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol
{
var signature = "v"
signature += "("
Expand Down Expand Up @@ -209,7 +211,8 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Ret>(
arg6: Arg6.Type,
ret: Ret.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol,
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Ret: WasmTypeProtocol
{
var signature = ""
Expand All @@ -234,7 +237,8 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7>(
arg6: Arg6.Type,
arg7: Arg7.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol,
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol
{
var signature = "v"
Expand All @@ -260,8 +264,10 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Ret>(
arg7: Arg7.Type,
ret: Ret.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol, Ret: WasmTypeProtocol
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol,
Ret: WasmTypeProtocol
{
var signature = ""
signature += try signatureIdentifier(for: ret.self)
Expand All @@ -287,8 +293,10 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8>(
arg7: Arg7.Type,
arg8: Arg8.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol, Arg8: WasmTypeProtocol
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol,
Arg8: WasmTypeProtocol
{
var signature = "v"
signature += "("
Expand All @@ -315,8 +323,10 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Ret>(
arg8: Arg8.Type,
ret: Ret.Type
) throws -> String
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol, Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol, Arg8: WasmTypeProtocol, Ret: WasmTypeProtocol
where Arg1: WasmTypeProtocol, Arg2: WasmTypeProtocol, Arg3: WasmTypeProtocol,
Arg4: WasmTypeProtocol,
Arg5: WasmTypeProtocol, Arg6: WasmTypeProtocol, Arg7: WasmTypeProtocol,
Arg8: WasmTypeProtocol, Ret: WasmTypeProtocol
{
var signature = ""
signature += try signatureIdentifier(for: ret.self)
Expand All @@ -333,7 +343,7 @@ func signature<Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Ret>(
return signature
}

func signatureIdentifier<T: WasmTypeProtocol>(for type: T.Type) throws -> String {
func signatureIdentifier<T: WasmTypeProtocol>(for _: T.Type) throws -> String {
if Int32.self == T.self { return "i" }
else if Int64.self == T.self { return "I" }
else if Float32.self == T.self { return "f" }
Expand Down
4 changes: 2 additions & 2 deletions Sources/WasmInterpreter/String+WasmInterpreter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension Array where Element == String {
buffer.append(0)
}

return try buffer.withUnsafeBufferPointer { (buffer) -> Result in
return try buffer.withUnsafeBufferPointer { buffer -> Result in
let pointer = UnsafeRawPointer(buffer.baseAddress!)
.bindMemory(to: CChar.self, capacity: buffer.count)
var cStrings: [UnsafePointer<CChar>?] = offsets.map { pointer + $0 }
Expand All @@ -25,7 +25,7 @@ extension Array where Element == String {
}

private extension Array where Element == Int {
func offsetsAndTotalLength() -> (Array<Int>, Int) {
func offsetsAndTotalLength() -> ([Int], Int) {
var output = [0]
var total = 0
for length in self {
Expand Down
Loading

0 comments on commit c736641

Please sign in to comment.