Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ jobs:
- os: windows
cpu: amd64
nim:
- ref: version-2-0
- ref: v2.2.4
memory_management: refc
- ref: version-2-2
- ref: v2.2.4
memory_management: orc
- ref: v2.2.10
memory_management: refc
- ref: version-2-2
- ref: v2.2.10
memory_management: orc
include:
- platform:
Expand Down
7 changes: 3 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
set -euo pipefail

# SPDX-License-Identifier: Apache-2.0 OR MIT
# Copyright (c) Status Research & Development GmbH

Expand All @@ -17,7 +19,7 @@ nimble install futhark@0.15.0

# Futhark's Opir cache key does not include the contents of the imported
# headers, so force it to rebuild when regenerating after an lsquic update.
nim c -d:opirRebuild --maxLoopIterationsVM:100000000 generate_lsquic_ffi.nim
nim c -d:nodeclguards -d:opirRebuild --maxLoopIterationsVM:100000000 generate_lsquic_ffi.nim

cat "${root}/prelude.nim" > lsquic/lsquic_ffi.nim

Expand All @@ -27,9 +29,6 @@ for file in "${toCompile[@]}"; do
echo "{.compile: \"$file\".}" >> lsquic/lsquic_ffi.nim
done

# correct casing for SockAddr
sed -i 's/Sockaddr/SockAddr/g' tmp_lsquic_ffi.nim

cat tmp_lsquic_ffi.nim >> lsquic/lsquic_ffi.nim

echo >> lsquic/lsquic_ffi.nim # linebreak
Expand Down
63 changes: 54 additions & 9 deletions generate_lsquic_ffi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,68 @@ import futhark
import std/json
from os import parentDir, `/`

import chronos/osdefs
import boringssl

const preludeTypes = ["struct_lsquic_cid", "lsquic_cid_t"]
include lsquic/lsquic_ffi_types

# These are emitted from the C headers, but supplied by the shared types file.
const manualPreludeSymbols =
["MAX_CID_LEN", "GQUIC_CID_LEN", "struct_lsquic_cid", "lsquic_cid_t"]

# Futhark would otherwise emit opaque placeholders for aliases to these types
# when declaration guards are disabled.
const predeclaredTypeNames = [
"lsquic_cid_t", "struct_ssl_st", "struct_ssl_ctx_st", "struct_ssl_session_st",
"struct_stack_st_X509",
]

# Opir nests type descriptions inside fields, parameters, and return values.
# Rewriting aliases to bases makes Futhark reuse the Nim types already in scope.
proc rewriteKnownTypeAliases(node: JsonNode, knownTypeNames: openArray[string]) =
case node.kind
of JObject:
if node{"kind"}.getStr("") == "alias":
let aliasName = node{"value"}.getStr("")
if aliasName in knownTypeNames:
node["kind"] = %"base"
return

# chronos already provides this type under Nim's SockAddr spelling.
if aliasName == "struct_sockaddr":
node["kind"] = %"base"
node["value"] = %"SockAddr"
return

for _, value in node.pairs:
rewriteKnownTypeAliases(value, knownTypeNames)
of JArray:
for value in node.items:
rewriteKnownTypeAliases(value, knownTypeNames)
else:
discard

proc normalizeOpirImpl(opirOutput: JsonNode): JsonNode =
var knownTypeNames: seq[string]
for name in predeclaredTypeNames:
knownTypeNames.add name

for node in opirOutput.items:
if node{"kind"}.getStr("") == "enum" and node.hasKey("name") and
node["name"].kind == JString:
knownTypeNames.add node{"name"}.getStr("")

proc dropPreludeTypesAndGeneratedCEnumsImpl(opirOutput: JsonNode): JsonNode =
var resp = newJArray()
for node in opirOutput:
for node in opirOutput.items:
if node{"name"}.getStr("") in manualPreludeSymbols:
continue

# enums are generated manually to avoid issue described in
# https://github.com/PMunch/futhark/issues/152
if node{"kind"}.getStr("") == "enum":
continue

# Futhark incorrectly maps the struct alignment on lsquic_cid_t to field alignment,
# so the prelude supplies the correct native layout instead.
if node{"name"}.getStr("") in preludeTypes:
continue
rewriteKnownTypeAliases(node, knownTypeNames)

resp.add node
resp
Expand All @@ -29,7 +75,6 @@ importc:
outputPath currentSourcePath.parentDir / "tmp_lsquic_ffi.nim"
path currentSourcePath.parentDir / "libs/lsquic/include"
addopircallback proc(opirOutput: JsonNode): JsonNode {.closure.} =
dropPreludeTypesAndGeneratedCEnumsImpl(opirOutput)
normalizeOpirImpl(opirOutput)
rename FILE, CFile # Rename `FILE` that STB uses to `CFile` which is the Nim equivalent
rename struct_sockaddr, SockAddr # Rename `struct_sockaddr` for chronos SockAddr
"lsquic.h"
2 changes: 1 addition & 1 deletion lsquic.nimble
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
packageName = "lsquic"
version = "0.5.1"
version = "0.5.2"
author = "Status Research & Development GmbH"
description = "Nim wrapper around the lsquic library"
license = "MIT"
Expand Down
Loading
Loading