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
16 changes: 8 additions & 8 deletions .trinity/seals/t27b_T27bElf.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"built_by": "t27c-bootstrap@0.5.2+b6f775178",
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [
{
"spec": "specs/tri/t27b/macho.t27",
"spec_hash": "sha256:3d7b5211967649508eff9770e966bc7d8522d1f3d964e30cfc76a5ae75978af3"
"spec_hash": "sha256:a3e7c9d8e03503cb525a543331394cafeb960bf865de04c07e7fd8b669f0b32c"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:e66deaa3b63b2361dfd465ef0de9e4ed3e3855d9ecfd0dac1b03490a189c5afd",
"gen_hash_rust": "sha256:ab550136a3a1a35c651143b1882e21c56eef008fda1be223dde559b847acb2fb",
"gen_hash_verilog": "sha256:da3d78a29822441998f8d9b33f9c20dba12a348f82eb0369a703ae2b746e16ad",
"gen_hash_zig": "sha256:f85271c74ef771277a4d6d8ebabf3a9f65aeef7e3a69dd32fc5dd34ed1a954ef",
"gen_hash_c": "sha256:7878ae05462d4b1bfc264f3157b713bc6f6073c7f5c9127547182bfdd02442f9",
"gen_hash_rust": "sha256:46de8aab89b119edfff7af2b0c2f0455eaecac214aa653351c78abe0f026d0d8",
"gen_hash_verilog": "sha256:27dd30d373f655764ac8da4f9492ceb5a0d3d2c62ab46b7f2ae02462ea9c2df7",
"gen_hash_zig": "sha256:17d6f05e65579097e408bcc6fdaedf3202714673077823b809d1ade51152418b",
"module": "T27bElf",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T06:03:43Z",
"sealed_at": "2026-10-20T10:17:42Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:abf7797624a25bb1f88587731fa99562f3b95d63d24e8ffb02741cc296f064a3",
"spec_hash": "sha256:49f01457d7d4270904b222bf4e40664114b4eed84c2f99154bd18d5c223b9988",
"spec_path": "specs/tri/t27b/elf.t27",
"tests": {
"failed": 0,
Expand Down
18 changes: 9 additions & 9 deletions .trinity/seals/t27b_T27bMachO.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
{
"built_by": "t27c-bootstrap@0.5.2+b6f775178",
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:0e438925fd931e9c9a2e9dfcf9c7303951892bdefe0fed705715356c740fc1b2",
"gen_hash_rust": "sha256:e6245bb514cb63dddf0d5872c3fd5277f69e2a1f613e404cb9b0fc715413e60f",
"gen_hash_verilog": "sha256:6165c329b35cc62a4eada03aa5120fc4176a92612eec899f55c2c68a0fd4ee3e",
"gen_hash_zig": "sha256:b839a0200c430cf37ffe52a8229288aedc3716aa463d937e8c21e64ff7c8aa99",
"gen_hash_c": "sha256:687d06416991d436a2bdbd14863fdcd2074caa72681f4cdbfe5730de38a5d8db",
"gen_hash_rust": "sha256:201f73a426886b2eed375bdfccc341dfb227a0f939f069329c066c45dcbe48a4",
"gen_hash_verilog": "sha256:3e5fc2af695f31197eebc669cb8a951dbe1d795b5871782293fed906caad3d5b",
"gen_hash_zig": "sha256:7c8a6c6713a923c2436646c25f1a5290ee6a7f634436cad0c9799c2bfee7ff6e",
"module": "T27bMachO",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T06:04:05Z",
"sealed_at": "2026-10-20T10:17:33Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:3d7b5211967649508eff9770e966bc7d8522d1f3d964e30cfc76a5ae75978af3",
"spec_hash": "sha256:a3e7c9d8e03503cb525a543331394cafeb960bf865de04c07e7fd8b669f0b32c",
"spec_path": "specs/tri/t27b/macho.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 20,
"total": 20,
"passed": 22,
"total": 22,
"vacuous": 0
},
"toolchain": {
Expand Down
18 changes: 9 additions & 9 deletions .trinity/seals/t27os_T27osInstall.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
{
"built_by": "t27c-bootstrap@0.5.2+c948f4df7",
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [
{
"spec": "specs/claw/text.t27",
"spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:1f41a6bb4d9ec65c187790eb458760fb7467780b2e8651dad5941a26dabc5936",
"gen_hash_rust": "sha256:3b70f85eb46ff31a0e7b52cf82f209121d124884eabd41e7e31cd62436fe0757",
"gen_hash_verilog": "sha256:1d90aa61656131b78be2afd49581c00ed5e1ab82db2adac6686132b357eacc98",
"gen_hash_zig": "sha256:e6999d57214ce4e9e2adadbe99b8f51982bcc17f1d7bf8b776d24ddc8bf5945b",
"gen_hash_c": "sha256:1c1bee34969fa4c569e25e81c66026c793a71fee399c46dddd21aa56b8d24414",
"gen_hash_rust": "sha256:a14737ae73fbe8d08c5d01c94f8610040f5adfd945f968d239b1663082516e86",
"gen_hash_verilog": "sha256:dd251ac478123296f1622aeb5dadffa175cae75b6e408830c7c49d73587bea03",
"gen_hash_zig": "sha256:db09cea066211936fb9791c45fcef89cbf0423ee9c0d695764777ea29936eec2",
"module": "T27osInstall",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-19T14:01:03Z",
"sealed_at": "2026-10-20T10:17:48Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:7315ca7fc6c30d92907c3311015ec5511e4d76622073032f9211ffe601a172c4",
"spec_hash": "sha256:3f6012f40457db8c325f856b28563dad4a02e08455fd12ecb63794c7a51dc318",
"spec_path": "specs/t27os/install.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 16,
"total": 16,
"passed": 24,
"total": 24,
"vacuous": 0
},
"toolchain": {
Expand Down
36 changes: 36 additions & 0 deletions .trinity/seals/t27os_T27osPlistMain.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [
{
"spec": "specs/t27os/install.t27",
"spec_hash": "sha256:3f6012f40457db8c325f856b28563dad4a02e08455fd12ecb63794c7a51dc318"
},
{
"spec": "specs/t27os/pty_sys.t27",
"spec_hash": "sha256:de47b090b70077f3f6eb52a582c3e6383186f2bab5e27a61e3d276c66bcedef4"
},
{
"spec": "specs/t27os/release.t27",
"spec_hash": "sha256:5ee4dc49a78a23c65e03a90051c40545805e1d99a92b41fa08dde8fee24bcce7"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:445ec28fad7fc375b00699d02d3a06957e2af695a3a25ea72252e98ad096bfe1",
"gen_hash_rust": "sha256:f05b5c44e7b68b9037eeda9d40ef9735cba6348414b2b0685d9c688b0eba989a",
"gen_hash_verilog": "sha256:1bfa9c08ace2985e9ad73b04605f74ec3009156d079422f064dee9d109570926",
"gen_hash_zig": "sha256:cbd4b513c7a0554abcf5ddc29eeb761cb952b13da853b282b1b43eb4cc9a76d2",
"module": "T27osPlistMain",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T10:17:56Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:5257c41c568bb80177c6db8293da719e27627f8b58a68a4f7eda9380d12a05b2",
"spec_path": "specs/t27os/plist_main.t27",
"tests": {
"blocked": "does not compile: spec.zig:136:5: error: expected 2 arguments, found 1"
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
33 changes: 33 additions & 0 deletions .trinity/seals/t27os_T27osRelease.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"built_by": "t27c-bootstrap@0.5.2+24a3abcad",
"closure": [
{
"spec": "specs/claw/text.t27",
"spec_hash": "sha256:968755ec1917f766eb2cdd0ab4c0c48aef028a0e7d69e191911695e925b286ad"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:19600e42829e3c70e1546fe00fba6718102a7d833fd831fdbccb68a67167e528",
"gen_hash_rust": "sha256:2b0227b6b45e3d9932295bee744bd2633f072ce263d47360486aa3ec0689cbe9",
"gen_hash_verilog": "sha256:1674b0bc8c28ae7610d0ae9b584f941d004c066f283383302b2158e3b6abce1d",
"gen_hash_zig": "sha256:b8677674704a0caacfdb7bbeafa44282c8244064906db85020303f78e53ed343",
"module": "T27osRelease",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-20T10:17:53Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:5ee4dc49a78a23c65e03a90051c40545805e1d99a92b41fa08dde8fee24bcce7",
"spec_path": "specs/t27os/release.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 21,
"total": 21,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:8512b80da533b79289110fca4a65f3336abd7a059ca4b72ea595d5e33ff8ad10",
"zig": "0.16.0"
}
}
29 changes: 28 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,23 @@ T27B := $(filter arm64 aarch64,$(shell uname -m))
LIST := $(PREFIX)/share/t27/install.list
PAIRS := scripts/tri:bin/tri target/release/t27c:bin/t27c target/release/tri:target/release/tri target/release/t27c:target/release/t27c $(if $(T27B),target/release/t27b:bin/t27b) $(if $(filter on,$(CLAW)),$(foreach f,specs/claw/service.t27 specs/claw/text.t27 .trinity/seals/claw_ClawService.json .trinity/seals/claw_ClawText.json,$(f):share/t27/claw/$(f)))

.PHONY: help install uninstall verify seal-check seal warnings-baseline
# The app target (#11315). specs/t27os/install.t27 decides the products, the frameworks, the plist text, the
# signing and the refusals; this names the same files and flags. T27OS_BUILD is the commit count.
T27OS_OUT := target/t27os
T27OS_BUILD ?= $(shell git rev-list --count HEAD)
T27OS_T27B := $(or $(CARGO_TARGET_DIR),target)/release/t27b
T27OS_FRAMEWORKS := Foundation AppKit CoreGraphics CoreText CoreFoundation QuartzCore Security WebKit ImageIO
T27OS_MIN_MACOS := 11.0

.PHONY: help install uninstall t27os verify seal-check seal warnings-baseline

## make install build and install tri, t27c and t27b under PREFIX (/usr/local); PIN=<version> insists on that t27c
## make -n install print the plan and change nothing
## make install PREFIX=$HOME/.local install under a directory you own
## make install CLAW=on also install TRI CLAW; EARN=on, the lab node, is refused
## make uninstall remove exactly the files the install listed
## tri --version check an install, from PREFIX/bin
## make t27os build target/t27os/T27OS.app and target/t27os/t27os-pty (Apple silicon; ad hoc signed, or T27OS_SIGN_ID=<identity>)
## make help this list; advisory shortcuts: make seal-check | seal | verify | warnings-baseline
help:
@sed -n 's/^## / /p' $(MAKEFILE_LIST)
Expand All @@ -35,6 +44,24 @@ install:
uninstall:
@if [ ! -f $(LIST) ]; then echo "nothing to remove: no $(LIST)"; elif grep -qE '^/|\.\.' $(LIST); then echo "$(LIST) names a path outside PREFIX; nothing removed" >&2; exit 2; else cd $(PREFIX) && xargs rm -f < share/t27/install.list && rmdir share/t27/claw/specs/claw share/t27/claw/specs share/t27/claw/.trinity/seals share/t27/claw/.trinity share/t27/claw share/t27 target/release target 2>/dev/null; true; fi

t27os:
@test "$$(uname -s)-$$(uname -m)" = Darwin-arm64 || { echo "make t27os: Apple silicon macOS only (app_platform_ok, specs/t27os/install.t27)" >&2; exit 2; }
@case "$(T27OS_BUILD)" in ""|0*|*[!0-9]*) echo "make t27os: T27OS_BUILD must be a commit count, got '$(T27OS_BUILD)'" >&2; exit 2;; esac
cargo build --release -p t27b
@set -e; O=$(T27OS_OUT); A=$$O/T27OS.app/Contents; mkdir -p $$A/MacOS; \
$(T27OS_T27B) build specs/t27os/pty_server.t27 -o $$O/pty_server.o --macho; \
$(T27OS_T27B) build specs/t27os/glass_window.t27 -o $$O/glass_window.o --macho; \
$(T27OS_T27B) build specs/t27os/plist_main.t27 -o $$O/plist_main.o --macho; \
for f in pty_server glass_window; do n=$$(nm -u $$O/$$f.o | grep -c .); test $$n -gt 0 || { echo "make t27os: $$f.o has no undefined symbols: this t27b has no @extern (object_ok)" >&2; exit 2; }; done; \
SDK=$$(xcrun --show-sdk-path); SDKV=$$(xcrun --show-sdk-version); \
LD="ld -arch arm64 -platform_version macos $(T27OS_MIN_MACOS) $$SDKV -syslibroot $$SDK -e _main -lSystem"; \
$$LD -o $$O/t27os-pty $$O/pty_server.o; \
$$LD -o $$O/plist_main $$O/plist_main.o; \
$$LD -lobjc $(foreach f,$(T27OS_FRAMEWORKS),-framework $(f)) -o $$A/MacOS/T27OS $$O/glass_window.o; \
T27OS_BUILD=$(T27OS_BUILD) $$O/plist_main > $$A/Info.plist; plutil -lint $$A/Info.plist >/dev/null; \
ID="$${T27OS_SIGN_ID:--}"; codesign --force --sign "$$ID" $$O/T27OS.app; codesign --force --sign "$$ID" $$O/t27os-pty; \
echo "built $$O/T27OS.app and $$O/t27os-pty (build $(T27OS_BUILD), signed with $$ID)"

# Advisory umbrella: seal freshness, warnings baseline and a quick test; always exits 0.
verify:
@scripts/verify.sh
Expand Down
38 changes: 5 additions & 33 deletions cli/t27b/src/a64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,7 @@ pub fn mov_imm(sf: bool, rd: Reg, value: u64, out: &mut Vec<u32>) {
// -------------------------------------------------------------- disassembly

fn xr(sf: bool, n: u32, sp_ctx: bool) -> String {
if n == 31 {
if sp_ctx {
return if sf { "sp".into() } else { "wsp".into() };
}
return if sf { "xzr".into() } else { "wzr".into() };
}
format!("{}{}", if sf { 'x' } else { 'w' }, n)
if n == 31 { [["wzr", "xzr"], ["wsp", "sp"]][sp_ctx as usize][sf as usize].into() } else { format!("{}{}", if sf { 'x' } else { 'w' }, n) }
}

/// Disassemble one word of the subset this module encodes (for `t27b asm`).
Expand Down Expand Up @@ -95,12 +89,7 @@ pub fn disasm(w: u32, pc: usize) -> String {
let s = (w >> 29) & 1 == 1;
let imm = (w >> 10) & 0xfff;
let sh = if (w >> 22) & 1 == 1 { ", lsl #12" } else { "" };
let name = match (sub, s) {
(false, false) => "add",
(false, true) => "adds",
(true, false) => "sub",
(true, true) => "subs",
};
let name = ["add", "adds", "sub", "subs"][2 * sub as usize + s as usize];
if s && rd == 31 {
return format!("{} {}, #{}{}", if sub { "cmp" } else { "cmn" }, xr(sf, rn, true), imm, sh);
}
Expand All @@ -113,12 +102,7 @@ pub fn disasm(w: u32, pc: usize) -> String {
if w & 0x1F00_0000 == 0x0B00_0000 {
let sub = (w >> 30) & 1 == 1;
let s = (w >> 29) & 1 == 1;
let name = match (sub, s) {
(false, false) => "add",
(false, true) => "adds",
(true, false) => "sub",
(true, true) => "subs",
};
let name = ["add", "adds", "sub", "subs"][2 * sub as usize + s as usize];
if (w >> 21) & 1 == 1 {
let opt = (w >> 13) & 7;
let ext = ["uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"][opt as usize];
Expand Down Expand Up @@ -173,26 +157,14 @@ pub fn disasm(w: u32, pc: usize) -> String {
let opc = (w >> 29) & 3;
let hw = (w >> 21) & 3;
let imm = (w >> 5) & 0xffff;
let name = match opc {
0 => "movn",
2 => "movz",
3 => "movk",
_ => return format!(".word {:#010x}", w),
};
let Some(name) = [Some("movn"), None, Some("movz"), Some("movk")][opc as usize] else { return format!(".word {:#010x}", w) };
let sh = if hw != 0 { format!(", lsl #{}", hw * 16) } else { String::new() };
return format!("{} {}, #{:#x}{}", name, xr(sf, rd, false), imm, sh);
}
// data processing 2 source
if w & 0x7FE0_0000 == 0x1AC0_0000 {
let op = (w >> 10) & 63;
let name = match op {
2 => "udiv",
3 => "sdiv",
8 => "lsl",
9 => "lsr",
10 => "asr",
_ => return format!(".word {:#010x}", w),
};
let name = match op { 2 => "udiv", 3 => "sdiv", 8 => "lsl", 9 => "lsr", 10 => "asr", _ => return format!(".word {:#010x}", w) };
return format!("{} {}, {}, {}", name, xr(sf, rd, false), xr(sf, rn, false), xr(sf, rm, false));
}
// data processing 3 source
Expand Down
8 changes: 6 additions & 2 deletions cli/t27b/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ struct Gen<'a> {
pub fn compile(prog: &Program, style: TrapStyle, with_tests: bool) -> Result<Vec<FuncCode>, CodegenError> {
let mut out = Vec::with_capacity(prog.funcs.len());
for (i, f) in prog.funcs.iter().enumerate() {
if f.is_test && !with_tests {
if (f.is_test && !with_tests) || (f.name.starts_with('@') && style != TrapStyle::Jit) { // an import (#8946) has no code in an object
continue;
}
out.push(compile_func(prog, i as FuncId, style)?);
Expand Down Expand Up @@ -1617,7 +1617,11 @@ impl<'a> Gen<'a> {
for &(v, _) in vals.iter().rev() {
self.release(v);
}
self.calls.push((self.code.len(), func));
match (self.prog.funcs[func as usize].name.starts_with('@'), self.style) { // a call to an import: its `bl` is a data ref with bit 31 set, which only macho.t27 resolves (#8946)
(true, TrapStyle::Brk) => self.data_refs.push((self.code.len(), 1 << 31 | func)),
(true, TrapStyle::Elf) => self.fail(format!("call to the import `{}` outside a Mach-O object", &self.prog.funcs[func as usize].name[1..])),
_ => self.calls.push((self.code.len(), func)), // the JIT runs an import as its empty body, which traps: eval refuses the call
}
self.emit(a64::bl(0));
if out_bytes > 0 {
self.emit(a64::add_imm(true, SP, SP, out_bytes));
Expand Down
18 changes: 17 additions & 1 deletion cli/t27b/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,14 @@ fn is_char_literal(n: &Node) -> bool {
let (a, t) = flat(std::slice::from_ref(n)); sh::char_literal(&a, &t, 0)
}

/// `fn f(..) T { return @extern("sym"); }` (or `{ @extern("sym"); }` for void) imports the C symbol `sym`
/// (#8946): the fn is named `@sym`, a name t27 source cannot declare, and the object writer reads it.
fn extern_sym(n: &Node) -> Option<String> {
let [s] = n.children.as_slice() else { return None };
let c = if s.name == "@extern" { s } else { s.children.first().filter(|_| matches!(s.kind, NodeKind::ExprReturn | NodeKind::StmtExpr))? };
c.children.first().filter(|a| c.name == "@extern" && c.children.len() == 1 && a.extra_kind == "string").map(|a| format!("@{}", a.value))
}

fn parse_int(s: &str) -> Option<i128> {
Some(st::parse_int(s.as_bytes())).filter(|v| *v != st::NO_INT)
}
Expand Down Expand Up @@ -1623,6 +1631,13 @@ impl<'a> Lower<'a> {
if poisoned {
return self.poisoned_function(n);
}
if let Some(name) = extern_sym(n) { // an import: no body, a str or slice goes as its bytes' address, an aggregate as its own
let ty = |t: &LTy| reg_ty(t).unwrap_or(Ty::U64);
let vars = params.iter().zip(&n.params).map(|(t, p)| Var { name: p.0.clone(), ty: ty(t) }).collect();
if ret.as_ref().is_some_and(is_agg) { return self.reject("FnDecl(extern)", format!("`{}` returns an aggregate; an import returns a scalar (#8972)", n.name)); }
let noreturn_site = if ret.is_some() { self.site(TrapKind::NoReturn, format!("import {} run outside an object", n.name), Ty::Bool) } else { 0 };
return Ok(Func { name, nparams: params.len(), ret: ret.map(|t| ty(&t)), vars, body: Vec::new(), slots: Vec::new(), line: n.line, is_test: false, is_invariant: false, noreturn_site });
}
// Parameters first (vars 0..), then the hidden result pointer, so
// that they are exactly the first `nparams` variables.
let mut ids = Vec::new();
Expand Down Expand Up @@ -3106,13 +3121,14 @@ impl<'a> Lower<'a> {
if c.children.len() != params.len() {
return self.reject("ExprCall", format!("`{}` takes {} arguments, {} given", c.name, params.len(), c.children.len()));
}
let mut args = Vec::new();
let (mut args, ext) = (Vec::new(), self.fns.get(&c.name).is_some_and(|f| extern_sym(f).is_some()));
for (i, a) in c.children.iter().enumerate() {
let v = if self.fns.get(&c.name).and_then(|f| f.params.get(i).map(|p| unread_any(f, &p.0, &p.1))) == Some(true) {
self.any_arg(c, a, &params[i])?
} else if is_undefined(a) && !self.is_void(&params[i]) { self.undefined_arg(c, i, a, &params[i])? } else { self.arg_as(a, &params[i])? };
args.push(match v {
// By reference; the callee never writes it.
Val::M(p) if ext && matches!(params[i], LTy::Str | LTy::Slice(..)) => Expr { ty: Ty::U64, kind: ExprKind::Load { addr: Box::new(addr_of(&p)), off: 0 } }, // C gets the bytes' address (#8946)
Val::M(p) => addr_of(&p),
v => self.reg(v)?,
});
Expand Down
Loading
Loading