/* * 800_ffi — verify the @symbol("X") attribute redirects CALLs at * the codegen layer. The ww source declares a body-less fn with an * external symbol name, calls it; the emitted .s must reference the * external name, not the ww-side ident. * * Also smoke-tests building lib/c/libc/libc.ww (parse + check + cgen * succeed; nothing to run). */ #include #include #include #include static char * run6c(const char *bin, const char *src) { char path[64]; snprintf(path, sizeof path, "/tmp/wwffi_%d.ww", getpid()); FILE *f = fopen(path, "wb"); fputs(src, f); fclose(f); char cmd[512]; snprintf(cmd, sizeof cmd, "%s/w6c %s 2>&1", bin, path); FILE *p = popen(cmd, "r"); size_t cap = 4096, n = 0; char *buf = malloc(cap); int c; while ((c = fgetc(p)) != EOF) { if (n + 1 >= cap) { cap *= 2; buf = realloc(buf, cap); } buf[n++] = (char)c; } buf[n] = '\0'; pclose(p); unlink(path); return buf; } int main(void) { const char *bin = getenv("BIN"); if (!bin) bin = "out/bin"; int fail = 0; /* @symbol redirects ident name to symbol name */ { char *out = run6c(bin, "@symbol(\"cout\") fn writeit(b: *u8, n: u64) i64;\n" "fn main() i32 = { writeit(nil, 0); return 0; };"); if (strstr(out, "CALL\tcout(SB)") == NULL) { fprintf(stderr, "ffi: missing CALL cout(SB) in:\n%s\n", out); fail++; } if (strstr(out, "CALL\twriteit(SB)") != NULL) { fprintf(stderr, "ffi: should not call by ident name:\n%s\n", out); fail++; } free(out); } /* lib/c/libc parses + cgens (no defined fns means no TEXT directives) */ { char path[256]; snprintf(path, sizeof path, "%s/../../lib/c/libc/libc.ww", bin); char cmd[512]; snprintf(cmd, sizeof cmd, "%s/w6c %s > /dev/null 2>&1", bin, path); int rc = system(cmd); if (rc != 0) { fprintf(stderr, "ffi: w6c failed on libc.ww (rc=%d)\n", rc); fail++; } } if (fail) return 1; puts("ffi: ok"); return 0; }