Browse Source

test: add pending C string FFI regression

Eric Streit 1 day ago
parent
commit
c072321925
3 changed files with 55 additions and 0 deletions
  1. 2 0
      compiler/run_tests.sh
  2. 37 0
      compiler/tests/t_cstring.mod
  3. 16 0
      runtime/syslib/shim.c

+ 2 - 0
compiler/run_tests.sh

@@ -169,6 +169,8 @@ expect_run t_chain.mod 42
 expect_run t_goto.mod 42
 expect_fail t_gotobad.mod "undeclared identifier"
 expect_run t_under.mod 42
+# Pending C string boundary: t_cstring.mod expects 42 once external
+# ARRAY OF CHAR actuals are converted to NUL-terminated char *.
 expect_run t_with.mod 114
 expect_run t_set.mod 131
 expect_run t_setchar.mod 77

+ 37 - 0
compiler/tests/t_cstring.mod

@@ -0,0 +1,37 @@
+MODULE TCString;
+(* C string boundary regression: an ARRAY OF CHAR actual must arrive at
+   a foreign C procedure as a NUL-terminated char *, not as the V3
+   descriptor address.  Expected exit code: 42.
+
+   This test is intentionally pending until the external-call boundary
+   conversion lands; it is not yet wired into run_tests.sh. *)
+PROCEDURE m2_c_strlen (s : ARRAY OF CHAR) : CARDINAL; EXTERNAL;
+PROCEDURE m2_c_fill (VAR buf : ARRAY OF CHAR;
+                     cap : CARDINAL; ch : CHAR) : CARDINAL; EXTERNAL;
+
+VAR
+  ExitCode : INTEGER;
+  fixed : ARRAY [0..7] OF CHAR;
+  out : ARRAY [0..7] OF CHAR;
+  n : CARDINAL;
+
+PROCEDURE open_len (s : ARRAY OF CHAR) : CARDINAL;
+BEGIN
+  RETURN m2_c_strlen(s)
+END open_len;
+
+BEGIN
+  fixed := "hello";
+  n := m2_c_fill(out, 8, 'x');
+  IF (m2_c_strlen("hello") = 5)
+     AND (m2_c_strlen(fixed) = 5)
+     AND (open_len("world") = 5)
+     AND (n = 7)
+     AND (out[0] = 'x')
+     AND (out[6] = 'x')
+     AND (out[7] = CHR(0)) THEN
+    ExitCode := 42
+  ELSE
+    ExitCode := 1
+  END
+END TCString.

+ 16 - 0
runtime/syslib/shim.c

@@ -364,6 +364,22 @@ long m2strlen(long *s)
     return (long)strlen((char *)(s + 1));
 }
 
+/* Test helpers for the foreign-call boundary: these expect real C
+   buffers, not V3 descriptors. */
+long m2_c_strlen(const char *s)
+{
+    return s ? (long)strlen(s) : -1;
+}
+
+long m2_c_fill(char *buf, long cap, int ch)
+{
+    long i;
+    if (!buf || cap <= 0) return -1;
+    for (i = 0; i < cap - 1; i++) buf[i] = (char)ch;
+    buf[cap - 1] = 0;
+    return cap - 1;
+}
+
 /* UString length: the codepoint count is the descriptor's header. */
 long m2ustrlen(long *s)
 {