Fix pcre2-release! double-free + keyword arg matching

ober

75cdc6698c853c7587e72f78fc17b9e6c56fcfba

diff --git a/src/jerboa-pcre2/pcre2.ss b/src/jerboa-pcre2/pcre2.ss
index 93bbbb0..92ae060 100644
--- a/src/jerboa-pcre2/pcre2.ss
+++ b/src/jerboa-pcre2/pcre2.ss
@@ -56,12 +56,12 @@
   ;; -----------------------------------------------------------------------
 
   (define-record-type pcre-regex
-    (fields code          ; void* — pcre2_code pointer
-            match-data    ; void* — pcre2_match_data pointer
-            pattern       ; string — original pattern
-            capture-count ; integer — number of capturing groups
-            jit?          ; boolean — JIT compilation succeeded
-            name-table)   ; alist ((name . group-number) ...)
+    (fields (mutable code)        ; void* — pcre2_code pointer (zeroed after release)
+            (mutable match-data)  ; void* — pcre2_match_data pointer (zeroed after release)
+            pattern               ; string — original pattern
+            capture-count         ; integer — number of capturing groups
+            jit?                  ; boolean — JIT compilation succeeded
+            name-table)           ; alist ((name . group-number) ...)
     (nongenerative pcre-regex))
 
   (define-record-type pcre-match
@@ -189,16 +189,22 @@
            (values caseless multiline dotall extended ungreedy utf ucp literal jit)]
           [(and (pair? args) (pair? (cdr args)))
            (let ([key (car args)] [val (cadr args)])
-             (case key
-               [(caseless:)  (set! caseless  val)]
-               [(multiline:) (set! multiline val)]
-               [(dotall:)    (set! dotall    val)]
-               [(extended:)  (set! extended  val)]
-               [(ungreedy:)  (set! ungreedy  val)]
-               [(utf:)       (set! utf       val)]
-               [(ucp:)       (set! ucp       val)]
-               [(literal:)   (set! literal   val)]
-               [(jit:)       (set! jit       val)]
+             ;; Use barred identifiers so the symbol "caseless:" is unambiguous
+             ;; under both readers. Jerboa's reader treats unescaped `name:` as
+             ;; keyword shorthand, which through case-clause transpilation
+             ;; degrades to a (list 'name:) literal that never matches. Chez's
+             ;; stock reader (used by --script tests) sees `'caseless:` as a
+             ;; plain symbol — `'|caseless:|` is the same plain symbol in both.
+             (cond
+               [(eq? key '|caseless:|)  (set! caseless  val)]
+               [(eq? key '|multiline:|) (set! multiline val)]
+               [(eq? key '|dotall:|)    (set! dotall    val)]
+               [(eq? key '|extended:|)  (set! extended  val)]
+               [(eq? key '|ungreedy:|)  (set! ungreedy  val)]
+               [(eq? key '|utf:|)       (set! utf       val)]
+               [(eq? key '|ucp:|)       (set! ucp       val)]
+               [(eq? key '|literal:|)   (set! literal   val)]
+               [(eq? key '|jit:|)       (set! jit       val)]
                [else (error 'pcre2-regex "unknown keyword" key)])
              (loop (cddr args)))]
           [else (error 'pcre2-regex "invalid keyword arguments" args)]))))
@@ -520,11 +526,18 @@
     (when (pcre-regex? regex)
       ;; Remove from cache
       (set! *cache* (filter (lambda (e) (not (eq? (cdr e) regex))) *cache*))
-      ;; Release FFI resources
+      ;; Release FFI resources, then ZERO the struct fields. The regex is
+      ;; still registered in pcre2-guardian; without zeroing, the eventual
+      ;; pcre2-collect! drain after GC would re-free the same C pointers,
+      ;; causing "invalid memory reference" on the next FFI call.
       (let ([md   (pcre-regex-match-data regex)]
             [code (pcre-regex-code regex)])
-        (when (not (zero? md))   (ffi-pcre2-match-data-free md))
-        (when (not (zero? code)) (ffi-pcre2-code-free code)))))
+        (when (not (zero? md))
+          (ffi-pcre2-match-data-free md)
+          (pcre-regex-match-data-set! regex 0))
+        (when (not (zero? code))
+          (ffi-pcre2-code-free code)
+          (pcre-regex-code-set! regex 0)))))
 
   ;; -----------------------------------------------------------------------
   ;; Pregexp-compatible API