Skip to content

Functions

Chung Leong edited this page Apr 16, 2024 · 5 revisions

A function written in Zig can be made available for use in JavaScript provided that it does not:

  • Accept any comptime argument
  • Accept anytype as argument
  • Accept a function pointer as argument
  • Return a data type that only exists in comptime

Naturally, the function would need to be made public using the pub keyword.

Memory allocator

A function that accepts std.mem.Allocator will automatically get one from Zigar. On the JavaScript side, it will end up with one fewer arguments:

const std = @import("std");

pub fn toUpperCase(allocator: std.mem.Allocator, s: []const u8) ![]const u8 {
    return try std.ascii.allocUpperString(allocator, s);
}
import { toUpperCase } from './function-example-1.zig';

console.log(toUpperCase('Hello world').string);
HELLO WORLD

The allocator given is only valid in for the duration of the call. Code that saves a copy of the allocator will likely crash when it tries to use it again. Memory from the allocator comes from the JavaScript language engine, which employs garbage collection. There is never a need to manually free up memory.

Struct methods

A function defined within a struct that accepts an instance of itself as its first argument can be invoked in JavaScript in the manner of an instance method:

pub const Rectangle = struct {
    left: f64,
    right: f64,
    width: f64,
    height: f64,

    pub fn size(self: Rectangle) f64 {
        return self.width * self.height;
    }
};
import { Rectangle } from './function-example-2.zig';

const rect = new Rectangle({ left: 5, right: 10, width: 20, height: 10 });
console.log(rect.size());
200

At the same time, it can be invoked like a static method:

import { Rectangle } from './function-example-2.zig';

console.log(Rectangle.size({ left: 5, right: 10, width: 30, height: 15 }));
450

It works the same way when the self argument is a pointer:

pub const Rectangle = struct {
    left: f64,
    right: f64,
    width: f64,
    height: f64,

    pub fn size(self: *const Rectangle) f64 {
        return self.width * self.height;
    }
};
import { Rectangle } from './function-example-3.zig';

const rect = new Rectangle({ left: 5, right: 10, width: 20, height: 10 });
console.log(rect.size());
console.log(Rectangle.size({ left: 5, right: 10, width: 30, height: 15 }));
200
450

Union, Enum, and Opaque can have methods attached to them in the same way.

Function pointer

Zigar currently does not support function pointers.

Error union

Clone this wiki locally