-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
py/runtime: Add MICROPY_LAZY_LOAD_GLOBAL. #5522
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
Conversation
Don't think so, since it is so specific. I mainly was interested in knowing why you were doing it this way. For the rest this is a general feature which could be quite useful for other things/ports as well. |
@@ -757,6 +757,14 @@ typedef double mp_float_t; | |||
#define MICROPY_CAN_OVERRIDE_BUILTINS (0) | |||
#endif | |||
|
|||
// Allow ports to provide a lazy load function for undefined globals | |||
// By enabling this, MicroPython will call mp_lazy_load_global() whenever an undefined | |||
// global is accessed. Ports can return a non-MP_OBJ_NULL value which will be returned instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick, no extra spaces at start of sentence before 'Ports' and 'It' below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm no big fan of 2 spaces after a period either, but I noticed it's the general convention here so I'm just following it. (e.g see the comment just next on MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, never even noticed that. Probably because it's also not applied consistently..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, it took me a while to notice, too. Been trying to follow that since. Can't say I've been strict about it.
Also, the Internet doesn't seem to like this habit: https://www.cultofpedagogy.com/two-spaces-after-period/
py/runtime.c
Outdated
@@ -184,6 +184,15 @@ mp_obj_t mp_load_global(qstr qst) { | |||
#endif | |||
elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); | |||
if (elem == NULL) { | |||
#if MICROPY_LAZY_LOAD_GLOBAL | |||
// allow port to provide this global |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure this comment adds anything useful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I guess you're right. Removed it
py/runtime.c
Outdated
#if MICROPY_LAZY_LOAD_GLOBAL | ||
// allow port to provide this global | ||
mp_obj_t obj = mp_lazy_load_global(qst); | ||
if (MP_OBJ_NULL != obj) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency use obj != MP_OBJ_NULL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
Allow ports to provide a lazy load function for undefined globals.
36316d5
to
a3b787a
Compare
Thanks for breaking this patch out and making it nice and clean. But IMO this is not a Pythonic way to do things (having a dynamic set of builtins). I think it's more Pythonic to have a module/class called, eg, >>> k.<kernel symbol> and it would do the dynamic lookup then (the |
Thanks Damien, that's a fine suggestion. I admit I find the "automatic globals" feature very handy, though, when working with the linux-kernel port. I'll consider adding this |
I am closing this PR, then. |
@Jongy you could also leave the PR open and push the new code, which also has the benefit that the discussion remains within one PR instead of getting spread out |
Such code would be tightly coupled with #5482 , I suppose. When I write it, I will see if there's anything that can remain split out, and push it here if relevant. |
Allow ports to provide a lazy load function for undefined globals.
Required for #5482 .
Continuing my explanation from the discussion in #5482 (comment):
The rationale behind kernel symbols available as Python globals is to make kernel APIs calls as seamless as possible for the Python code.
Now, why do it lazily? I admit I didn't even try preloading them all, because I don't think it'll behave properly. First of all, since the number of symbols may be huge (e.g over 200k, depending on the kernel) it may slow down the initialization. More importantly, I assume it will induce a runtime performance hit - I don't believe MicroPython's dict lookup was ever meant to handle 200k dictionary entries. I also don't think we should fix it to handle such numbers. That's why doing it lazy makes sense - only those you need are actually loaded (and for simple scripts, you won't ever reach those huge numbers)
Also, not to mention that symbols can be added in runtime via modules, so preloading them once without any dynamic component is not an option).
Next, sliding to the discussion #5482 (comment) about the global scope - as I said, I value typing speed and conciseness here, that's why symbols are available as mere globals.
In the kernel port I'll add a function
kernel_ffi.symbol(s: str) -> Symbol
. I'll also allow disabling the automatic global loads (as I explained here #5482 (comment)). Thekernel_ffi.symbol
will be available in both cases. It'll also be used for symbols which are invalid Python identifiers and can't be loaded as globals either way (LTO symbols containing.
's, module symbols which are referenced withmodname:symname
, ...).@stinos do you think this explanation (or part of it) fits anywhere in the code to justify this patch?