Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot rename provided variable used by a snip (in DrRacket) #1916

Closed
LeifAndersen opened this issue Dec 20, 2017 · 4 comments
Closed

Cannot rename provided variable used by a snip (in DrRacket) #1916

LeifAndersen opened this issue Dec 20, 2017 · 4 comments

Comments

@LeifAndersen
Copy link
Member

I'm going to tag both @mflatt and @rfindler on this one as I'm not sure if its a drracket bug, or a module path resolver bug.

First, lets make a module A.rkt, that simply defines and provides some variable x:

#lang racket

(provide x)
(define x "hello")

Next, lets make a module B.rkt that defines a snip and uses dynamic-require in the snip's body:

#lang racket/gui

(require racket/runtime-path)

(define-runtime-path here ".")

(define my-snip%
  (class snip%
    (super-new)
    (define/override (copy)
      (dynamic-require (build-path here "A.rkt") 'x)
      (new my-snip%))))

(new my-snip%)

When we run module B.rkt from within DrRacket we get an empty snip as expected.

However, if we switch all instances of x to y in both A.rkt and B.rkt, giving us:

#lang racket ; A.rkt

(provide y)
(define y "hello")
#lang racket/gui ; B.rkt

(require racket/runtime-path)

(define-runtime-path here ".")

(define my-snip%
  (class snip%
    (super-new)
    (define/override (copy)
      (dynamic-require (build-path here "A.rkt") 'y)
      (new my-snip%))))

(new my-snip%)

I now get a DrRacket internal error:

dynamic-require: name is not provided
  name: 'y
  module: #<resolved-module-path:"/Users/leif/A.rkt">
  context...:
   /Users/leif/B.rkt:10:4: copy method in my-snip%
   /Users/leif/rsrc/gui/gui-lib/framework/private/text.rkt:2900:6: loop
   /Users/leif/rsrc/gui/gui-lib/framework/private/text.rkt:2893:4: do-insertion method in ...ork/private/text.rkt:2547:2
   /Users/leif/rsrc/gui/gui-lib/framework/private/text.rkt:2886:9
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:428:6
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:479:32
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:627:3

Of course, if I restart DrRacket the error now goes away, unless I go from y back to x, in which case the error comes back...until I restart DrRacket.

I feel like something is getting cached incorrectly, but I'm not sure if its in the module registry, or an internal DrRacket bug. (Or maybe I'm just doing something wrong.)

@rfindler
Copy link
Member

I think it is reasonable to consider this a bug in DrRacket in the sense that DrRacket should not call your snip's callbacks on its custodian/eventspace/thread, etc. This is a long standing bug that I do hope to get to eventually, but probably not soon. (I don't think keeping this issue open is helpful, unless there is something else to discuss in the near future.)

@LeifAndersen
Copy link
Member Author

Alright, this makes sense. And ya, I agree that no point in keeping it open in this bug tracker.

I should mention though that I am going to run into this issue a LOT in the near future. Could you point me to where DrRacket loads snips so I can take a look at it?

@rfindler
Copy link
Member

If you are interested in working on it, I'm happy to provide guidance. My first suggestion would be to start a new discussion on the drracket repo. :)

My second one is that what's needed is a new implementation of a snip that works by forwarding messages back and forth to/from a snip that is another eventspace. The high-level idea is that you ahve a snip that has methods whose code is not trusted. So there is a separate eventspace/namespace/custodian under which all calls to it must run. then you have a separate eventspace/namespace/custodian where you run only trusted code that is allowed to communicate only certain things back (anything that doesn't have a procedure in it, roughly). So when you need to render the snip, you send over the bytes that correspond to a bitmap and you build a bitmap on the trusted side. When a mouse event comes in, you forward the mouse event over (which might trigger calling various other snip methods that cause communication to come back), etc. Be aware that the untrusted side's eventspace's main thread might die at any moment, so you'll need to use kill-safe protocols to communicate. The snip protocol has a bunch of moving pieces, but I think that it can probably support this usecase.

After that is working (which can be its own separate little library), then DrRacket can just plug it in and the code example above will work properly.

@LeifAndersen
Copy link
Member Author

This makes sense. I am closing this as an issue now and work on it in a separate (smaller) project.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants