summaryrefslogtreecommitdiffstatshomepage
path: root/tools/mpy-tool.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mpy-tool.py')
-rwxr-xr-xtools/mpy-tool.py64
1 files changed, 46 insertions, 18 deletions
diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py
index 972ede8325..bc8ac4fbd3 100755
--- a/tools/mpy-tool.py
+++ b/tools/mpy-tool.py
@@ -42,6 +42,7 @@ else:
# end compatibility code
import sys
+import struct
from collections import namedtuple
sys.path.append('../py')
@@ -282,15 +283,15 @@ class RawCode:
# generate constant objects
for i, obj in enumerate(self.objs):
obj_name = 'const_obj_%s_%u' % (self.escaped_name, i)
- if is_str_type(obj):
- obj = bytes_cons(obj, 'utf8')
- print('STATIC const mp_obj_str_t %s = '
- '{{&mp_type_str}, 0, %u, (const byte*)"%s"};'
- % (obj_name, len(obj), ''.join(('\\x%02x' % b) for b in obj)))
- elif is_bytes_type(obj):
- print('STATIC const mp_obj_str_t %s = '
- '{{&mp_type_bytes}, 0, %u, (const byte*)"%s"};'
- % (obj_name, len(obj), ''.join(('\\x%02x' % b) for b in obj)))
+ if is_str_type(obj) or is_bytes_type(obj):
+ if is_str_type(obj):
+ obj = bytes_cons(obj, 'utf8')
+ obj_type = 'mp_type_str'
+ else:
+ obj_type = 'mp_type_bytes'
+ print('STATIC const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};'
+ % (obj_name, obj_type, qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH),
+ len(obj), ''.join(('\\x%02x' % b) for b in obj)))
elif is_int_type(obj):
if config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE:
# TODO check if we can actually fit this long-int into a small-int
@@ -315,9 +316,13 @@ class RawCode:
'{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t[]){%s}}};'
% (obj_name, neg, ndigs, ndigs, bits_per_dig, digs))
elif type(obj) is float:
- # works for REPR A and B only
+ print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B')
print('STATIC const mp_obj_float_t %s = {{&mp_type_float}, %.16g};'
% (obj_name, obj))
+ print('#endif')
+ elif type(obj) is complex:
+ print('STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, %.16g, %.16g};'
+ % (obj_name, obj.real, obj.imag))
else:
# TODO
raise FreezeError(self, 'freezing of object %r is not implemented' % (obj,))
@@ -328,7 +333,18 @@ class RawCode:
for qst in self.qstrs:
print(' (mp_uint_t)MP_OBJ_NEW_QSTR(%s),' % global_qstrs[qst].qstr_id)
for i in range(len(self.objs)):
- print(' (mp_uint_t)&const_obj_%s_%u,' % (self.escaped_name, i))
+ if type(self.objs[i]) is float:
+ print('#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B')
+ print(' (mp_uint_t)&const_obj_%s_%u,' % (self.escaped_name, i))
+ print('#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C')
+ n = struct.unpack('<I', struct.pack('<f', self.objs[i]))[0]
+ n = ((n & ~0x3) | 2) + 0x80800000
+ print(' (mp_uint_t)0x%08x,' % (n,))
+ print('#else')
+ print('#error "MICROPY_OBJ_REPR_D not supported with floats in frozen mpy files"')
+ print('#endif')
+ else:
+ print(' (mp_uint_t)&const_obj_%s_%u,' % (self.escaped_name, i))
for rc in self.raw_codes:
print(' (mp_uint_t)&raw_code_%s,' % rc.escaped_name)
print('};')
@@ -431,10 +447,7 @@ def dump_mpy(raw_codes):
for rc in raw_codes:
rc.dump()
-def freeze_mpy(qcfgs, base_qstrs, raw_codes):
- cfg_bytes_len = int(qcfgs['BYTES_IN_LEN'])
- cfg_bytes_hash = int(qcfgs['BYTES_IN_HASH'])
-
+def freeze_mpy(base_qstrs, raw_codes):
# add to qstrs
new = {}
for q in global_qstrs:
@@ -475,6 +488,15 @@ def freeze_mpy(qcfgs, base_qstrs, raw_codes):
print('#endif')
print()
+ print('#if MICROPY_PY_BUILTINS_COMPLEX')
+ print('typedef struct _mp_obj_complex_t {')
+ print(' mp_obj_base_t base;')
+ print(' mp_float_t real;')
+ print(' mp_float_t imag;')
+ print('} mp_obj_complex_t;')
+ print('#endif')
+ print()
+
print('enum {')
for i in range(len(new)):
if i == 0:
@@ -492,7 +514,8 @@ def freeze_mpy(qcfgs, base_qstrs, raw_codes):
print(' %u, // used entries' % len(new))
print(' {')
for _, _, qstr in new:
- print(' %s,' % qstrutil.make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr))
+ print(' %s,'
+ % qstrutil.make_bytes(config.MICROPY_QSTR_BYTES_IN_LEN, config.MICROPY_QSTR_BYTES_IN_HASH, qstr))
print(' },')
print('};')
@@ -536,10 +559,15 @@ def main():
}[args.mlongint_impl]
config.MPZ_DIG_SIZE = args.mmpz_dig_size
+ # set config values for qstrs, and get the existing base set of qstrs
if args.qstr_header:
qcfgs, base_qstrs = qstrutil.parse_input_headers([args.qstr_header])
+ config.MICROPY_QSTR_BYTES_IN_LEN = int(qcfgs['BYTES_IN_LEN'])
+ config.MICROPY_QSTR_BYTES_IN_HASH = int(qcfgs['BYTES_IN_HASH'])
else:
- qcfgs, base_qstrs = {'BYTES_IN_LEN':1, 'BYTES_IN_HASH':1}, {}
+ config.MICROPY_QSTR_BYTES_IN_LEN = 1
+ config.MICROPY_QSTR_BYTES_IN_HASH = 1
+ base_qstrs = {}
raw_codes = [read_mpy(file) for file in args.files]
@@ -547,7 +575,7 @@ def main():
dump_mpy(raw_codes)
elif args.freeze:
try:
- freeze_mpy(qcfgs, base_qstrs, raw_codes)
+ freeze_mpy(base_qstrs, raw_codes)
except FreezeError as er:
print(er, file=sys.stderr)
sys.exit(1)