Skip to content

Special exports __zigar

Chung Leong edited this page May 28, 2024 · 4 revisions

Zigar exposes certain utility functions through the symbol __zigar:

init()

Return a promise that resolves when WebAssembly code finishes compiling and all Zig functions can be called synchronously.

const std = @import("std");

pub fn hello() void {
    std.debug.print("hello\n", .{});
}
import { __zigar, hello } from './special-exports-example-1.zig';
const { init } = __zigar;
await init();
hello();
hello

Use of this function is only necessary when topLevelAwait is false. For node-zigar, this function is useless. It returns a promise that resolves immediately.

init() accepts WASI interface object as an a optional argument. Suppose you have transcoded a Zig file to WASM using Rollup. You can run it in Node.js in this manner:

import { WASI } from 'wasi';
import { __zigar, openDoc } from './zig-libx.js';
const { init } = __zigar;

const wasi = new WASI({
    version: 'preview1',
    args: [],
    env: {},
    preopens: {
        '/local': '/var/data',
    },
});
await init(wasi);
const doc = openDoc('/local/file.ext');

The file would have to be transpiled with topLevelAwait set to false.

abandon()

Unload the module from memory. Imported functions would no longer work afterward. This function is meant mainly for automated testing where a large number of modules would get loaded and used only once.

const std = @import("std");

pub fn hello() void {
    std.debug.print("hello\n", .{});
}
import { __zigar, hello } from './special-exports-example-1.zig';
const { abandon } = __zigar;

hello();
abandon();
try {
    hello();
} catch (err) {
    console.log(err.message);
}
hello
Module was abandoned

Unloading does not happen immediately. This function merely removes all references to the module, allowing it to be garbage-collected. It can fail if there're objects allocated from the fixed memory heap sitting somewhere.

released()

Return true if module has been unloaded from memory; false otherwise.

const std = @import("std");

pub fn hello() void {
    std.debug.print("hello\n", .{});
}
import { __zigar } from './special-exports-example-1.zig';
const { abandon, released } = __zigar;

abandon();
// force garbage collection to occur (need --expose-gc)
gc();   
// give V8 a chance to invoke object finalizers
await new Promise(r => setTimeout(r, 0));
console.log(released());

connect(c)

Use a different console object to display output to stdout and stderr. Only its log method will get called, always with a single string as argument.

const std = @import("std");

pub fn hello() void {
    std.debug.print("hello\n", .{});
}
import { __zigar, hello } from './special-exports-example-1.zig';
const { connect } = __zigar;

connect({
    log(s) {
        console.log(`Zig output: "${s}"`);
    }
});
hello();

sizeOf(T)

Return the size of a Zig data structure in bytes.

pub const Struct1 = struct {
    number1: i32,
    number2: i32,
};

pub const Struct2 = struct {
    number1: i64,
    number2: i64,
};
import { __zigar, Struct1, Struct2 } from './special-exports-example-2.zig';
const { sizeOf } = __zigar;

console.log(sizeOf(Struct1));
console.log(sizeOf(Struct2));
8
16

alignOf(T)

Return the alignment of a Zig data structure.

pub const Struct1 = struct {
    number1: i32,
    number2: i32,
};

pub const Struct2 = struct {
    number1: i64,
    number2: i64,
};
import { __zigar, Struct1, Struct2 } from './special-exports-example-2.zig';
const { alignOf } = __zigar;

console.log(alignOf(Struct1));
console.log(alignOf(Struct2));
4
8

typeOf(T)

Return the type of a Zig data structure.

Possible values:

  • primitive
  • array
  • struct
  • extern struct
  • packed struct
  • extern union
  • bare union
  • tagged union
  • error union
  • error set
  • enum
  • optional
  • pointer
  • slice
  • vector
  • opaque
pub const Error = error { fell_victim_to_micro_aggression };

pub const Struct = struct {
    number1: i32,
    number2: i32,
};
pub const StructEU = Error!Struct;
pub const StructO = ?Struct;

pub const Union = union(enum) {
    number1: i32,
    number2: i64,
};
import { 
    __zigar, 
    Error, 
    Struct, 
    StructEU, 
    StructO, 
    Union 
} from './special-exports-example-3.zig';
const { typeOf } = __zigar;

console.log(typeOf(Error));
console.log(typeOf(Struct));
console.log(typeOf(StructEU));
console.log(typeOf(StructO));
console.log(typeOf(Union));
error set
struct
error union
optional
tagged union
Clone this wiki locally