Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Closed
wants to merge 1 commit into from

Conversation

Jongy
Copy link
Contributor

@Jongy Jongy commented Jan 12, 2020

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)). The kernel_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 with modname:symname, ...).

@stinos do you think this explanation (or part of it) fits anywhere in the code to justify this patch?

@Jongy Jongy mentioned this pull request Jan 12, 2020
8 tasks
@stinos
Copy link
Contributor

stinos commented Jan 13, 2020

do you think this explanation (or part of it) fits anywhere in the code to justify this patch?

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
Copy link
Contributor

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

Copy link
Contributor Author

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)

Copy link
Contributor

@stinos stinos Jan 13, 2020

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..

Copy link
Contributor Author

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
Copy link
Contributor

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

Copy link
Contributor Author

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) {
Copy link
Contributor

@stinos stinos Jan 13, 2020

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

Copy link
Contributor Author

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.
@Jongy Jongy force-pushed the micropy-lazy-load-global branch from 36316d5 to a3b787a Compare January 13, 2020 20:36
@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Aug 19, 2021
@dpgeorge
Copy link
Member

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 which has dynamic attributes. Then you'd do:

>>> k.<kernel symbol>

and it would do the dynamic lookup then (the k object would implement attr so it could do the dynamic lookup). You can add k to MICROPY_PORT_BUILTINS so it doesn't need to be imported.

@Jongy
Copy link
Contributor Author

Jongy commented Aug 20, 2021

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 which has dynamic attributes. Then you'd do:

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 k object and seeing whether it's an equivalent substitute. In any case I understand why you don't want to pull this un-Pythonic patch into mpy's master.

@Jongy
Copy link
Contributor Author

Jongy commented Aug 20, 2021

I am closing this PR, then.

@Jongy Jongy closed this Aug 20, 2021
@stinos
Copy link
Contributor

stinos commented Aug 21, 2021

@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

@Jongy
Copy link
Contributor Author

Jongy commented Aug 21, 2021

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants