wren-lang / wren

The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.
http://wren.io
MIT License
6.9k stars 552 forks source link

Unloading modules? #791

Open GlaireDaggers opened 4 years ago

GlaireDaggers commented 4 years ago

Hello, I've recently started developing a fantasy console/computer, and it uses Wren as its scripting language. As a part of how things work, I wanted to have not just apps/games be written in Wren, but to have entire OS shell be also written in Wren as well. This led to me creating a custom local branch of Wren based on PR #776 so I could have the shell dynamically load in a script as a modules, construct an instance of that script's Program class, call its Main method, and then return control back to the shell.

This all works great. However, there's one little detail: unless I recreate the entire VM from scratch, once a script has been loaded it is effectively "baked in", preventing users from just making some changes and then re-launching their app.

My question is, is there any mechanism at my disposal for unloading modules? The idea being I would keep track of modules an app loads as it is run, then after it finishes I would unload all of those modules so that rerunning the app would produce a fresh new run w/o loading from cache. Or, alternatively, could I implement this myself in my own branch? At first glance, it seems like I could try and retrieve the Obj* representing the module from vm->modules and remove its entry from the map (which as far as I can tell should allow it to be garbage collected)? Would that work as I expect it to, have any odd side effects, etc?

ruby0x1 commented 4 years ago

The short answer is not at the moment, it's not possible to unload (or reload) a module. This is something I'm interested in as well but haven't had much time to look into properly.

I think that suggestion (removing the module from vm->modules) would be a good starting point to see what happens when you execute a second time. I'd be interested in what you find.

mhermier commented 4 years ago

There is a high chance that it will work, if it doesn't bomb on garbage collection first. But indeed it is interesting to see if does works.

ruby0x1 commented 4 years ago

Just tested a bit and seems to work, even with calling functions on instances created from within the module, after the module is unloaded.

I do assume that potentially there are lurking issues (like references that can be collected behind your back) but from some quick tests it does seem like a starting point.

GlaireDaggers commented 4 years ago

Alright. The good news is that in my particular use case I have a relative degree of certainty that I will not call into the modules after they have been unloaded, as all of the modules represent the state of a virtual running "app" that, at that point, will have exited and no longer be referenced by the shell which started it. As long as it's not a memory leak or something bad like that, I think I'll take that approach for now then. Thanks!