guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/02: Fix race when expanding syntax-parameterize and d


From: Andy Wingo
Subject: [Guile-commits] 02/02: Fix race when expanding syntax-parameterize and define-syntax-parameter
Date: Fri, 22 Feb 2019 09:13:49 -0500 (EST)

wingo pushed a commit to branch master
in repository guile.

commit 61a8c9300daeb730fe5094f889bf13241942be84
Author: Andy Wingo <address@hidden>
Date:   Fri Feb 22 15:01:29 2019 +0100

    Fix race when expanding syntax-parameterize and define-syntax-parameter
    
    * libguile/macros.c (scm_i_make_primitive_macro): Give primitive macros
      a primitive-macro macro-type.
    * module/ice-9/psyntax.scm (put-global-definition-hook)
      (get-global-definition-hook): Inline into uses.
      (make-binding): Change format of lexically defined or rebound syntax
      parameters to just be the transformer, not a list of the transformer.
      (resolve-identifier, expand-install-global, expand-body)
      (syntax-parameterize): Adapt to use the variable object (box) holding
      the top-level syntax parameter as the "key" for lookups into the
      lexical environment, instead of a fresh object associated with the
      syntax transformer.
    * module/ice-9/psyntax-pp.scm: Regenerate.
    
    Fixes #27476, a horrible race when one thread is expanding a
    syntax-parameterize form including uses, and another thread is expanding
    the corresponding define-syntax-parameter.  See
    https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27476#102.
---
 libguile/macros.c           |   6 +-
 module/ice-9/psyntax-pp.scm | 206 ++++++++++++++++++++++----------------------
 module/ice-9/psyntax.scm    | 158 +++++++++++++++++++--------------
 3 files changed, 199 insertions(+), 171 deletions(-)

diff --git a/libguile/macros.c b/libguile/macros.c
index 70373e8..e26ed65 100644
--- a/libguile/macros.c
+++ b/libguile/macros.c
@@ -1,4 +1,4 @@
-/* Copyright 1995-1998,2000-2003,2006,2008-2012,2018
+/* Copyright 1995-1998,2000-2003,2006,2008-2012,2018-2019
      Free Software Foundation, Inc.
 
    This file is part of Guile.
@@ -64,6 +64,8 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate)
   return 1;
 }
 
+SCM_SYMBOL (sym_primitive_macro, "primitive-macro");
+
 /* Return a mmacro that is known to be one of guile's built in macros. */
 SCM
 scm_i_make_primitive_macro (const char *name, scm_t_macro_primitive fn)
@@ -71,7 +73,7 @@ scm_i_make_primitive_macro (const char *name, 
scm_t_macro_primitive fn)
   SCM z = scm_words (scm_tc16_macro, 5);
   SCM_SET_SMOB_DATA_N (z, 1, (scm_t_bits)fn);
   SCM_SET_SMOB_OBJECT_N (z, 2, scm_from_utf8_symbol (name));
-  SCM_SET_SMOB_OBJECT_N (z, 3, SCM_BOOL_F);
+  SCM_SET_SMOB_OBJECT_N (z, 3, sym_primitive_macro);
   SCM_SET_SMOB_OBJECT_N (z, 4, SCM_BOOL_F);
   return z;
 }
diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm
index 532e80f..151bf8e 100644
--- a/module/ice-9/psyntax-pp.scm
+++ b/module/ice-9/psyntax-pp.scm
@@ -116,26 +116,6 @@
      (session-id
        (let ((v (module-variable (current-module) 'syntax-session-id)))
          (lambda () ((variable-ref v)))))
-     (put-global-definition-hook
-       (lambda (symbol type val)
-         (module-define!
-           (current-module)
-           symbol
-           (make-syntax-transformer symbol type val))))
-     (get-global-definition-hook
-       (lambda (symbol module)
-         (if (and (not module) (current-module))
-           (warn "module system is booted, we should have a module" symbol))
-         (and (not (equal? module '(primitive)))
-              (let ((v (module-variable
-                         (if module (resolve-module (cdr module)) 
(current-module))
-                         symbol)))
-                (and v
-                     (variable-bound? v)
-                     (let ((val (variable-ref v)))
-                       (and (macro? val)
-                            (macro-type val)
-                            (cons (macro-type val) (macro-binding val)))))))))
      (decorate-source
        (lambda (e s)
          (if (and s (supports-source-properties? e))
@@ -273,7 +253,11 @@
                (cons a (macros-only-env (cdr r)))
                (macros-only-env (cdr r)))))))
      (global-extend
-       (lambda (type sym val) (put-global-definition-hook sym type val)))
+       (lambda (type sym val)
+         (module-define!
+           (current-module)
+           sym
+           (make-syntax-transformer sym type val))))
      (nonsymbol-id?
        (lambda (x) (and (syntax? x) (symbol? (syntax-expression x)))))
      (id? (lambda (x)
@@ -432,23 +416,37 @@
      (resolve-identifier
        (lambda (id w r mod resolve-syntax-parameters?)
          (letrec*
-           ((resolve-syntax-parameters
-              (lambda (b)
-                (if (and resolve-syntax-parameters? (eq? (car b) 
'syntax-parameter))
-                  (or (assq-ref r (cdr b)) (cons 'macro (car (cdr b))))
-                  b)))
-            (resolve-global
+           ((resolve-global
               (lambda (var mod)
-                (let ((b (resolve-syntax-parameters
-                           (or (get-global-definition-hook var mod) 
'(global)))))
-                  (if (eq? (car b) 'global)
-                    (values 'global var mod)
-                    (values (car b) (cdr b) mod)))))
+                (if (and (not mod) (current-module))
+                  (warn "module system is booted, we should have a module" 
var))
+                (let ((v (and (not (equal? mod '(primitive)))
+                              (module-variable
+                                (if mod (resolve-module (cdr mod)) 
(current-module))
+                                var))))
+                  (if (and v (variable-bound? v) (macro? (variable-ref v)))
+                    (let* ((m (variable-ref v))
+                           (type (macro-type m))
+                           (trans (macro-binding m))
+                           (trans (if (pair? trans) (car trans) trans)))
+                      (if (eq? type 'syntax-parameter)
+                        (if resolve-syntax-parameters?
+                          (let ((lexical (assq-ref r v)))
+                            (values 'macro (if lexical (cdr lexical) trans) 
mod))
+                          (values type v mod))
+                        (values type trans mod)))
+                    (values 'global var mod)))))
             (resolve-lexical
               (lambda (label mod)
-                (let ((b (resolve-syntax-parameters
-                           (or (assq-ref r label) '(displaced-lexical)))))
-                  (values (car b) (cdr b) mod)))))
+                (let ((b (assq-ref r label)))
+                  (if b
+                    (let ((type (car b)) (value (cdr b)))
+                      (if (eq? type 'syntax-parameter)
+                        (if resolve-syntax-parameters?
+                          (values 'macro value mod)
+                          (values type label mod))
+                        (values type value mod)))
+                    (values 'displaced-lexical #f #f))))))
            (let ((n (id-var-name id w mod)))
              (cond ((syntax? n)
                     (if (not (eq? n id))
@@ -692,11 +690,13 @@
            (build-primcall
              #f
              'make-syntax-transformer
-             (if (eq? type 'define-syntax-parameter-form)
-               (list (build-data #f name)
-                     (build-data #f 'syntax-parameter)
-                     (build-primcall #f 'list (list e)))
-               (list (build-data #f name) (build-data #f 'macro) e))))))
+             (list (build-data #f name)
+                   (build-data
+                     #f
+                     (if (eq? type 'define-syntax-parameter-form)
+                       'syntax-parameter
+                       'macro))
+                   e)))))
      (parse-when-list
        (lambda (e when-list)
          (let ((result (strip when-list '(()))))
@@ -976,11 +976,11 @@
                          (source-wrap e w (cdr w) mod)
                          x))
                       (else (decorate-source x s))))))
-           (let* ((t-680b775fb37a463-7da transformer-environment)
-                  (t-680b775fb37a463-7db (lambda (k) (k e r w s rib mod))))
+           (let* ((t-680b775fb37a463-7b8 transformer-environment)
+                  (t-680b775fb37a463-7b9 (lambda (k) (k e r w s rib mod))))
              (with-fluid*
-               t-680b775fb37a463-7da
-               t-680b775fb37a463-7db
+               t-680b775fb37a463-7b8
+               t-680b775fb37a463-7b9
                (lambda ()
                  (rebuild-macro-output
                    (p (source-wrap e (anti-mark w) s mod))
@@ -1038,7 +1038,7 @@
                                   (extend-env
                                     (list label)
                                     (list (cons 'syntax-parameter
-                                                (list (eval-local-transformer 
(expand e trans-r w mod) mod))))
+                                                (eval-local-transformer 
(expand e trans-r w mod) mod)))
                                     (cdr r)))
                                 (parse (cdr body) (cons id ids) labels var-ids 
vars vals bindings)))
                              ((memv key '(begin-form))
@@ -1513,11 +1513,11 @@
                                           s
                                           mod
                                           get-formals
-                                          (map (lambda (tmp-680b775fb37a463-acb
-                                                        tmp-680b775fb37a463-aca
-                                                        
tmp-680b775fb37a463-ac9)
-                                                 (cons tmp-680b775fb37a463-ac9
-                                                       (cons 
tmp-680b775fb37a463-aca tmp-680b775fb37a463-acb)))
+                                          (map (lambda (tmp-680b775fb37a463-aa9
+                                                        tmp-680b775fb37a463-aa8
+                                                        
tmp-680b775fb37a463-aa7)
+                                                 (cons tmp-680b775fb37a463-aa7
+                                                       (cons 
tmp-680b775fb37a463-aa8 tmp-680b775fb37a463-aa9)))
                                                e2*
                                                e1*
                                                args*)))
@@ -1590,7 +1590,8 @@
                            (bindings
                              (let ((trans-r (macros-only-env r)))
                                (map (lambda (x)
-                                      (cons 'macro (eval-local-transformer 
(expand x trans-r w mod) mod)))
+                                      (cons 'syntax-parameter
+                                            (eval-local-transformer (expand x 
trans-r w mod) mod)))
                                     val))))
                        (expand-body
                          (cons e1 e2)
@@ -1814,11 +1815,11 @@
               (apply (lambda (args e1 e2)
                        (build-it
                          '()
-                         (map (lambda (tmp-680b775fb37a463-c98
-                                       tmp-680b775fb37a463-c97
-                                       tmp-680b775fb37a463-c96)
-                                (cons tmp-680b775fb37a463-c96
-                                      (cons tmp-680b775fb37a463-c97 
tmp-680b775fb37a463-c98)))
+                         (map (lambda (tmp-680b775fb37a463-c76
+                                       tmp-680b775fb37a463-c75
+                                       tmp-680b775fb37a463-c74)
+                                (cons tmp-680b775fb37a463-c74
+                                      (cons tmp-680b775fb37a463-c75 
tmp-680b775fb37a463-c76)))
                               e2
                               e1
                               args)))
@@ -1830,11 +1831,11 @@
                   (apply (lambda (docstring args e1 e2)
                            (build-it
                              (list (cons 'documentation (syntax->datum 
docstring)))
-                             (map (lambda (tmp-680b775fb37a463-cae
-                                           tmp-680b775fb37a463-cad
-                                           tmp-680b775fb37a463-cac)
-                                    (cons tmp-680b775fb37a463-cac
-                                          (cons tmp-680b775fb37a463-cad 
tmp-680b775fb37a463-cae)))
+                             (map (lambda (tmp-680b775fb37a463-c8c
+                                           tmp-680b775fb37a463-c8b
+                                           tmp-680b775fb37a463-c8a)
+                                    (cons tmp-680b775fb37a463-c8a
+                                          (cons tmp-680b775fb37a463-c8b 
tmp-680b775fb37a463-c8c)))
                                   e2
                                   e1
                                   args)))
@@ -1857,11 +1858,11 @@
               (apply (lambda (args e1 e2)
                        (build-it
                          '()
-                         (map (lambda (tmp-680b775fb37a463-cce
-                                       tmp-680b775fb37a463-ccd
-                                       tmp-680b775fb37a463-ccc)
-                                (cons tmp-680b775fb37a463-ccc
-                                      (cons tmp-680b775fb37a463-ccd 
tmp-680b775fb37a463-cce)))
+                         (map (lambda (tmp-680b775fb37a463-cac
+                                       tmp-680b775fb37a463-cab
+                                       tmp-680b775fb37a463-caa)
+                                (cons tmp-680b775fb37a463-caa
+                                      (cons tmp-680b775fb37a463-cab 
tmp-680b775fb37a463-cac)))
                               e2
                               e1
                               args)))
@@ -1873,11 +1874,11 @@
                   (apply (lambda (docstring args e1 e2)
                            (build-it
                              (list (cons 'documentation (syntax->datum 
docstring)))
-                             (map (lambda (tmp-680b775fb37a463-ce4
-                                           tmp-680b775fb37a463-ce3
-                                           tmp-680b775fb37a463-ce2)
-                                    (cons tmp-680b775fb37a463-ce2
-                                          (cons tmp-680b775fb37a463-ce3 
tmp-680b775fb37a463-ce4)))
+                             (map (lambda (tmp-680b775fb37a463-cc2
+                                           tmp-680b775fb37a463-cc1
+                                           tmp-680b775fb37a463-cc0)
+                                    (cons tmp-680b775fb37a463-cc0
+                                          (cons tmp-680b775fb37a463-cc1 
tmp-680b775fb37a463-cc2)))
                                   e2
                                   e1
                                   args)))
@@ -2452,8 +2453,7 @@
                      (let ((key type))
                        (cond ((memv key '(lexical)) (values 'lexical value))
                              ((memv key '(macro)) (values 'macro value))
-                             ((memv key '(syntax-parameter))
-                              (values 'syntax-parameter (car value)))
+                             ((memv key '(syntax-parameter)) (values 
'syntax-parameter value))
                              ((memv key '(syntax)) (values 'pattern-variable 
value))
                              ((memv key '(displaced-lexical)) (values 
'displaced-lexical #f))
                              ((memv key '(global))
@@ -2802,9 +2802,11 @@
                                #f
                                k
                                (list docstring)
-                               (map (lambda (tmp-680b775fb37a463-2 
tmp-680b775fb37a463-1 tmp-680b775fb37a463)
-                                      (list (cons tmp-680b775fb37a463 
tmp-680b775fb37a463-1)
-                                            tmp-680b775fb37a463-2))
+                               (map (lambda (tmp-680b775fb37a463
+                                             tmp-680b775fb37a463-112f
+                                             tmp-680b775fb37a463-112e)
+                                      (list (cons tmp-680b775fb37a463-112e 
tmp-680b775fb37a463-112f)
+                                            tmp-680b775fb37a463))
                                     template
                                     pattern
                                     keyword)))
@@ -2819,11 +2821,9 @@
                                    dots
                                    k
                                    '()
-                                   (map (lambda (tmp-680b775fb37a463-116b
-                                                 tmp-680b775fb37a463-116a
-                                                 tmp-680b775fb37a463)
-                                          (list (cons tmp-680b775fb37a463 
tmp-680b775fb37a463-116a)
-                                                tmp-680b775fb37a463-116b))
+                                   (map (lambda (tmp-680b775fb37a463-2 
tmp-680b775fb37a463-1 tmp-680b775fb37a463)
+                                          (list (cons tmp-680b775fb37a463 
tmp-680b775fb37a463-1)
+                                                tmp-680b775fb37a463-2))
                                         template
                                         pattern
                                         keyword)))
@@ -2839,9 +2839,9 @@
                                        dots
                                        k
                                        (list docstring)
-                                       (map (lambda (tmp-680b775fb37a463-118a 
tmp-680b775fb37a463-1 tmp-680b775fb37a463)
+                                       (map (lambda (tmp-680b775fb37a463-2 
tmp-680b775fb37a463-1 tmp-680b775fb37a463)
                                               (list (cons tmp-680b775fb37a463 
tmp-680b775fb37a463-1)
-                                                    tmp-680b775fb37a463-118a))
+                                                    tmp-680b775fb37a463-2))
                                             template
                                             pattern
                                             keyword)))
@@ -2989,8 +2989,8 @@
                                                (apply (lambda (p)
                                                         (if (= lev 0)
                                                           (quasilist*
-                                                            (map (lambda 
(tmp-680b775fb37a463-11f5)
-                                                                   (list 
"value" tmp-680b775fb37a463-11f5))
+                                                            (map (lambda 
(tmp-680b775fb37a463-11d3)
+                                                                   (list 
"value" tmp-680b775fb37a463-11d3))
                                                                  p)
                                                             (quasi q lev))
                                                           (quasicons
@@ -3013,8 +3013,8 @@
                                                    (apply (lambda (p)
                                                             (if (= lev 0)
                                                               (quasiappend
-                                                                (map (lambda 
(tmp-680b775fb37a463-11fa)
-                                                                       (list 
"value" tmp-680b775fb37a463-11fa))
+                                                                (map (lambda 
(tmp-680b775fb37a463-11d8)
+                                                                       (list 
"value" tmp-680b775fb37a463-11d8))
                                                                      p)
                                                                 (quasi q lev))
                                                               (quasicons
@@ -3048,7 +3048,8 @@
                                   (apply (lambda (p)
                                            (if (= lev 0)
                                              (quasilist*
-                                               (map (lambda 
(tmp-680b775fb37a463) (list "value" tmp-680b775fb37a463))
+                                               (map (lambda 
(tmp-680b775fb37a463-11ee)
+                                                      (list "value" 
tmp-680b775fb37a463-11ee))
                                                     p)
                                                (vquasi q lev))
                                              (quasicons
@@ -3067,8 +3068,8 @@
                                       (apply (lambda (p)
                                                (if (= lev 0)
                                                  (quasiappend
-                                                   (map (lambda 
(tmp-680b775fb37a463)
-                                                          (list "value" 
tmp-680b775fb37a463))
+                                                   (map (lambda 
(tmp-680b775fb37a463-11f3)
+                                                          (list "value" 
tmp-680b775fb37a463-11f3))
                                                         p)
                                                    (vquasi q lev))
                                                  (quasicons
@@ -3158,8 +3159,8 @@
                                 (let ((tmp-1 ls))
                                   (let ((tmp ($sc-dispatch tmp-1 'each-any)))
                                     (if tmp
-                                      (apply (lambda (t-680b775fb37a463-125e)
-                                               (cons "vector" 
t-680b775fb37a463-125e))
+                                      (apply (lambda (t-680b775fb37a463-123c)
+                                               (cons "vector" 
t-680b775fb37a463-123c))
                                              tmp)
                                       (syntax-violation
                                         #f
@@ -3169,8 +3170,7 @@
                        (let ((tmp-1 ($sc-dispatch tmp '(#(atom "quote") 
each-any))))
                          (if tmp-1
                            (apply (lambda (y)
-                                    (k (map (lambda (tmp-680b775fb37a463-126a)
-                                              (list "quote" 
tmp-680b775fb37a463-126a))
+                                    (k (map (lambda (tmp-680b775fb37a463) 
(list "quote" tmp-680b775fb37a463))
                                             y)))
                                   tmp-1)
                            (let ((tmp-1 ($sc-dispatch tmp '(#(atom "list") . 
each-any))))
@@ -3213,10 +3213,10 @@
                                             (let ((tmp-1 (list (emit (car x*)) 
(f (cdr x*)))))
                                               (let ((tmp ($sc-dispatch tmp-1 
'(any any))))
                                                 (if tmp
-                                                  (apply (lambda 
(t-680b775fb37a463-129c t-680b775fb37a463-129b)
+                                                  (apply (lambda 
(t-680b775fb37a463-127a t-680b775fb37a463)
                                                            (list (make-syntax 
'cons '((top)) '(hygiene guile))
-                                                                 
t-680b775fb37a463-129c
-                                                                 
t-680b775fb37a463-129b))
+                                                                 
t-680b775fb37a463-127a
+                                                                 
t-680b775fb37a463))
                                                          tmp)
                                                   (syntax-violation
                                                     #f
@@ -3229,9 +3229,9 @@
                                             (let ((tmp-1 (map emit x)))
                                               (let ((tmp ($sc-dispatch tmp-1 
'each-any)))
                                                 (if tmp
-                                                  (apply (lambda 
(t-680b775fb37a463-12a8)
+                                                  (apply (lambda 
(t-680b775fb37a463)
                                                            (cons (make-syntax 
'append '((top)) '(hygiene guile))
-                                                                 
t-680b775fb37a463-12a8))
+                                                                 
t-680b775fb37a463))
                                                          tmp)
                                                   (syntax-violation
                                                     #f
@@ -3244,9 +3244,9 @@
                                                 (let ((tmp-1 (map emit x)))
                                                   (let ((tmp ($sc-dispatch 
tmp-1 'each-any)))
                                                     (if tmp
-                                                      (apply (lambda 
(t-680b775fb37a463-12b4)
+                                                      (apply (lambda 
(t-680b775fb37a463)
                                                                (cons 
(make-syntax 'vector '((top)) '(hygiene guile))
-                                                                     
t-680b775fb37a463-12b4))
+                                                                     
t-680b775fb37a463))
                                                              tmp)
                                                       (syntax-violation
                                                         #f
@@ -3257,9 +3257,9 @@
                                          (if tmp-1
                                            (apply (lambda (x)
                                                     (let ((tmp (emit x)))
-                                                      (let 
((t-680b775fb37a463-12c0 tmp))
+                                                      (let 
((t-680b775fb37a463-129e tmp))
                                                         (list (make-syntax 
'list->vector '((top)) '(hygiene guile))
-                                                              
t-680b775fb37a463-12c0))))
+                                                              
t-680b775fb37a463-129e))))
                                                   tmp-1)
                                            (let ((tmp-1 ($sc-dispatch tmp 
'(#(atom "value") any))))
                                              (if tmp-1
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index adc6997..0cad977 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -1,6 +1,6 @@
 ;;;; -*-scheme-*-
 ;;;;
-;;;; Copyright (C) 2001, 2003, 2006, 2009, 2010-2018
+;;;; Copyright (C) 2001, 2003, 2006, 2009, 2010-2019
 ;;;;   Free Software Foundation, Inc.
 ;;;;
 ;;;; This library is free software; you can redistribute it and/or
@@ -292,29 +292,7 @@
       (define session-id
         (let ((v (module-variable (current-module) 'syntax-session-id)))
           (lambda ()
-            ((variable-ref v)))))
-
-      (define put-global-definition-hook
-        (lambda (symbol type val)
-          (module-define! (current-module)
-                          symbol
-                          (make-syntax-transformer symbol type val))))
-    
-      (define get-global-definition-hook
-        (lambda (symbol module)
-          (if (and (not module) (current-module))
-              (warn "module system is booted, we should have a module" symbol))
-          (and (not (equal? module '(primitive)))
-               (let ((v (module-variable (if module
-                                             (resolve-module (cdr module))
-                                             (current-module))
-                                         symbol)))
-                 (and v (variable-bound? v)
-                      (let ((val (variable-ref v)))
-                        (and (macro? val) (macro-type val)
-                             (cons (macro-type val)
-                                   (macro-binding val))))))))))
-
+            ((variable-ref v))))))
 
     (define (decorate-source e s)
       (if (and s (supports-source-properties? e))
@@ -492,11 +470,10 @@
     ;;   wrap : id --> label
     ;;   env : label --> <element>
 
-    ;; environments are represented in two parts: a lexical part and a global
-    ;; part.  The lexical part is a simple list of associations from labels
-    ;; to bindings.  The global part is implemented by
-    ;; {put,get}-global-definition-hook and associates symbols with
-    ;; bindings.
+    ;; environments are represented in two parts: a lexical part and a
+    ;; global part.  The lexical part is a simple list of associations
+    ;; from labels to bindings.  The global part is implemented by
+    ;; Guile's module system and associates symbols with bindings.
 
     ;; global (assumed global variable) and displaced-lexical (see below)
     ;; do not show up in any environment; instead, they are fabricated by
@@ -507,7 +484,7 @@
     ;; identifier bindings include a type and a value
 
     ;; <binding> ::= (macro . <procedure>)           macros
-    ;;               (syntax-parameter . (<procedure>)) syntax parameters
+    ;;               (syntax-parameter . <procedure>) syntax parameters
     ;;               (core . <procedure>)            core forms
     ;;               (module-ref . <procedure>)      @ or @@
     ;;               (begin)                         begin
@@ -589,7 +566,9 @@
 
     (define global-extend
       (lambda (type sym val)
-        (put-global-definition-hook sym type val)))
+        (module-define! (current-module)
+                        sym
+                        (make-syntax-transformer sym type val))))
 
 
     ;; Conceptually, identifiers are always syntax objects.  Internally,
@@ -871,27 +850,75 @@
                              results)))))))
         (scan (wrap-subst w) '())))
 
-    ;; Returns three values: binding type, binding value, the module (for
-    ;; resolving toplevel vars).
+    ;; Returns three values: binding type, binding value, and the module
+    ;; (for resolving toplevel vars).
     (define (resolve-identifier id w r mod resolve-syntax-parameters?)
-      (define (resolve-syntax-parameters b)
-        (if (and resolve-syntax-parameters?
-                 (eq? (binding-type b) 'syntax-parameter))
-            (or (assq-ref r (binding-value b))
-                (make-binding 'macro (car (binding-value b))))
-            b))
       (define (resolve-global var mod)
-        (let ((b (resolve-syntax-parameters
-                  (or (get-global-definition-hook var mod)
-                      (make-binding 'global)))))
-          (if (eq? (binding-type b) 'global)
-              (values 'global var mod)
-              (values (binding-type b) (binding-value b) mod))))
+        (when (and (not mod) (current-module))
+          (warn "module system is booted, we should have a module" var))
+        (let ((v (and (not (equal? mod '(primitive)))
+                      (module-variable (if mod
+                                           (resolve-module (cdr mod))
+                                           (current-module))
+                                       var))))
+          ;; The expander needs to know when a top-level definition from
+          ;; outside the compilation unit is a macro.
+          ;;
+          ;; Additionally if a macro is actually a syntax-parameter, we
+          ;; might need to resolve its current binding.  If the syntax
+          ;; parameter is locally bound (via syntax-parameterize), then
+          ;; its variable will be present in `r', the expand-time
+          ;; environment.  It's a kind of double lookup: first we see
+          ;; that a name is bound to a syntax parameter, then we look
+          ;; for the current binding of the syntax parameter.
+          ;;
+          ;; We use the variable (box) holding the syntax parameter
+          ;; definition as the key for the second lookup.  We use the
+          ;; variable for two reasons:
+          ;;
+          ;;   1. If the syntax parameter is redefined in parallel
+          ;;   (perhaps via a parallel module compilation), the
+          ;;   redefinition keeps the same variable.  We don't want to
+          ;;   use a "key" that could change during a redefinition.  See
+          ;;   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27476.
+          ;;
+          ;;   2. Using the variable instead of its (symname, modname)
+          ;;   pair allows for syntax parameters to be renamed or
+          ;;   aliased while preserving the syntax parameter's identity.
+          ;;
+          (if (and v (variable-bound? v) (macro? (variable-ref v)))
+              (let* ((m (variable-ref v))
+                     (type (macro-type m))
+                     (trans (macro-binding m))
+                     (trans (if (pair? trans) (car trans) trans)))
+                (if (eq? type 'syntax-parameter)
+                    (if resolve-syntax-parameters?
+                        (let ((lexical (assq-ref r v)))
+                          ;; A resolved syntax parameter is
+                          ;; indistinguishable from a macro.
+                          (values 'macro
+                                  (if lexical
+                                      (binding-value lexical)
+                                      trans)
+                                  mod))
+                        ;; Return box as value for use in second lookup.
+                        (values type v mod))
+                    (values type trans mod)))
+              (values 'global var mod))))
       (define (resolve-lexical label mod)
-        (let ((b (resolve-syntax-parameters
-                  (or (assq-ref r label)
-                      (make-binding 'displaced-lexical)))))
-          (values (binding-type b) (binding-value b) mod)))
+        (let ((b (assq-ref r label)))
+          (if b
+              (let ((type (binding-type b))
+                    (value (binding-value b)))
+                (if (eq? type 'syntax-parameter)
+                    (if resolve-syntax-parameters?
+                        (values 'macro value mod)
+                        ;; If the syntax parameter was defined within
+                        ;; this compilation unit, use its label as its
+                        ;; lookup key.
+                        (values type label mod))
+                    (values type value mod)))
+              (values 'displaced-lexical #f #f))))
       (let ((n (id-var-name id w mod)))
         (cond
          ((syntax? n)
@@ -1224,13 +1251,12 @@
          (build-primcall
           no-source
           'make-syntax-transformer
-          (if (eq? type 'define-syntax-parameter-form)
-              (list (build-data no-source name)
-                    (build-data no-source 'syntax-parameter)
-                    (build-primcall no-source 'list (list e)))
-              (list (build-data no-source name)
-                    (build-data no-source 'macro)
-                    e))))))
+          (list (build-data no-source name)
+                (build-data no-source
+                            (if (eq? type 'define-syntax-parameter-form)
+                                'syntax-parameter
+                                'macro))
+                e)))))
     
     (define parse-when-list
       (lambda (e when-list)
@@ -1620,7 +1646,7 @@
                                         (cdr r)))
                            (parse (cdr body) (cons id ids) labels var-ids vars 
vals bindings)))
                         ((define-syntax-parameter-form)
-                         ;; Same as define-syntax-form, but different format 
of the binding.
+                         ;; Same as define-syntax-form, different binding type 
though.
                          (let ((id (wrap value w mod))
                                (label (gen-label))
                                (trans-r (macros-only-env er)))
@@ -1629,9 +1655,9 @@
                                         (list label)
                                         (list (make-binding
                                                'syntax-parameter
-                                               (list (eval-local-transformer
-                                                      (expand e trans-r w mod)
-                                                      mod))))
+                                               (eval-local-transformer
+                                                (expand e trans-r w mod)
+                                                mod)))
                                         (cdr r)))
                            (parse (cdr body) (cons id ids) labels var-ids vars 
vals bindings)))
                         ((begin-form)
@@ -2032,14 +2058,14 @@
                  (let ((trans-r (macros-only-env r)))
                    (map (lambda (x)
                           (make-binding
-                           'macro
+                           'syntax-parameter
                            (eval-local-transformer (expand x trans-r w mod) 
mod)))
                         #'(val ...)))))
             (expand-body #'(e1 e2 ...)
-                      (source-wrap e w s mod)
-                      (extend-env names bindings r)
-                      w
-                      mod)))
+                         (source-wrap e w s mod)
+                         (extend-env names bindings r)
+                         w
+                         mod)))
          (_ (syntax-violation 'syntax-parameterize "bad syntax"
                               (source-wrap e w s mod))))))
 
@@ -2778,7 +2804,7 @@
                (case type
                  ((lexical) (values 'lexical value))
                  ((macro) (values 'macro value))
-                 ((syntax-parameter) (values 'syntax-parameter (car value)))
+                 ((syntax-parameter) (values 'syntax-parameter value))
                  ((syntax) (values 'pattern-variable value))
                  ((displaced-lexical) (values 'displaced-lexical #f))
                  ((global)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]