1# test importing of .mpy files with native code (x64 only) 2 3try: 4 import usys, uio, uos 5 6 uio.IOBase 7 uos.mount 8except (ImportError, AttributeError): 9 print("SKIP") 10 raise SystemExit 11 12if not (usys.platform == "linux" and usys.maxsize > 2 ** 32): 13 print("SKIP") 14 raise SystemExit 15 16 17class UserFile(uio.IOBase): 18 def __init__(self, data): 19 self.data = memoryview(data) 20 self.pos = 0 21 22 def readinto(self, buf): 23 n = min(len(buf), len(self.data) - self.pos) 24 buf[:n] = self.data[self.pos : self.pos + n] 25 self.pos += n 26 return n 27 28 def ioctl(self, req, arg): 29 return 0 30 31 32class UserFS: 33 def __init__(self, files): 34 self.files = files 35 36 def mount(self, readonly, mksfs): 37 pass 38 39 def umount(self): 40 pass 41 42 def stat(self, path): 43 if path in self.files: 44 return (32768, 0, 0, 0, 0, 0, 0, 0, 0, 0) 45 raise OSError 46 47 def open(self, path, mode): 48 return UserFile(self.files[path]) 49 50 51# these are the test .mpy files 52# fmt: off 53user_files = { 54 # bad architecture 55 '/mod0.mpy': b'M\x05\xff\x00\x10', 56 57 # test loading of viper and asm 58 '/mod1.mpy': ( 59 b'M\x05\x0b\x1f\x20' # header 60 61 b'\x20' # n bytes, bytecode 62 b'\x00\x08\x02m\x02m' # prelude 63 b'\x51' # LOAD_CONST_NONE 64 b'\x63' # RETURN_VALUE 65 66 b'\x00\x02' # n_obj, n_raw_code 67 68 b'\x22' # n bytes, viper code 69 b'\x00\x00\x00\x00\x00\x00' # dummy machine code 70 b'\x00\x00' # qstr0 71 b'\x01\x0c\x0aprint' # n_qstr, qstr0 72 b'\x00\x00\x00' # scope_flags, n_obj, n_raw_code 73 74 b'\x23' # n bytes, asm code 75 b'\x00\x00\x00\x00\x00\x00\x00\x00' # dummy machine code 76 b'\x00\x00\x00' # scope_flags, n_pos_args, type_sig 77 ), 78 79 # test loading viper with additional scope flags and relocation 80 '/mod2.mpy': ( 81 b'M\x05\x0b\x1f\x20' # header 82 83 b'\x20' # n bytes, bytecode 84 b'\x00\x08\x02m\x02m' # prelude 85 b'\x51' # LOAD_CONST_NONE 86 b'\x63' # RETURN_VALUE 87 88 b'\x00\x01' # n_obj, n_raw_code 89 90 b'\x12' # n bytes(=4), viper code 91 b'\x00\x00\x00\x00' # dummy machine code 92 b'\x00' # n_qstr 93 b'\x70' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC 94 b'\x00\x00' # n_obj, n_raw_code 95 b'\x06rodata' # rodata, 6 bytes 96 b'\x04' # bss, 4 bytes 97 b'\x03\x01\x00' # dummy relocation of rodata 98 ), 99} 100# fmt: on 101 102# create and mount a user filesystem 103uos.mount(UserFS(user_files), "/userfs") 104usys.path.append("/userfs") 105 106# import .mpy files from the user filesystem 107for i in range(len(user_files)): 108 mod = "mod%u" % i 109 try: 110 __import__(mod) 111 print(mod, "OK") 112 except ValueError as er: 113 print(mod, "ValueError", er) 114 115# unmount and undo path addition 116uos.umount("/userfs") 117usys.path.pop() 118