py/persistentcode: Introduce .mpy sub-version.

The intent is to allow us to make breaking changes to the native ABI (e.g.
changes to dynruntime.h) without needing the bytecode version to increment.

With this commit the two bits previously used for the feature flags (but
now unused as of .mpy version 6) encode a sub-version.  A bytecode-only
.mpy file can be loaded as long as MPY_VERSION matches, but a native .mpy
(i.e. one with an arch set) must also match MPY_SUB_VERSION.  This allows 3
additional updates to the native ABI per bytecode revision.

The sub-version is set to 1 because the previous commits that changed the
layout of mp_obj_type_t have changed the native ABI.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Jim Mussared
2022-09-17 23:57:12 +10:00
committed by Damien George
parent b41aaaa8a9
commit d94141e147
8 changed files with 46 additions and 27 deletions

View File

@@ -88,6 +88,7 @@ class FreezeError(Exception):
class Config:
MPY_VERSION = 6
MPY_SUB_VERSION = 1
MICROPY_LONGINT_IMPL_NONE = 0
MICROPY_LONGINT_IMPL_LONGLONG = 1
MICROPY_LONGINT_IMPL_MPZ = 2
@@ -1335,6 +1336,9 @@ def read_mpy(filename):
feature_byte = header[2]
mpy_native_arch = feature_byte >> 2
if mpy_native_arch != MP_NATIVE_ARCH_NONE:
mpy_sub_version = feature_byte & 3
if mpy_sub_version != config.MPY_SUB_VERSION:
raise MPYReadError(filename, "incompatible .mpy sub-version")
if config.native_arch == MP_NATIVE_ARCH_NONE:
config.native_arch = mpy_native_arch
elif config.native_arch != mpy_native_arch:
@@ -1658,7 +1662,9 @@ def merge_mpy(compiled_modules, output_file):
else:
main_cm_idx = None
for idx, cm in enumerate(compiled_modules):
if cm.header[2]:
feature_byte = cm.header[2]
mpy_native_arch = feature_byte >> 2
if mpy_native_arch:
# Must use qstr_table and obj_table from this raw_code
if main_cm_idx is not None:
raise Exception("can't merge files when more than one contains native code")
@@ -1670,7 +1676,7 @@ def merge_mpy(compiled_modules, output_file):
header = bytearray(4)
header[0] = ord("M")
header[1] = config.MPY_VERSION
header[2] = config.native_arch << 2
header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION
header[3] = config.mp_small_int_bits
merged_mpy.extend(header)