---
title: "Zig e WebAssembly — Resolver Problemas com WASM"
url: "https://ziglang.com.br/troubleshooting/zig-e-webassembly-resolver-problemas-com-wasm/"
markdown_url: "https://ziglang.com.br/troubleshooting/zig-e-webassembly-resolver-problemas-com-wasm.MD"
description: "Guia para resolver problemas de compilação e execução WebAssembly com Zig. Targets WASM, exports, imports, memória, JavaScript interop e debugging WASM."
date: "2026-02-21"
author: "Zig Brasil"
---

# Zig e WebAssembly — Resolver Problemas com WASM

Guia para resolver problemas de compilação e execução WebAssembly com Zig. Targets WASM, exports, imports, memória, JavaScript interop e debugging WASM.


# Zig e WebAssembly — Resolver Problemas com WASM

Zig compila nativamente para WebAssembly, produzindo binários pequenos e eficientes. Este guia resolve os problemas mais comuns ao trabalhar com WASM.

## Escolhendo o Target WASM Correto

```bash
# WASM para browser (sem sistema operacional)
zig build -Dtarget=wasm32-freestanding

# WASM com WASI (para runtimes como Wasmtime, Wasmer)
zig build -Dtarget=wasm32-wasi

# Diferenças:
# freestanding: sem I/O, sem filesystem, para browser
# wasi: com I/O básico, para server-side WASM
```

## Erro: Funções Não Exportadas

**Sintoma:** JavaScript não consegue chamar funções do WASM.

```zig
// PROBLEMA: funções não são exportadas por padrão

// SOLUÇÃO: usar export
export fn somar(a: i32, b: i32) i32 {
    return a + b;
}

// Ou usar callconv(.C) para compatibilidade
fn multiplicar(a: i32, b: i32) callconv(.C) i32 {
    return a * b;
}
```

```zig
// No build.zig — garantir exports
const lib = b.addSharedLibrary(.{
    .name = "meu-modulo",
    .root_source_file = b.path("src/lib.zig"),
    .target = b.resolveTargetQuery(.{
        .cpu_arch = .wasm32,
        .os_tag = .freestanding,
    }),
    .optimize = optimize,
});

// Exportar símbolos específicos
lib.export_symbol_names = &.{ "somar", "multiplicar" };

// Ou não definir entry point para library
lib.entry_point = null;
```

## Erro: "memory out of bounds"

**Causa:** O WASM tem memória limitada por padrão.

```zig
// No build.zig — aumentar memória inicial
lib.initial_memory = 65536 * 16; // 1MB
lib.max_memory = 65536 * 256;    // 16MB

// Ou deixar a memória crescer
lib.import_memory = true; // Memória gerenciada pelo host
```

```javascript
// No JavaScript — definir memória
const memory = new WebAssembly.Memory({
    initial: 256,  // 256 páginas = 16MB
    maximum: 1024, // 1024 páginas = 64MB
});

const importObject = {
    env: { memory: memory }
};
```

## Problema: Carregar WASM no Browser

```javascript
// Método moderno de carregar WASM
async function carregarWasm() {
    const response = await fetch('modulo.wasm');
    const bytes = await response.arrayBuffer();
    const { instance } = await WebAssembly.instantiate(bytes, {
        env: {
            // Imports que o Zig precisa
        }
    });

    // Chamar funções exportadas
    const resultado = instance.exports.somar(2, 3);
    console.log('Resultado:', resultado); // 5
}

carregarWasm();
```

## Problema: std.debug.print Não Funciona

**Causa:** Em WASM freestanding, não existe console/stdout.

```zig
// PROBLEMA: não funciona em WASM freestanding
// std.debug.print("Hello\n", .{});

// SOLUÇÃO 1: Importar função de log do JavaScript
extern fn js_log(ptr: [*]const u8, len: usize) void;

fn log(msg: []const u8) void {
    js_log(msg.ptr, msg.len);
}

export fn processar() void {
    log("Processando...");
}
```

```javascript
// No JavaScript — fornecer a função de log
const importObject = {
    env: {
        js_log: (ptr, len) => {
            const bytes = new Uint8Array(instance.exports.memory.buffer, ptr, len);
            const text = new TextDecoder().decode(bytes);
            console.log(text);
        }
    }
};
```

## Problema: Compartilhar Strings entre Zig e JavaScript

```zig
// Zig: exportar ponteiro e tamanho
var resultado_global: []const u8 = "";

export fn processar_texto(ptr: [*]const u8, len: usize) void {
    const input = ptr[0..len];
    // ...processar input...
    _ = input;
}

export fn get_resultado_ptr() [*]const u8 {
    return resultado_global.ptr;
}

export fn get_resultado_len() usize {
    return resultado_global.len;
}
```

```javascript
// JavaScript: enviar e receber strings
function enviarString(instance, texto) {
    const encoder = new TextEncoder();
    const bytes = encoder.encode(texto);

    // Copiar para memória WASM
    const ptr = instance.exports.alocar(bytes.length);
    const mem = new Uint8Array(instance.exports.memory.buffer);
    mem.set(bytes, ptr);

    instance.exports.processar_texto(ptr, bytes.length);
}
```

## Problema: Allocator em WASM

```zig
// WASM freestanding não tem malloc por padrão
// Use FixedBufferAllocator ou page_allocator

// Opção 1: Buffer fixo
var buffer: [65536]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&buffer);

// Opção 2: Page allocator (funciona em WASM)
const allocator = std.heap.page_allocator;

// Opção 3: Exportar allocator para JavaScript controlar
export fn alocar(tamanho: usize) ?[*]u8 {
    const slice = std.heap.page_allocator.alloc(u8, tamanho) catch return null;
    return slice.ptr;
}

export fn liberar(ptr: [*]u8, tamanho: usize) void {
    std.heap.page_allocator.free(ptr[0..tamanho]);
}
```

## Problema: Tamanho do WASM Grande

```bash
# Compilar para tamanho mínimo
zig build -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall

# Verificar tamanho
ls -la zig-out/lib/modulo.wasm
wc -c zig-out/lib/modulo.wasm

# Usar wasm-opt para otimizar ainda mais (binaryen)
wasm-opt -Oz modulo.wasm -o modulo-opt.wasm

# Remover seções desnecessárias
wasm-strip modulo.wasm
```

## WASI: Rodar Fora do Browser

```bash
# Compilar para WASI
zig build -Dtarget=wasm32-wasi

# Executar com Wasmtime
wasmtime ./zig-out/bin/meu-app.wasm

# Executar com Wasmer
wasmer ./zig-out/bin/meu-app.wasm

# Com acesso a diretório
wasmtime --dir=. ./zig-out/bin/meu-app.wasm
```

## Debugging WASM

```bash
# Compilar com debug info
zig build -Dtarget=wasm32-freestanding

# No browser: Chrome DevTools > Sources > WASM
# Firefox também suporta debugging de WASM

# Usar wasm2wat para inspecionar o módulo (wabt tools)
wasm2wat modulo.wasm -o modulo.wat
```

## Veja Também

- [FAQ Performance](/faq/faq-performance/) — WASM e performance
- [Cross-Compile Falha](/troubleshooting/zig-cross-compile-falha/) — Compilação cruzada
- [FAQ Build System](/faq/faq-build-system/) — Configuração de targets
- [Embedded Debug](/troubleshooting/zig-embedded-debug/) — Ambientes restritos
- [Receitas](/receitas/) — Exemplos de WASM com Zig
