Skip to content

Instantly share code, notes, and snippets.

View andrewrk's full-sized avatar

Andrew Kelley andrewrk

View GitHub Profile
@andrewrk
andrewrk / demo.zig
Created March 20, 2021 22:05
demonstration of zig's default unit testing allocator catching various mistakes
const std = @import("std");
// leak
test "example 1" {
var array = std.ArrayList(i32).init(std.testing.allocator);
try array.append(1234);
}
// double free
@andrewrk
andrewrk / a.ll
Created February 26, 2021 05:15
LLVM 12 sret LLVMDumpModule
; Function Attrs: nobuiltin noredzone nounwind sspstrong
define void @entry() #1 !dbg !2228 {
Entry:
%0 = alloca %Foo, align 4
call fastcc void @doit(%Foo* sret %0), !dbg !2232
ret void, !dbg !2234
}
; Function Attrs: nobuiltin noredzone nounwind sspstrong
define internal fastcc void @doit(%Foo* nonnull sret %0) unnamed_addr #1 !dbg !2235 {
@andrewrk
andrewrk / builtin.zig
Created February 23, 2021 20:15
`zig build-obj --show-builtin` on an M1. ziglang/zig commit d9e46dceeca3f66b87e6b2e36415417495d2d2a0
usingnamespace @import("std").builtin;
/// Deprecated
pub const arch = Target.current.cpu.arch;
/// Deprecated
pub const endian = Target.current.cpu.arch.endian();
/// Zig version. When writing code that supports multiple versions of Zig, prefer
/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
pub const zig_version = try @import("std").SemanticVersion.parse("0.8.0-dev.1159+d9e46dcee");
@andrewrk
andrewrk / static-window.c
Created November 20, 2020 21:24
experimenting with reloading a static binary to make it dynamic
#include <stdbool.h>
#include <stddef.h>
void __attribute__((weak)) dlopen(const char *filename, int flags);
int __attribute__((weak)) dlclose(void *handle);
struct ZigWindowFns {
void (*dlopen)(const char *filename, int flags);
int (*dlclose)(void *handle);
};
@andrewrk
andrewrk / thin.md
Created October 17, 2020 23:26
Eleanor's proposal

Absolute Zero

Bootstrapping Zig from below C level.

Motivation

The first computer programs were written directly in machine code. To make things easier, automated assemblers were developed, initially in machine code as well and then in their own input language. To make things easier again, high-level (for the time) languages such as BCPL, B, and eventually C were developed, which abstracted some of the details of the underlying architecture and allowed more complex compound logic. These languages were implemented by first writing compilers for subsets of them in assembly, then using those compilers to compile compilers for the full languages. Thus, there was a concrete bootstrap chain extending right down to assembly.

Nowadays, this is a lost art. Quite literally all languages that bootstrap themselves nowadays start from a pre-existing high-level language, usually C or C++, and then reject their roots as soon as they can. Zig stands out by maintaining its bootstrap chain, but this chain begins at a sy

@andrewrk
andrewrk / strace_c.txt
Last active November 22, 2023 17:47
overhead of hello world in C, C++, Zig
andy@ark ~/tmp> gcc -o hello hello.c
andy@ark ~/tmp> strace ./hello
execve("./hello", ["./hello"], 0x7ffe96b5ddb0 /* 62 vars */) = 0
brk(NULL) = 0x2129000
access("/etc/ld-nix.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/tls/haswell/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/tls/haswell/x86_64", 0x7fff2bd55cc0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/tls/haswell/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/tls/haswell", 0x7fff2bd55cc0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/xg6ilb9g9zhi2zg1dpi4zcp288rhnvns-glibc-2.30/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or dire
@andrewrk
andrewrk / stage1-memory-report.txt
Created July 28, 2020 06:41
zig stage1 -fmem-report when building the self-hosted compiler
[nix-shell:~/Downloads/zig/build-memprof]$ /home/andy/Downloads/zig/build-memprof/zig build-exe /home/andy/Downloads/zig/src-self-hosted/main.zig --pkg-begin build_options /home/andy/Downloads/zig/zig-cache/zig_build_options.zig --pkg-end --cache-dir /home/andy/Downloads/zig/zig-cache --name zig --cache on -fmem-report
LLVM Emit Output...
--- MEMORY PROFILE REPORT [ArenaAllocator]: pass1 ---
ZigValue: 88 bytes each, alloc{ 11598748 calls, 12201639 objects, total 1.000 GiB }, dealloc{ 0 calls, 0 objects, total 0.000 bytes }, remain{ 11598748 calls, 12201639 objects, total 1.000 GiB }
Total bytes allocated: 1.000 GiB, deallocated: 0.000 bytes, remaining: 1.000 GiB
Total calls alloc: 11598748, dealloc: 0, remain: 11598748
/home/andy/Downloads/zig/zig-cache/o/otcooWOP9TnG_gnFACLXE_743NOny6YBSAPQTDX5Rd7qC2swx_yDtkMjVzxxqjWB
--- IR INTERNING REPORT ---
@noreturn = primitive(noreturn)
@void = primitive(void)
@usize = primitive(usize)
@0 = int(0)
@1 = int(1)
@2 = int(2)
@3 = int(3)
@syscall_array = str("syscall")
@sysoutreg_array = str("={rax}")
@andrewrk
andrewrk / benchmark_stuff.txt
Created May 13, 2020 18:21
RedisConf2020 Talk: "Writing Redis Modules in Zig" https://www.youtube.com/watch?v=Csz26Wy9Ses
test "benchmark" {
var timer = try std.time.Timer.start();
const start = timer.lap();
var i: usize = 0;
var hash: usize = 0;
while (i < 1000000) : (i += 1) {
const src = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
var output: [100]u8 = undefined;
var bf: BrainFuckInterpreter = undefined;
bf.init(src, "", &output, 500);
fn entry(start_index: usize, slice: []usize, value: usize) ?usize {
var i: usize = start_index;
while (i >= 0) : (i -= 1) {
if (slice[i] == value) {
return i;
}
}
return null;