WebAssembly et Swift : intégration avancée sur iOS/macOS

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction à WebAssembly pour les développeurs Swift



WebAssembly (Wasm) est un jeu d'instructions binaires de bas niveau qui s'exécute dans une machine virtuelle isolée. Pour un développeur Swift sur iOS/macOS, l'intégration de Wasm ouvre de nouveaux horizons : portage de code depuis d'autres langages, bac à sable pour les bibliothèques tierces et exécution de calculs haute performance sans code natif. Dans cet article, nous explorerons les techniques avancées de travail avec WebAssembly en Swift : de la compilation à la manipulation directe de la mémoire et à l'appel de fonctions.



Contrairement aux tutoriels de base, nous nous concentrerons sur des tâches réelles : transmission de types de données complexes, gestion manuelle de la mémoire et optimisation des performances. Il est supposé que vous êtes déjà familier avec les bases de Swift et le concept fondamental de WebAssembly.



Compilation de code en WebAssembly pour Swift



Outils et configuration



Pour compiler du code tiers (C/C++/Rust) en Wasm, utilisez Emscripten ou wasm-pack (pour Rust). Pour du Swift pur, il existe le projet SwiftWasm, mais il est limité. Le plus souvent, vous intégrerez des modules prêts à l'emploi.



Exemple de compilation d'une simple fonction C en Wasm :



// math.cint add(int a, int b) {    return a + b;}


Commande :



emcc math.c -o math.wasm -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -Os


Indicateurs clés : EXPORTED_FUNCTIONS — spécifie les fonctions à exporter, -Os — optimisation de la taille. Le fichier math.wasm obtenu est prêt à être chargé dans Swift.



Chargement du module en Swift



Sur iOS/macOS, pour travailler avec Wasm, utilisez WasmKit ou WKWebView. Examinons l'option avancée — WasmKit avec gestion directe de la mémoire.



import WasmKit

guard let wasmData = try? Data(contentsOf: URL(fileURLWithPath: "math.wasm")) else { fatalError("Impossible de charger wasm")}

let module = try WasmModule(data: wasmData)let engine = WasmEngine()let instance = try engine.instantiate(module: module)

// Récupération de la fonction exportéeguard let addFunc = instance.export("add")?.function else { fatalError("Fonction add non trouvée")}


Notez que WasmKit nécessite une gestion manuelle des imports et de la mémoire. Cela offre un contrôle total, mais augmente la complexité.



Travail direct avec la mémoire : transmission de tableaux et de chaînes



Mémoire linéaire Wasm



WebAssembly utilise une mémoire linéaire (linear memory) — un tableau plat d'octets. Pour transmettre des structures complexes (tableaux, chaînes), vous devez allouer de la mémoire à l'intérieur de Wasm et copier les données.



Prenons un exemple : transmission d'un tableau d'entiers de Swift à une fonction Wasm qui calcule la somme.



// sum_array.cint sum_array(int* arr, int len) {    int sum = 0;    for (int i = 0; i < len; i++) {        sum += arr[i];    }    return sum;}


Compilation avec exportation de malloc et free :



emcc sum_array.c -o sum_array.wasm -s WASM=1 -s EXPORTED_FUNCTIONS='["_sum_array", "_malloc", "_free"]' -s ALLOW_MEMORY_GROWTH=1


En Swift, nous allouons la mémoire, copions les données et appelons la fonction :



let numbers = [10, 20, 30, 40, 50]let count = numbers.count

// Allocation de mémoire pour le tableau (4 octets par int)guard let mallocFunc = instance.export("malloc")?.function else { return }let ptrResult = mallocFunc.call(Int32(count * MemoryLayout<Int32>.size))guard let ptr = ptrResult?.i32 else { return }

// Copie des données dans la mémoire Wasmlet memory = instance.memory!for i in 0..<count { let offset = ptr + Int32(i * MemoryLayout<Int32>.size) memory.store(offset: Int(offset), value: Int32(numbers[i]))}

// Appel de sum_arrayguard let sumArrayFunc = instance.export("sum_array")?.function else { return }let result = sumArrayFun

Blogs

Book Recommendations