{
  "project": "slang",
  "maintainer": {
    "name": "Dolphlabs",
    "entity": "Dolph Tech Limited",
    "url": "https://dolphlabs.com"
  },
  "packages": {
    "byteutil": {
      "name": "byteutil",
      "kind": "source",
      "items": [
        {
          "name": "find",
          "decl": "fn",
          "sig": "fn find(b: bytes, from: int, target: int) -> int",
          "doc": "Index of the first `target` byte in `b` at or after `from`, or -1 if it does not occur. `target` is a byte value, not a substring: 44 is a comma.",
          "file": "stdlib/byteutil/byteutil.sl",
          "line": 4
        },
        {
          "name": "has_prefix",
          "decl": "fn",
          "sig": "fn has_prefix(b: bytes, prefix: bytes) -> bool",
          "doc": "Does `b` begin with `prefix`? A prefix longer than `b` is false rather than an error.",
          "file": "stdlib/byteutil/byteutil.sl",
          "line": 17
        },
        {
          "name": "has_suffix",
          "decl": "fn",
          "sig": "fn has_suffix(b: bytes, suffix: bytes) -> bool",
          "doc": "Does `b` end with `suffix`? A suffix longer than `b` is false rather than an error.",
          "file": "stdlib/byteutil/byteutil.sl",
          "line": 33
        },
        {
          "name": "trim",
          "decl": "fn",
          "sig": "fn trim(b: bytes) -> bytes",
          "doc": "`b` without leading or trailing ASCII whitespace -- space, tab, CR and LF. Returns a new `bytes`; the input is unchanged.",
          "file": "stdlib/byteutil/byteutil.sl",
          "line": 54
        },
        {
          "name": "split",
          "decl": "fn",
          "sig": "fn split(b: bytes, sep: int) -> [bytes]",
          "doc": "Split `b` on every occurrence of the `sep` byte. Adjacent separators yield empty elements, so the result always has one more element than there were separators.",
          "file": "stdlib/byteutil/byteutil.sl",
          "line": 69
        }
      ]
    },
    "crypto": {
      "name": "crypto",
      "kind": "native",
      "items": [
        {
          "name": "sha256",
          "params": [
            "bytes"
          ],
          "ret": "bytes",
          "tls": false,
          "sig": "crypto.sha256(bytes) -> bytes"
        },
        {
          "name": "hmac_sha256",
          "params": [
            "bytes",
            "bytes"
          ],
          "ret": "bytes",
          "tls": false,
          "sig": "crypto.hmac_sha256(bytes, bytes) -> bytes"
        },
        {
          "name": "rand",
          "params": [
            "int"
          ],
          "ret": "result[bytes,str]",
          "tls": false,
          "sig": "crypto.rand(int) -> result[bytes,str]"
        }
      ]
    },
    "fs": {
      "name": "fs",
      "kind": "native",
      "items": [
        {
          "name": "open",
          "params": [
            "str"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "fs.open(str) -> result[i32,str]"
        },
        {
          "name": "create",
          "params": [
            "str"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "fs.create(str) -> result[i32,str]"
        },
        {
          "name": "read",
          "params": [
            "int",
            "int"
          ],
          "ret": "result[bytes,str]",
          "tls": false,
          "sig": "fs.read(int, int) -> result[bytes,str]"
        },
        {
          "name": "write",
          "params": [
            "int",
            "bytes"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "fs.write(int, bytes) -> result[i32,str]"
        },
        {
          "name": "close",
          "params": [
            "int"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "fs.close(int) -> result[bool,str]"
        },
        {
          "name": "mkdir",
          "params": [
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "fs.mkdir(str) -> result[bool,str]"
        }
      ]
    },
    "http": {
      "name": "http",
      "kind": "source",
      "items": [
        {
          "name": "Request",
          "decl": "struct",
          "sig": "gc struct Request",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 3
        },
        {
          "name": "Incoming",
          "decl": "struct",
          "sig": "gc struct Incoming",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 11
        },
        {
          "name": "Response",
          "decl": "struct",
          "sig": "gc struct Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 16
        },
        {
          "name": "header",
          "decl": "fn",
          "sig": "fn header(r: Request, name: str) -> opt[str]",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 161
        },
        {
          "name": "parse",
          "decl": "fn",
          "sig": "fn parse(raw: bytes) -> result[Request, str]",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 169
        },
        {
          "name": "serialize",
          "decl": "fn",
          "sig": "fn serialize(r: Response) -> bytes",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 226
        },
        {
          "name": "wants_close",
          "decl": "fn",
          "sig": "fn wants_close(r: Request) -> bool",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 267
        },
        {
          "name": "read",
          "decl": "fn",
          "sig": "fn read(c: &mut link, buf: wire, filled: int, deadline: until) -> result[Incoming, str]",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 281
        },
        {
          "name": "write",
          "decl": "fn",
          "sig": "fn write(c: &mut link, r: Response, a: &mut arena, deadline: until) -> result[int, fault]",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 333
        },
        {
          "name": "text_response",
          "decl": "fn",
          "sig": "fn text_response(status: i32, status_text: str, content_type: str,",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 338
        },
        {
          "name": "ok_html",
          "decl": "fn",
          "sig": "fn ok_html(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 350
        },
        {
          "name": "ok_css",
          "decl": "fn",
          "sig": "fn ok_css(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 354
        },
        {
          "name": "ok_js",
          "decl": "fn",
          "sig": "fn ok_js(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 358
        },
        {
          "name": "ok_json",
          "decl": "fn",
          "sig": "fn ok_json(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 363
        },
        {
          "name": "ok_text",
          "decl": "fn",
          "sig": "fn ok_text(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 367
        },
        {
          "name": "created_json",
          "decl": "fn",
          "sig": "fn created_json(body: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 371
        },
        {
          "name": "bad_request",
          "decl": "fn",
          "sig": "fn bad_request(msg: str) -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 376
        },
        {
          "name": "not_found",
          "decl": "fn",
          "sig": "fn not_found() -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 381
        },
        {
          "name": "method_not_allowed",
          "decl": "fn",
          "sig": "fn method_not_allowed() -> Response",
          "doc": "",
          "file": "stdlib/http/http.sl",
          "line": 386
        }
      ]
    },
    "http2": {
      "name": "http2",
      "kind": "source",
      "items": [
        {
          "name": "W_RAW",
          "decl": "let",
          "sig": "let W_RAW = 0;       // pre-built frames, not flow controlled",
          "doc": "---- writer messages -------------------------------------------------  Everything the writer task needs arrives on ONE channel, tagged.  When this was written slang had no `select`, so a writer watching both \"here is a response\" and \"the peer granted more window\" on two channels could only ever block on one of them. `select` exists now and would compile -- but the single tagged stream is still the better design here, and stays. Two channels would make the ORDER between a grant and a body a race the writer has to reason about; one channel makes it the order they were sent, for free, and leaves the writer an ordinary state machine with a single blocking point.",
          "file": "stdlib/http2/conn.sl",
          "line": 64
        },
        {
          "name": "W_BODY",
          "decl": "let",
          "sig": "let W_BODY = 1;      // a response: HEADERS now, DATA as window allows",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 65
        },
        {
          "name": "W_GRANT",
          "decl": "let",
          "sig": "let W_GRANT = 2;     // peer's WINDOW_UPDATE: `n` octets to `stream`",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 66
        },
        {
          "name": "W_INITIAL",
          "decl": "let",
          "sig": "let W_INITIAL = 3;   // peer's SETTINGS_INITIAL_WINDOW_SIZE is now `n`",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 67
        },
        {
          "name": "W_MAXFRAME",
          "decl": "let",
          "sig": "let W_MAXFRAME = 4;  // peer's SETTINGS_MAX_FRAME_SIZE is now `n`",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 68
        },
        {
          "name": "WMsg",
          "decl": "struct",
          "sig": "gc struct WMsg",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 70
        },
        {
          "name": "raw_msg",
          "decl": "fn",
          "sig": "fn raw_msg(b: bytes) -> WMsg",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 78
        },
        {
          "name": "grant_msg",
          "decl": "fn",
          "sig": "fn grant_msg(stream: int, n: int) -> WMsg",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 82
        },
        {
          "name": "response_msg",
          "decl": "fn",
          "sig": "fn response_msg(stream: int, status: str, extra: [Header],",
          "doc": "Build a response. The body is handed over UNFRAMED: the writer owns the peer's window and its max frame size, so it -- not the handler -- decides how the body is cut into DATA frames and when each may go.",
          "file": "stdlib/http2/conn.sl",
          "line": 93
        },
        {
          "name": "Limits",
          "decl": "struct",
          "sig": "gc struct Limits",
          "doc": "---- deadlines -------------------------------------------------------  Four separate budgets, in nanoseconds, because they defend against four different peers and want wildly different numbers.  `idle` is the generous one on purpose: an HTTP/2 connection sitting open with no streams is completely normal -- that is the whole point of connection reuse -- so timing it out aggressively breaks correct clients. `request` is the strict one: once a client has started a request it must finish it, and dribbling DATA forever is exactly the slowloris shape.",
          "file": "stdlib/http2/conn.sl",
          "line": 123
        },
        {
          "name": "default_limits",
          "decl": "fn",
          "sig": "fn default_limits() -> Limits",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 135
        },
        {
          "name": "is_timeout",
          "decl": "fn",
          "sig": "fn is_timeout(e: str) -> bool",
          "doc": "The reserved error string net.recv_until / net.send_until return when a deadline passes. Exposed as a predicate so callers can react to a slow peer (GOAWAY with ENHANCE_YOUR_CALM) differently from a broken one, without hardcoding the text.",
          "file": "stdlib/http2/conn.sl",
          "line": 152
        },
        {
          "name": "DEFAULT_MAX_FRAME",
          "decl": "let",
          "sig": "let DEFAULT_MAX_FRAME = 16384;",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 156
        },
        {
          "name": "DEFAULT_WINDOW",
          "decl": "let",
          "sig": "let DEFAULT_WINDOW = 65535;",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 157
        },
        {
          "name": "MAX_HEADER_FIELDS",
          "decl": "let",
          "sig": "let MAX_HEADER_FIELDS = 128;",
          "doc": "Our own limits, advertised in SETTINGS and enforced on receipt.",
          "file": "stdlib/http2/conn.sl",
          "line": 159
        },
        {
          "name": "MAX_BODY",
          "decl": "let",
          "sig": "let MAX_BODY = 1048576;",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 160
        },
        {
          "name": "RESET_BURST",
          "decl": "let",
          "sig": "let RESET_BURST = 100;",
          "doc": "---- Rapid Reset (CVE-2023-44487) ------------------------------------  A peer opens a stream and immediately RST_STREAMs it. From its side the stream is closed the instant it opens, so a concurrency limit never sees it -- while the server has already done the HPACK decode and, in most designs, started the work. Repeat and the server is driven at whatever rate the attacker can write frames.  Cancelling a request IS legitimate: a browser navigating away resets its in-flight streams, and a client that gives up on a slow endpoint should. So a flat \"no resets\" rule would break correct clients. What is not legitimate is resetting nearly everything you open, forever.  Hence a burst plus a ratio: RESET_BURST cancellations are free, and after that a peer whose resets outnumber half of what it opened is ending the connection. A browser that abandons a page load trips neither; a Rapid Reset flood resets every stream it opens, so it trips both the moment the burst is spent.",
          "file": "stdlib/http2/conn.sl",
          "line": 180
        },
        {
          "name": "Conn",
          "decl": "struct",
          "sig": "gc struct Conn",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 182
        },
        {
          "name": "Req",
          "decl": "struct",
          "sig": "gc struct Req",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 196
        },
        {
          "name": "conn_new",
          "decl": "fn",
          "sig": "fn conn_new() -> Conn",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 206
        },
        {
          "name": "our_settings",
          "decl": "fn",
          "sig": "fn our_settings() -> bytes",
          "doc": "Our SETTINGS: a modest frame size, and push disabled because server push is deprecated and no current client wants it.",
          "file": "stdlib/http2/conn.sl",
          "line": 220
        },
        {
          "name": "gate",
          "decl": "fn",
          "sig": "fn gate(n: int) -> chan[bool]",
          "doc": "---- the stream gate -------------------------------------------------  The connection layer cannot cap concurrency on its own: it does not spawn the handlers, the CALLER does. (slang has function values now, so handing it a callback would compile -- but that only moves the same question inside, and the answer would still be this.) So the bound lives in a token channel the caller holds, and this is the mechanism plus the vocabulary for it.  A gate is a chan[bool] holding `n` tokens. gate_enter takes one and blocks when none are left; gate_leave puts one back. That blocking IS the backpressure -- the reader stops pulling frames while every slot is busy, which is the correct answer to \"more work than I can do\", and far better than the alternative measured before this existed: 3002 concurrent handler tasks from a peer we had told our limit was 100.  It also solves shutdown. Closing the writer channel while handlers are still in flight panics them with \"send on closed channel\", and nothing else could tell whether any were left. gate_drain waits for every token to come home, so the close is safe by construction.  The one rule: gate_leave must run on EVERY path out of a handler, including error returns. A lost token permanently shrinks the connection's capacity, and losing all of them wedges that connection (only that one -- the failure is bounded and visible, not a crash).",
          "file": "stdlib/http2/conn.sl",
          "line": 253
        },
        {
          "name": "gate_enter",
          "decl": "fn",
          "sig": "fn gate_enter(g: chan[bool])",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 267
        },
        {
          "name": "gate_leave",
          "decl": "fn",
          "sig": "fn gate_leave(g: chan[bool])",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 274
        },
        {
          "name": "gate_drain",
          "decl": "fn",
          "sig": "fn gate_drain(g: chan[bool], n: int)",
          "doc": "Wait until every handler has finished, by collecting all `n` tokens. Call before chan_close on the writer channel.",
          "file": "stdlib/http2/conn.sl",
          "line": 280
        },
        {
          "name": "Transport",
          "decl": "struct",
          "sig": "gc struct Transport",
          "doc": "---- transport -------------------------------------------------------  h2 runs over cleartext TCP (h2c, prior knowledge) or over TLS, and the two are reached through different runtime calls: net.recv_until on an fd, net.tls_recv_until on an SSL handle. Everything above this point is identical either way, so the difference is confined to one struct and two functions rather than duplicated through the whole layer.  This matters beyond tidiness: browsers speak HTTP/2 ONLY over TLS with ALPN, so a connection layer that can only do fds cannot serve a browser at all, however conformant the rest of it is.",
          "file": "stdlib/http2/conn.sl",
          "line": 302
        },
        {
          "name": "transport_fd",
          "decl": "fn",
          "sig": "fn transport_fd(fd: i32) -> Transport",
          "doc": "h2c: cleartext, prior knowledge. curl --http2-prior-knowledge, and Go's http2.Transport with AllowHTTP.",
          "file": "stdlib/http2/conn.sl",
          "line": 309
        },
        {
          "name": "transport_tls",
          "decl": "fn",
          "sig": "fn transport_tls(ssl: rawptr) -> Transport",
          "doc": "h2 over TLS. The handle comes from net.tls_accept, and the caller is responsible for having negotiated \"h2\" via ALPN first -- see alpn_is_h2 below.",
          "file": "stdlib/http2/conn.sl",
          "line": 316
        },
        {
          "name": "tr_close",
          "decl": "fn",
          "sig": "fn tr_close(t: Transport)",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 334
        },
        {
          "name": "alpn_is_h2",
          "decl": "fn",
          "sig": "fn alpn_is_h2(proto: str) -> bool",
          "doc": "RFC 7301 \u00a73.1: the peer either selected \"h2\" or it did not. A server that advertised h2 and http/1.1 must look, because a browser offered both and may well have picked http/1.1 -- feeding an HTTP/1.1 client into this layer produces \"bad connection preface\", which is true but unhelpful.",
          "file": "stdlib/http2/conn.sl",
          "line": 347
        },
        {
          "name": "Reader",
          "decl": "struct",
          "sig": "gc struct Reader",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 356
        },
        {
          "name": "reader_new",
          "decl": "fn",
          "sig": "fn reader_new() -> Reader",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 360
        },
        {
          "name": "read_frame",
          "decl": "fn",
          "sig": "fn read_frame(r: Reader, t: Transport, max_frame: int, u: until)",
          "doc": "Pull bytes until at least one complete frame is buffered, then return it and keep the remainder. Note the `&mut *c` at every site below that forwards this borrow: passing `c` directly MOVES it, so the second call would fail with \"use of moved value\". Reborrowing keeps the caller's borrow usable.  `u` bounds the WHOLE call, not each recv: a peer that sends one octet every second must still finish the frame inside the budget, which is what makes this a slowloris defence rather than a keepalive check. Pass until_never() only where blocking forever is genuinely intended.",
          "file": "stdlib/http2/conn.sl",
          "line": 374
        },
        {
          "name": "accept_preface",
          "decl": "fn",
          "sig": "fn accept_preface(r: Reader, t: Transport, wch: chan[WMsg], u: until)",
          "doc": "Verify the 24-byte client connection preface and send ours.",
          "file": "stdlib/http2/conn.sl",
          "line": 411
        },
        {
          "name": "read_request",
          "decl": "fn",
          "sig": "fn read_request(cn: Conn, r: Reader, t: Transport, wch: chan[WMsg],",
          "doc": "Read frames until one complete request has arrived.  Two clocks, switched at the first HEADERS. Before it the connection is idle and gets the generous `idle` budget, refreshed by each control frame that arrives -- a client PINGing a kept-alive connection is behaving correctly and must not be disconnected. After it the strict `request` budget applies to the request as a WHOLE and is never refreshed, so no amount of dribbled DATA or CONTINUATION can extend it.",
          "file": "stdlib/http2/conn.sl",
          "line": 583
        },
        {
          "name": "writer_task",
          "decl": "fn",
          "sig": "fn writer_task(t: Transport, wch: chan[WMsg], write_ns: int)",
          "doc": "Owns the write side, and with it the peer's send windows.  Flow control has to live here rather than in the handlers. The window is a property of the CONNECTION, shared by every concurrent stream, so no handler can decide on its own whether it may send -- and the WINDOW_UPDATE that grants credit arrives on the read side, in a different task entirely. Routing both into this one task is what lets the accounting be correct without a lock at all. slang does have a mutex now, but reaching for one here would be the worse design: it would serialise the writers without making the window arithmetic any less shared.  A blocked stream parks its BODY here, not its task: the handler hands the response over and moves on, so a peer with a tiny window costs a queue entry rather than a live task.",
          "file": "stdlib/http2/conn.sl",
          "line": 919
        },
        {
          "name": "respond",
          "decl": "fn",
          "sig": "fn respond(cn: Conn, wch: chan[WMsg], stream: int, status: str,",
          "doc": "Enqueue a response for `stream`. Every write on the connection goes through the writer task, so there is deliberately no direct-write variant: one would be able to interleave with a handler mid-frame.",
          "file": "stdlib/http2/conn.sl",
          "line": 1024
        },
        {
          "name": "send_reset",
          "decl": "fn",
          "sig": "fn send_reset(wch: chan[WMsg], stream: int, code: int)",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 1029
        },
        {
          "name": "send_goaway",
          "decl": "fn",
          "sig": "fn send_goaway(wch: chan[WMsg], last_stream: int, code: int, msg: str)",
          "doc": "",
          "file": "stdlib/http2/conn.sl",
          "line": 1033
        },
        {
          "name": "FRAME_HEADER_LEN",
          "decl": "let",
          "sig": "let FRAME_HEADER_LEN = 9;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 17
        },
        {
          "name": "T_DATA",
          "decl": "let",
          "sig": "let T_DATA = 0x0;",
          "doc": "Frame types (RFC 9113 \u00a76). PUSH_PROMISE is parsed but never sent: server push is deprecated and no major client accepts it any more.",
          "file": "stdlib/http2/frame.sl",
          "line": 21
        },
        {
          "name": "T_HEADERS",
          "decl": "let",
          "sig": "let T_HEADERS = 0x1;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 22
        },
        {
          "name": "T_PRIORITY",
          "decl": "let",
          "sig": "let T_PRIORITY = 0x2;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 23
        },
        {
          "name": "T_RST_STREAM",
          "decl": "let",
          "sig": "let T_RST_STREAM = 0x3;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 24
        },
        {
          "name": "T_SETTINGS",
          "decl": "let",
          "sig": "let T_SETTINGS = 0x4;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 25
        },
        {
          "name": "T_PUSH_PROMISE",
          "decl": "let",
          "sig": "let T_PUSH_PROMISE = 0x5;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 26
        },
        {
          "name": "T_PING",
          "decl": "let",
          "sig": "let T_PING = 0x6;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 27
        },
        {
          "name": "T_GOAWAY",
          "decl": "let",
          "sig": "let T_GOAWAY = 0x7;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 28
        },
        {
          "name": "T_WINDOW_UPDATE",
          "decl": "let",
          "sig": "let T_WINDOW_UPDATE = 0x8;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 29
        },
        {
          "name": "T_CONTINUATION",
          "decl": "let",
          "sig": "let T_CONTINUATION = 0x9;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 30
        },
        {
          "name": "FLAG_END_STREAM",
          "decl": "let",
          "sig": "let FLAG_END_STREAM = 0x1;",
          "doc": "Flags. The same bit means different things per frame type, which is why these are named by type: 0x1 is END_STREAM on DATA/HEADERS but ACK on SETTINGS/PING.",
          "file": "stdlib/http2/frame.sl",
          "line": 35
        },
        {
          "name": "FLAG_ACK",
          "decl": "let",
          "sig": "let FLAG_ACK = 0x1;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 36
        },
        {
          "name": "FLAG_END_HEADERS",
          "decl": "let",
          "sig": "let FLAG_END_HEADERS = 0x4;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 37
        },
        {
          "name": "FLAG_PADDED",
          "decl": "let",
          "sig": "let FLAG_PADDED = 0x8;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 38
        },
        {
          "name": "FLAG_PRIORITY",
          "decl": "let",
          "sig": "let FLAG_PRIORITY = 0x20;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 39
        },
        {
          "name": "E_NO_ERROR",
          "decl": "let",
          "sig": "let E_NO_ERROR = 0x0;",
          "doc": "Error codes (RFC 9113 \u00a77).",
          "file": "stdlib/http2/frame.sl",
          "line": 42
        },
        {
          "name": "E_PROTOCOL_ERROR",
          "decl": "let",
          "sig": "let E_PROTOCOL_ERROR = 0x1;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 43
        },
        {
          "name": "E_INTERNAL_ERROR",
          "decl": "let",
          "sig": "let E_INTERNAL_ERROR = 0x2;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 44
        },
        {
          "name": "E_FLOW_CONTROL_ERROR",
          "decl": "let",
          "sig": "let E_FLOW_CONTROL_ERROR = 0x3;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 45
        },
        {
          "name": "E_SETTINGS_TIMEOUT",
          "decl": "let",
          "sig": "let E_SETTINGS_TIMEOUT = 0x4;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 46
        },
        {
          "name": "E_STREAM_CLOSED",
          "decl": "let",
          "sig": "let E_STREAM_CLOSED = 0x5;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 47
        },
        {
          "name": "E_FRAME_SIZE_ERROR",
          "decl": "let",
          "sig": "let E_FRAME_SIZE_ERROR = 0x6;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 48
        },
        {
          "name": "E_REFUSED_STREAM",
          "decl": "let",
          "sig": "let E_REFUSED_STREAM = 0x7;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 49
        },
        {
          "name": "E_CANCEL",
          "decl": "let",
          "sig": "let E_CANCEL = 0x8;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 50
        },
        {
          "name": "E_COMPRESSION_ERROR",
          "decl": "let",
          "sig": "let E_COMPRESSION_ERROR = 0x9;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 51
        },
        {
          "name": "E_CONNECT_ERROR",
          "decl": "let",
          "sig": "let E_CONNECT_ERROR = 0xa;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 52
        },
        {
          "name": "E_ENHANCE_YOUR_CALM",
          "decl": "let",
          "sig": "let E_ENHANCE_YOUR_CALM = 0xb;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 53
        },
        {
          "name": "E_INADEQUATE_SECURITY",
          "decl": "let",
          "sig": "let E_INADEQUATE_SECURITY = 0xc;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 54
        },
        {
          "name": "E_HTTP_1_1_REQUIRED",
          "decl": "let",
          "sig": "let E_HTTP_1_1_REQUIRED = 0xd;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 55
        },
        {
          "name": "S_HEADER_TABLE_SIZE",
          "decl": "let",
          "sig": "let S_HEADER_TABLE_SIZE = 0x1;",
          "doc": "Settings parameters (RFC 9113 \u00a76.5.2).",
          "file": "stdlib/http2/frame.sl",
          "line": 58
        },
        {
          "name": "S_ENABLE_PUSH",
          "decl": "let",
          "sig": "let S_ENABLE_PUSH = 0x2;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 59
        },
        {
          "name": "S_MAX_CONCURRENT_STREAMS",
          "decl": "let",
          "sig": "let S_MAX_CONCURRENT_STREAMS = 0x3;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 60
        },
        {
          "name": "S_INITIAL_WINDOW_SIZE",
          "decl": "let",
          "sig": "let S_INITIAL_WINDOW_SIZE = 0x4;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 61
        },
        {
          "name": "S_MAX_FRAME_SIZE",
          "decl": "let",
          "sig": "let S_MAX_FRAME_SIZE = 0x5;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 62
        },
        {
          "name": "S_MAX_HEADER_LIST_SIZE",
          "decl": "let",
          "sig": "let S_MAX_HEADER_LIST_SIZE = 0x6;",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 63
        },
        {
          "name": "preface",
          "decl": "fn",
          "sig": "fn preface() -> bytes",
          "doc": "The connection preface a client must send first (RFC 9113 \u00a73.4).",
          "file": "stdlib/http2/frame.sl",
          "line": 66
        },
        {
          "name": "Frame",
          "decl": "struct",
          "sig": "gc struct Frame",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 70
        },
        {
          "name": "be16",
          "decl": "fn",
          "sig": "fn be16(b: bytes, off: int) -> int",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 80
        },
        {
          "name": "be24",
          "decl": "fn",
          "sig": "fn be24(b: bytes, off: int) -> int",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 84
        },
        {
          "name": "be32",
          "decl": "fn",
          "sig": "fn be32(b: bytes, off: int) -> int",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 88
        },
        {
          "name": "put16",
          "decl": "fn",
          "sig": "fn put16(v: int) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 92
        },
        {
          "name": "put24",
          "decl": "fn",
          "sig": "fn put24(v: int) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 99
        },
        {
          "name": "put32",
          "decl": "fn",
          "sig": "fn put32(v: int) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 107
        },
        {
          "name": "header_bytes",
          "decl": "fn",
          "sig": "fn header_bytes(ftype: int, flags: int, stream: int, plen: int) -> bytes",
          "doc": "Serialize a frame header. The caller appends the payload.",
          "file": "stdlib/http2/frame.sl",
          "line": 119
        },
        {
          "name": "encode",
          "decl": "fn",
          "sig": "fn encode(f: Frame) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 128
        },
        {
          "name": "peek_length",
          "decl": "fn",
          "sig": "fn peek_length(b: bytes, off: int) -> int",
          "doc": "Payload length of the frame starting at `off`, or -1 if the 9-byte header is not fully buffered yet.",
          "file": "stdlib/http2/frame.sl",
          "line": 135
        },
        {
          "name": "decode",
          "decl": "fn",
          "sig": "fn decode(b: bytes, off: int, max_frame: int) -> result[Frame, str]",
          "doc": "Decode one frame at `off`. `max_frame` is our advertised SETTINGS_MAX_FRAME_SIZE: a peer exceeding it is a connection error, and checking here keeps a bogus length from driving a huge allocation.",
          "file": "stdlib/http2/frame.sl",
          "line": 145
        },
        {
          "name": "strip_padding",
          "decl": "fn",
          "sig": "fn strip_padding(payload: bytes, flags: int) -> result[bytes, str]",
          "doc": "Strip padding from a DATA or HEADERS payload when FLAG_PADDED is set: one length octet, then the field, then that many padding octets.",
          "file": "stdlib/http2/frame.sl",
          "line": 170
        },
        {
          "name": "settings_ack",
          "decl": "fn",
          "sig": "fn settings_ack() -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 186
        },
        {
          "name": "ping_ack",
          "decl": "fn",
          "sig": "fn ping_ack(opaque: bytes) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 190
        },
        {
          "name": "rst_stream",
          "decl": "fn",
          "sig": "fn rst_stream(stream: int, code: int) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 194
        },
        {
          "name": "goaway",
          "decl": "fn",
          "sig": "fn goaway(last_stream: int, code: int, debug: str) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 198
        },
        {
          "name": "window_update",
          "decl": "fn",
          "sig": "fn window_update(stream: int, increment: int) -> bytes",
          "doc": "",
          "file": "stdlib/http2/frame.sl",
          "line": 203
        },
        {
          "name": "settings_frame",
          "decl": "fn",
          "sig": "fn settings_frame(ids: [int], vals: [int]) -> bytes",
          "doc": "One SETTINGS entry is a 16-bit identifier and a 32-bit value.",
          "file": "stdlib/http2/frame.sl",
          "line": 209
        },
        {
          "name": "Decoder",
          "decl": "struct",
          "sig": "gc struct Decoder",
          "doc": "",
          "file": "stdlib/http2/header_block.sl",
          "line": 8
        },
        {
          "name": "decoder_new",
          "decl": "fn",
          "sig": "fn decoder_new(cap: int) -> Decoder",
          "doc": "",
          "file": "stdlib/http2/header_block.sl",
          "line": 17
        },
        {
          "name": "decode_block",
          "decl": "fn",
          "sig": "fn decode_block(d: Decoder, b: bytes, max_headers: int)",
          "doc": "Decode one complete header block. `max_headers` caps how many fields a peer may send: without it a small compressed block can expand into an unbounded list, which is the HPACK bomb.",
          "file": "stdlib/http2/header_block.sl",
          "line": 50
        },
        {
          "name": "encode_header",
          "decl": "fn",
          "sig": "fn encode_header(name: str, value: str) -> bytes",
          "doc": "",
          "file": "stdlib/http2/header_block.sl",
          "line": 152
        },
        {
          "name": "encode_block",
          "decl": "fn",
          "sig": "fn encode_block(hs: [Header]) -> bytes",
          "doc": "",
          "file": "stdlib/http2/header_block.sl",
          "line": 167
        },
        {
          "name": "Header",
          "decl": "struct",
          "sig": "gc struct Header",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 15
        },
        {
          "name": "Table",
          "decl": "struct",
          "sig": "gc struct Table",
          "doc": "A decoder's dynamic table. Bounded by `cap` octets, where each entry costs len(name) + len(value) + 32 (RFC 7541 \u00a74.1); the constant accounts for per-entry overhead so a peer cannot exhaust memory with many tiny headers.",
          "file": "stdlib/http2/hpack.sl",
          "line": 24
        },
        {
          "name": "table_new",
          "decl": "fn",
          "sig": "fn table_new(cap: int) -> Table",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 31
        },
        {
          "name": "table_add",
          "decl": "fn",
          "sig": "fn table_add(t: Table, name: str, value: str)",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 51
        },
        {
          "name": "table_resize",
          "decl": "fn",
          "sig": "fn table_resize(t: Table, cap: int)",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 66
        },
        {
          "name": "IntRead",
          "decl": "struct",
          "sig": "gc struct IntRead",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 77
        },
        {
          "name": "read_int",
          "decl": "fn",
          "sig": "fn read_int(b: bytes, off: int, prefix_bits: int) -> result[IntRead, str]",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 82
        },
        {
          "name": "write_int",
          "decl": "fn",
          "sig": "fn write_int(v: int, prefix_bits: int, first: int) -> bytes",
          "doc": "`first` supplies the bits ABOVE the prefix (the representation tag).",
          "file": "stdlib/http2/hpack.sl",
          "line": 114
        },
        {
          "name": "StrRead",
          "decl": "struct",
          "sig": "gc struct StrRead",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 136
        },
        {
          "name": "read_string",
          "decl": "fn",
          "sig": "fn read_string(h: Huff, b: bytes, off: int) -> result[StrRead, str]",
          "doc": "",
          "file": "stdlib/http2/hpack.sl",
          "line": 141
        },
        {
          "name": "write_string",
          "decl": "fn",
          "sig": "fn write_string(s: str) -> bytes",
          "doc": "Always emitted as a raw literal, never Huffman-coded. That is fully legal (the H bit says which), costs a few bytes per response, and avoids shipping an encoder table for a saving the transport layer mostly recovers anyway.",
          "file": "stdlib/http2/hpack.sl",
          "line": 178
        },
        {
          "name": "Huff",
          "decl": "struct",
          "sig": "gc struct Huff",
          "doc": "",
          "file": "stdlib/http2/huffman.sl",
          "line": 9
        },
        {
          "name": "huff_new",
          "decl": "fn",
          "sig": "fn huff_new() -> Huff",
          "doc": "",
          "file": "stdlib/http2/huffman.sl",
          "line": 14
        },
        {
          "name": "huff_decode",
          "decl": "fn",
          "sig": "fn huff_decode(h: Huff, src: bytes) -> result[bytes, str]",
          "doc": "Decode a Huffman-coded byte string to BYTES, not str.  Returning str here would be a silent data-loss bug: symbol 0 is NUL, and to_str truncates there, so a value containing \\x00 came back empty. Header field values are byte sequences on the wire; the caller decides whether to reject NUL (read_string does) rather than having the codec quietly drop everything after it.  Padding rules (RFC 7541 \u00a75.2) are enforced rather than ignored: the tail must be fewer than 8 bits, must be all ones, and must not encode a symbol. A decoder that skips these accepts streams a conforming one rejects, which is how HPACK implementations end up disagreeing.",
          "file": "stdlib/http2/huffman.sl",
          "line": 30
        },
        {
          "name": "HUFF_MAX_BITS",
          "decl": "let",
          "sig": "let HUFF_MAX_BITS = 30;",
          "doc": "",
          "file": "stdlib/http2/huffman_table.sl",
          "line": 16
        },
        {
          "name": "HUFF_EOS",
          "decl": "let",
          "sig": "let HUFF_EOS = 256;",
          "doc": "",
          "file": "stdlib/http2/huffman_table.sl",
          "line": 17
        },
        {
          "name": "huff_counts",
          "decl": "fn",
          "sig": "fn huff_counts() -> [int]",
          "doc": "counts[l] = number of codes of length l (index 0..30; 0..4 are zero)",
          "file": "stdlib/http2/huffman_table.sl",
          "line": 20
        },
        {
          "name": "huff_symbols",
          "decl": "fn",
          "sig": "fn huff_symbols() -> [int]",
          "doc": "symbols in canonical order: all 5-bit codes, then 6-bit, and so on",
          "file": "stdlib/http2/huffman_table.sl",
          "line": 28
        },
        {
          "name": "STATIC_LEN",
          "decl": "let",
          "sig": "let STATIC_LEN = 61;",
          "doc": "",
          "file": "stdlib/http2/static_table.sl",
          "line": 47
        },
        {
          "name": "static_name",
          "decl": "fn",
          "sig": "fn static_name(idx: int) -> str",
          "doc": "",
          "file": "stdlib/http2/static_table.sl",
          "line": 49
        },
        {
          "name": "static_value",
          "decl": "fn",
          "sig": "fn static_value(idx: int) -> str",
          "doc": "",
          "file": "stdlib/http2/static_table.sl",
          "line": 57
        },
        {
          "name": "static_find",
          "decl": "fn",
          "sig": "fn static_find(name: str, value: str) -> int",
          "doc": "Index of an exact name+value match, or 0. Used by the encoder to send a one-byte indexed field for the common cases (:status 200, :method GET) instead of a literal.",
          "file": "stdlib/http2/static_table.sl",
          "line": 68
        },
        {
          "name": "static_find_name",
          "decl": "fn",
          "sig": "fn static_find_name(name: str) -> int",
          "doc": "Index of any entry with this name, or 0 -- lets the encoder reference a known name and send only the value as a literal.",
          "file": "stdlib/http2/static_table.sl",
          "line": 81
        }
      ]
    },
    "json": {
      "name": "json",
      "kind": "native",
      "items": []
    },
    "log": {
      "name": "log",
      "kind": "native",
      "items": [
        {
          "name": "debug",
          "params": [
            "str"
          ],
          "ret": null,
          "tls": false,
          "sig": "log.debug(str)"
        },
        {
          "name": "info",
          "params": [
            "str"
          ],
          "ret": null,
          "tls": false,
          "sig": "log.info(str)"
        },
        {
          "name": "warn",
          "params": [
            "str"
          ],
          "ret": null,
          "tls": false,
          "sig": "log.warn(str)"
        },
        {
          "name": "error",
          "params": [
            "str"
          ],
          "ret": null,
          "tls": false,
          "sig": "log.error(str)"
        }
      ]
    },
    "net": {
      "name": "net",
      "kind": "native",
      "items": [
        {
          "name": "listen",
          "params": [
            "int"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.listen(int) -> result[i32,str]"
        },
        {
          "name": "port",
          "params": [
            "int"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.port(int) -> result[i32,str]"
        },
        {
          "name": "accept",
          "params": [
            "int"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.accept(int) -> result[i32,str]"
        },
        {
          "name": "dial",
          "params": [
            "str",
            "int"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.dial(str, int) -> result[i32,str]"
        },
        {
          "name": "send",
          "params": [
            "int",
            "bytes"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.send(int, bytes) -> result[i32,str]"
        },
        {
          "name": "recv",
          "params": [
            "int",
            "int"
          ],
          "ret": "result[bytes,str]",
          "tls": false,
          "sig": "net.recv(int, int) -> result[bytes,str]"
        },
        {
          "name": "recv_until",
          "params": [
            "int",
            "int",
            "until"
          ],
          "ret": "result[bytes,str]",
          "tls": false,
          "sig": "net.recv_until(int, int, until) -> result[bytes,str]"
        },
        {
          "name": "send_until",
          "params": [
            "int",
            "bytes",
            "until"
          ],
          "ret": "result[i32,str]",
          "tls": false,
          "sig": "net.send_until(int, bytes, until) -> result[i32,str]"
        },
        {
          "name": "close",
          "params": [
            "int"
          ],
          "ret": null,
          "tls": false,
          "sig": "net.close(int)"
        },
        {
          "name": "nonblock",
          "params": [
            "int"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "net.nonblock(int) -> result[bool,str]"
        },
        {
          "name": "tls_server_ctx",
          "params": [
            "str",
            "str"
          ],
          "ret": "result[rawptr,str]",
          "tls": true,
          "sig": "net.tls_server_ctx(str, str) -> result[rawptr,str]"
        },
        {
          "name": "tls_client_ctx",
          "params": [
            "str"
          ],
          "ret": "result[rawptr,str]",
          "tls": true,
          "sig": "net.tls_client_ctx(str) -> result[rawptr,str]"
        },
        {
          "name": "tls_accept",
          "params": [
            "int",
            "rawptr"
          ],
          "ret": "result[rawptr,str]",
          "tls": true,
          "sig": "net.tls_accept(int, rawptr) -> result[rawptr,str]"
        },
        {
          "name": "tls_dial",
          "params": [
            "str",
            "int",
            "rawptr"
          ],
          "ret": "result[rawptr,str]",
          "tls": true,
          "sig": "net.tls_dial(str, int, rawptr) -> result[rawptr,str]"
        },
        {
          "name": "tls_send",
          "params": [
            "rawptr",
            "bytes"
          ],
          "ret": "result[i32,str]",
          "tls": true,
          "sig": "net.tls_send(rawptr, bytes) -> result[i32,str]"
        },
        {
          "name": "tls_recv",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "result[bytes,str]",
          "tls": true,
          "sig": "net.tls_recv(rawptr, int) -> result[bytes,str]"
        },
        {
          "name": "tls_recv_until",
          "params": [
            "rawptr",
            "int",
            "until"
          ],
          "ret": "result[bytes,str]",
          "tls": true,
          "sig": "net.tls_recv_until(rawptr, int, until) -> result[bytes,str]"
        },
        {
          "name": "tls_send_until",
          "params": [
            "rawptr",
            "bytes",
            "until"
          ],
          "ret": "result[i32,str]",
          "tls": true,
          "sig": "net.tls_send_until(rawptr, bytes, until) -> result[i32,str]"
        },
        {
          "name": "tls_close",
          "params": [
            "rawptr"
          ],
          "ret": null,
          "tls": true,
          "sig": "net.tls_close(rawptr)"
        },
        {
          "name": "tls_ctx_require_client",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": true,
          "sig": "net.tls_ctx_require_client(rawptr, str) -> result[bool,str]"
        },
        {
          "name": "tls_ctx_use_cert",
          "params": [
            "rawptr",
            "str",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": true,
          "sig": "net.tls_ctx_use_cert(rawptr, str, str) -> result[bool,str]"
        },
        {
          "name": "tls_ctx_add_sni",
          "params": [
            "rawptr",
            "str",
            "str",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": true,
          "sig": "net.tls_ctx_add_sni(rawptr, str, str, str) -> result[bool,str]"
        },
        {
          "name": "tls_ctx_alpn",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": true,
          "sig": "net.tls_ctx_alpn(rawptr, str) -> result[bool,str]"
        },
        {
          "name": "tls_alpn",
          "params": [
            "rawptr"
          ],
          "ret": "str",
          "tls": true,
          "sig": "net.tls_alpn(rawptr) -> str"
        }
      ]
    },
    "os": {
      "name": "os",
      "kind": "native",
      "items": [
        {
          "name": "setenv",
          "params": [
            "str",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "os.setenv(str, str) -> result[bool,str]"
        },
        {
          "name": "unsetenv",
          "params": [
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "os.unsetenv(str) -> result[bool,str]"
        },
        {
          "name": "environ",
          "params": [],
          "ret": "[str]",
          "tls": false,
          "sig": "os.environ() -> [str]"
        },
        {
          "name": "pid",
          "params": [],
          "ret": "int",
          "tls": false,
          "sig": "os.pid() -> int"
        },
        {
          "name": "hostname",
          "params": [],
          "ret": "result[str,str]",
          "tls": false,
          "sig": "os.hostname() -> result[str,str]"
        },
        {
          "name": "tmpdir",
          "params": [],
          "ret": "str",
          "tls": false,
          "sig": "os.tmpdir() -> str"
        },
        {
          "name": "exists",
          "params": [
            "str"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "os.exists(str) -> bool"
        },
        {
          "name": "is_dir",
          "params": [
            "str"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "os.is_dir(str) -> bool"
        },
        {
          "name": "is_file",
          "params": [
            "str"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "os.is_file(str) -> bool"
        },
        {
          "name": "size",
          "params": [
            "str"
          ],
          "ret": "result[int,str]",
          "tls": false,
          "sig": "os.size(str) -> result[int,str]"
        },
        {
          "name": "mtime",
          "params": [
            "str"
          ],
          "ret": "result[int,str]",
          "tls": false,
          "sig": "os.mtime(str) -> result[int,str]"
        },
        {
          "name": "read_dir",
          "params": [
            "str"
          ],
          "ret": "result[[str],str]",
          "tls": false,
          "sig": "os.read_dir(str) -> result[[str],str]"
        },
        {
          "name": "remove",
          "params": [
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "os.remove(str) -> result[bool,str]"
        },
        {
          "name": "rename",
          "params": [
            "str",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "os.rename(str, str) -> result[bool,str]"
        }
      ]
    },
    "proc": {
      "name": "proc",
      "kind": "native",
      "items": [
        {
          "name": "shutdown_requested",
          "params": [],
          "ret": "bool",
          "tls": false,
          "sig": "proc.shutdown_requested() -> bool"
        },
        {
          "name": "active_tasks",
          "params": [],
          "ret": "int",
          "tls": false,
          "sig": "proc.active_tasks() -> int"
        },
        {
          "name": "wait_idle",
          "params": [],
          "ret": null,
          "tls": false,
          "sig": "proc.wait_idle()"
        },
        {
          "name": "getenv",
          "params": [
            "str"
          ],
          "ret": "opt[str]",
          "tls": false,
          "sig": "proc.getenv(str) -> opt[str]"
        },
        {
          "name": "args",
          "params": [],
          "ret": "[str]",
          "tls": false,
          "sig": "proc.args() -> [str]"
        },
        {
          "name": "cwd",
          "params": [],
          "ret": "result[str,str]",
          "tls": false,
          "sig": "proc.cwd() -> result[str,str]"
        }
      ]
    },
    "regex": {
      "name": "regex",
      "kind": "native",
      "items": [
        {
          "name": "compile",
          "params": [
            "str"
          ],
          "ret": "result[rawptr,str]",
          "tls": false,
          "sig": "regex.compile(str) -> result[rawptr,str]"
        },
        {
          "name": "free",
          "params": [
            "rawptr"
          ],
          "ret": null,
          "tls": false,
          "sig": "regex.free(rawptr)"
        },
        {
          "name": "groups",
          "params": [
            "rawptr"
          ],
          "ret": "int",
          "tls": false,
          "sig": "regex.groups(rawptr) -> int"
        },
        {
          "name": "is_match",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "regex.is_match(rawptr, str) -> bool"
        },
        {
          "name": "is_match_bytes",
          "params": [
            "rawptr",
            "bytes"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "regex.is_match_bytes(rawptr, bytes) -> bool"
        },
        {
          "name": "find",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "[int]",
          "tls": false,
          "sig": "regex.find(rawptr, str) -> [int]"
        },
        {
          "name": "find_at",
          "params": [
            "rawptr",
            "str",
            "int"
          ],
          "ret": "[int]",
          "tls": false,
          "sig": "regex.find_at(rawptr, str, int) -> [int]"
        },
        {
          "name": "find_bytes",
          "params": [
            "rawptr",
            "bytes"
          ],
          "ret": "[int]",
          "tls": false,
          "sig": "regex.find_bytes(rawptr, bytes) -> [int]"
        },
        {
          "name": "find_bytes_at",
          "params": [
            "rawptr",
            "bytes",
            "int"
          ],
          "ret": "[int]",
          "tls": false,
          "sig": "regex.find_bytes_at(rawptr, bytes, int) -> [int]"
        }
      ]
    },
    "sql": {
      "name": "sql",
      "kind": "native",
      "items": [
        {
          "name": "open",
          "params": [
            "str"
          ],
          "ret": "result[rawptr,str]",
          "tls": false,
          "sig": "sql.open(str) -> result[rawptr,str]"
        },
        {
          "name": "close",
          "params": [
            "rawptr"
          ],
          "ret": null,
          "tls": false,
          "sig": "sql.close(rawptr)"
        },
        {
          "name": "exec",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "result[int,str]",
          "tls": false,
          "sig": "sql.exec(rawptr, str) -> result[int,str]"
        },
        {
          "name": "last_insert_id",
          "params": [
            "rawptr"
          ],
          "ret": "int",
          "tls": false,
          "sig": "sql.last_insert_id(rawptr) -> int"
        },
        {
          "name": "prepare",
          "params": [
            "rawptr",
            "str"
          ],
          "ret": "result[rawptr,str]",
          "tls": false,
          "sig": "sql.prepare(rawptr, str) -> result[rawptr,str]"
        },
        {
          "name": "finalize",
          "params": [
            "rawptr"
          ],
          "ret": null,
          "tls": false,
          "sig": "sql.finalize(rawptr)"
        },
        {
          "name": "reset",
          "params": [
            "rawptr"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.reset(rawptr) -> result[bool,str]"
        },
        {
          "name": "bind_int",
          "params": [
            "rawptr",
            "int",
            "int"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.bind_int(rawptr, int, int) -> result[bool,str]"
        },
        {
          "name": "bind_float",
          "params": [
            "rawptr",
            "int",
            "float"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.bind_float(rawptr, int, float) -> result[bool,str]"
        },
        {
          "name": "bind_text",
          "params": [
            "rawptr",
            "int",
            "str"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.bind_text(rawptr, int, str) -> result[bool,str]"
        },
        {
          "name": "bind_blob",
          "params": [
            "rawptr",
            "int",
            "bytes"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.bind_blob(rawptr, int, bytes) -> result[bool,str]"
        },
        {
          "name": "bind_null",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.bind_null(rawptr, int) -> result[bool,str]"
        },
        {
          "name": "step",
          "params": [
            "rawptr"
          ],
          "ret": "result[bool,str]",
          "tls": false,
          "sig": "sql.step(rawptr) -> result[bool,str]"
        },
        {
          "name": "col_count",
          "params": [
            "rawptr"
          ],
          "ret": "int",
          "tls": false,
          "sig": "sql.col_count(rawptr) -> int"
        },
        {
          "name": "col_name",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "str",
          "tls": false,
          "sig": "sql.col_name(rawptr, int) -> str"
        },
        {
          "name": "col_is_null",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "bool",
          "tls": false,
          "sig": "sql.col_is_null(rawptr, int) -> bool"
        },
        {
          "name": "col_int",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "int",
          "tls": false,
          "sig": "sql.col_int(rawptr, int) -> int"
        },
        {
          "name": "col_float",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "float",
          "tls": false,
          "sig": "sql.col_float(rawptr, int) -> float"
        },
        {
          "name": "col_text",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "str",
          "tls": false,
          "sig": "sql.col_text(rawptr, int) -> str"
        },
        {
          "name": "col_blob",
          "params": [
            "rawptr",
            "int"
          ],
          "ret": "bytes",
          "tls": false,
          "sig": "sql.col_blob(rawptr, int) -> bytes"
        }
      ]
    },
    "time": {
      "name": "time",
      "kind": "native",
      "items": [
        {
          "name": "mono",
          "params": [],
          "ret": "duration",
          "tls": false,
          "sig": "time.mono() -> duration"
        },
        {
          "name": "wall",
          "params": [],
          "ret": "int",
          "tls": false,
          "sig": "time.wall() -> int"
        },
        {
          "name": "sleep",
          "params": [
            "int"
          ],
          "ret": null,
          "tls": false,
          "sig": "time.sleep(int)"
        }
      ]
    }
  }
}