diff options
Diffstat (limited to 'tools/mpy-tool.py')
-rwxr-xr-x | tools/mpy-tool.py | 64 |
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) |