guile-devel
[Top][All Lists]
Advanced

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

Unsafe psyntax label generation


From: Mark H Weaver
Subject: Unsafe psyntax label generation
Date: Tue, 24 Jan 2012 09:01:16 -0500

Hi Andy,

I'm worried about this change you recently committed:

> diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
> index 1bf3c32..fd33e98 100644
> --- a/module/ice-9/psyntax.scm
> +++ b/module/ice-9/psyntax.scm
> @@ -636,7 +636,12 @@
>      ;; labels must be comparable with "eq?", have read-write invariance,
>      ;; and distinct from symbols.
>      (define gen-label
> -      (lambda () (symbol->string (gensym "i"))))
> +      (let ((i 0))
> +        (lambda ()
> +          (let ((n i))
> +            ;; FIXME: Use atomic ops.
> +            (set! i (1+ n))
> +            (number->string n 36)))))
>  
>      (define gen-labels
>        (lambda (ls)

I guess you did this as an optimization, but as your comment above
confesses, this optimization is not quite correct.  Apart from the
obvious lack of mutex on the global counter, there's another problem
having to do with your implementation of `local-eval'.

If we use your implementation of `local-eval', I think we may need
universally-unique labels here.

You decided that we didn't, because labels are always compared using
`eq?' and labels from an earlier session will never be `eq?' to labels
generated in a newer session, even if they have the same name.  So far
so good, but there's a case you didn't consider:

`local-eval' combines syntax objects from two different sessions into a
single syntax object (in the wrapper procedure), and thus there may be
label name collisions.  Now, if this combined syntax object is
serialized as a compiled procedure, these labels with the same name will
be optimized together into the same string object!

I think this can actually happen, as follows:

* Session "A" compiles procedure (foo), which uses (the-environment), to
  a .go file.

* Session "B" loads the .go file and calls (foo) to create a
  <lexical-environment>.  Then it uses `local-compile' to compile a
  local-expression that uses (the-environment) again.

Maybe there's something I'm missing here, but if the change you made
above was safe, I think the burden of proof is on you to explain why.

   Thanks,
     Mark



reply via email to

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