-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Add ability to have frozen bytecode #1811
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
To test:
|
Regarding the cross compiler (upy-compiler/ in this PR): currently it needs to be rebuilt to suit a given target. This is because certain compile-time options make it produce different bytecode (eg whether bytecode has dict caching for certain opcodes). This is a bit of a pain, because you'll need separate binaries per target. I think it's worth considering making the relevant configuration options that do modify the bytecode, dynamically selectable. Then you could specify them on the command line of the cross compiler, and only need one binary for all targets. Eg something like: Also, as per @dhylands' suggestion, we'd also want to make constants (eg stm module) dynamically selectable. |
I took a look at the code and it would be quite straightforward to make the upy-cross-compiler dynamically configurable (via command line) so it could produce mpy files for all targets. |
This is now updated to use the new mpy-cross compiler. It also includes ability to freeze bytecode into the stmhal build. @peterhinch this may interest you :) Try the following (start from root dir):
Then just import your script as usual, eg "import font". I tested it with a large bytes object and indeed it stays in flash. Please let me know if/how it works for you. |
I hope I'm not doing something daft but I'm failing at the first hurdle. I cloned the source to ~/temp/micropython, cd'd to the micropython root, and did the following:
|
Thanks Damien! |
@peterhinch: Make sure to have 32-bit code generation enabled on your host machine. |
Thanks for testing @chuckbook! You must have some large scripts to fill 1mb... out of interest what is the number of lines of Python code that got to 1mb? @peterhinch it builds 32-bit by default to reduce the size of the binary. You can comment out the first line of the Makefile and try building again. It should work in 64-bit mode as well. |
@dpgeorge ~16000, however just a frozen database, after that it ran into a emit->code_info_offset assertion. |
@chuckbook a failed assertion is bad. If you can reproduce it then I can try to fix it. |
@dpgeorge I raise to 49107 lines of code. The assertion results from an 'if else chain' in a function with more than 15000 lines of python code. Most of the code is random generated. I would just drive this thing to the top. Flash is now plugged like a Christmas goose! |
Doubtless I'm doing something dumb here, but I can't get this to work. Everything appears OK but I end up with a build identical to the standard one and lacking my modules. Is there a cross-compilation step I'm missing? Here is my session, with comments and some lines omitted. It's notable that the names of my modules never appear in any of the build output listings.
|
You will need to clone the branch from the PR, not the master branch!
|
Try to use FROZEN_DIR instead of FROZEN_MPY_DIR It looks like importing frozen mpy files isn't yet supported. Both of my comments applied to the master branch. I see @dpgeorge clarified that these changes are on the PR branch. |
Sorry I'm being dumb but I'm still a n00b when it comes to git. I tried
Is that correct? I'm still getting no joy. I can explicitly compile individual modules to mpy files in my scripts directory (is this step necessary?) but the build file remains the same size. |
@peterhinch, try: |
I was going to say to do: git fetch origin pull/1811/head:new-branch-name replace new-branch-name with what you'd like. On Sat, Feb 27, 2016 at 12:27 AM, chuckbook notifications@github.com
Dave Hylands |
Just out of curiosity, I tried the git pull mentioned by @chuckbook but it wants to do a merge commit. The git fetch/checkout doesn't require any merge commit. |
As a novice, also out of curiosity, if one starts with a fresh clone, isn't the pull thing adequate? |
Right, got it, thanks.
otherwise mpy-tool.py fell over. The usual issue of defaulting to Python 2.x. |
You get the files, but the history doesn't look right because it does a merge commit. So if I do:
whereas if I do:
then I get to see the commit history exactly like I was in @dpgeorge's repository. |
@dhylands , thanks a lot for the explanation! |
@dpgeorge I'm deeply impressed by this and can see plenty of applications :-) Do you plan to extend it to handle decorators emitting native code (including asm)? |
I'm hitting an error trying to freeze a file upower.py. I can compile the file to an mpy file. The error occurs when trying to produce a firmware build - in the absence of any line number information I'm not clear what it's objecting to. The file can be found here
@dpgeorge If it's any help I could do a binary chop of the file to try to narrow down the cause, but perhaps the object number is clue enough? |
Freezing of floats is not yet supported. There are plent of directions frozen bytecode can go, for example:
The problem is time, just not enough of it :) |
There is no regex in mpy-tool... I'll have to look into it. |
Not regex per se but string encoding/substitution in general. |
When will this be merged to master? |
Soon :) There are a lot of other things pending that need to be done first. |
It's needed by frozen bytecode.
Currently it can freeze .mpy files.
The config variable MICROPY_MODULE_FROZEN is now made of two separate parts: MICROPY_MODULE_FROZEN_STR and MICROPY_MODULE_FROZEN_MPY. This allows to have none, either or both of frozen strings and frozen mpy files (aka frozen bytecode).
frozentest.py is frozen into the binary as frozen bytecode. The .mpy file is included so that there is no dependency on the cross compiler.
9167980
to
1cc81ed
Compare
@dpgeorge this does not work as a frozen bytecode: |
@chuckbook thanks, should now be fixed. |
nearly :-)
works |
@chuckbook should be fixed by 49bb04e. |
@dpgeorge thanks a lot! |
Tweak RTD to install svg2pdfconverter
This PR brings proper frozen bytecode. Bytecode is compiled using a "MicroPython cross compiler", and then frozen using tools/mpytool.py. The output file is then a .c file that's compiled into your uPy binary. Then "import frozenmod" works as expected. The resulting frozen module requires zero RAM to compile (but does require about 1 GC block to hold the function object, although that could eventually be optimised away).
The main changes in the PR are:
One thing to note is that MICROPY_MODULE_FROZEN has changed meaning, and all old uses of this macro should (and are in this PR) changed to MICROPY_MODULE_FROZEN_STR. There is now also MICROPY_MODULE_FROZEN_MPY to support both original frozen strings, and new frozen bytecode/mpy files.
Question: should upy-compiler be included? I think so. What should the dir be called? What should the executable be called (I just made it "micropython").