← index #3445PR #1811
Related · high · value 1.940
QUERY · ISSUE

freezing an .mpy with mpy-cross -s suffix = *.mpy results in frozen_mpy.c having a DOT prepended to "__lt_module_gt_"

openby adritiumopened 2017-11-17updated 2024-09-29
  1. Create empty main.py
  2. "../../mpy-cross/mpy-cross.exe" -o main.mpy -s main.**mpy** main.py
    Note the -s param suffix is .mpy, not the to-be-expected .py
  3. python "../../tools/mpy-tool.py" -f -q build\genhdr\qstrdefs.preprocessed.h main.mpy > frozen_mpy.c
    will result in a dot placed where it shouldn't be i.e. search for .__lt_module_gt_ in the below frozen_mpy.c (it's in 4 places)

I understand you'd want to have -s with .py usually and I wasn't trying to break mpy-cross. If for some reason mpy-cross -s *.mpy isn't allowed because it unnecessarily increases difficulty in mpy-tool, then mpy-cross should err out and simply not produce an .mpy

But the idea place to fix this is in mpy-tool.py.


#include "py/mpconfig.h"
#include "py/objint.h"
#include "py/objstr.h"
#include "py/emitglue.h"

#if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE != 0
#error "incompatible MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE"
#endif

#if MICROPY_LONGINT_IMPL != 2
#error "incompatible MICROPY_LONGINT_IMPL"
#endif

#if MPZ_DIG_SIZE != 16
#error "incompatible MPZ_DIG_SIZE"
#endif

#if MICROPY_PY_BUILTINS_FLOAT
typedef struct _mp_obj_float_t {
    mp_obj_base_t base;
    mp_float_t value;
} mp_obj_float_t;
#endif

#if MICROPY_PY_BUILTINS_COMPLEX
typedef struct _mp_obj_complex_t {
    mp_obj_base_t base;
    mp_float_t real;
    mp_float_t imag;
} mp_obj_complex_t;
#endif

enum {
    MP_QSTR_main_dot_mpy = MP_QSTRnumber_of,
};

extern const qstr_pool_t mp_qstr_const_pool;
const qstr_pool_t mp_qstr_frozen_const_pool = {
    (qstr_pool_t*)&mp_qstr_const_pool, // previous pool
    MP_QSTRnumber_of, // previous pool size
    1, // allocated entries
    1, // used entries
    {
        (const byte*)"\xc4\x08" "main.mpy",
    },
};

// frozen bytecode for file main.mpy, scope main._<module>
STATIC const byte bytecode_data_main.__lt_module_gt_[16] = {
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
    MP_QSTR__lt_module_gt_ & 0xff, MP_QSTR__lt_module_gt_ >> 8,
    MP_QSTR_main_dot_mpy & 0xff, MP_QSTR_main_dot_mpy >> 8,
    0x00, 0x00, 0xff,
    0x11, 
    0x5b, 
};
const mp_raw_code_t raw_code_main.__lt_module_gt_ = {
    .kind = MP_CODE_BYTECODE,
    .scope_flags = 0x00,
    .n_pos_args = 0,
    .data.u_byte = {
        .bytecode = bytecode_data_main.__lt_module_gt_,
        .const_table = NULL,
        #if MICROPY_PERSISTENT_CODE_SAVE
        .bc_len = 16,
        .n_obj = 0,
        .n_raw_code = 0,
        #endif
    },
};

const char mp_frozen_mpy_names[] = {
"main.mpy\0"
"\0"};
const mp_raw_code_t *const mp_frozen_mpy_content[] = {
    &raw_code_main.__lt_module_gt_,
};

CANDIDATE · PULL REQUEST

Add ability to have frozen bytecode

closedby dpgeorgeopened 2016-01-31updated 2016-04-15

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:

  • support in core for frozen modules (including import and adding a new qstr pool for the frozen qstrs)
  • addition of top-level dir upy-compiler/ which contains an example cross compiler (that's real-world usable, just needs editing of mpconfigport.h to suit a given target)
  • minor modifications to minimal port to include an example of frozen bytecode (.mpy file is included so you don't need the cross-compiler to build it)

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

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied