Skip to content

Commit 6b239c2

Browse files
committed
py: Factor out persistent-code reader into separate files.
Implementations of persistent-code reader are provided for POSIX systems and systems using FatFS. Macros to use these are MICROPY_READER_POSIX and MICROPY_READER_FATFS respectively. If an alternative implementation is needed then a port can define the function mp_reader_new_file.
1 parent 6810f2c commit 6b239c2

14 files changed

Lines changed: 316 additions & 121 deletions

File tree

cc3200/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
5656
#define MICROPY_OPT_COMPUTED_GOTO (0)
5757
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
58+
#define MICROPY_READER_FATFS (1)
5859
#ifndef DEBUG // we need ram on the launchxl while debugging
5960
#define MICROPY_CPYTHON_COMPAT (1)
6061
#else

esp8266/esp8266.ld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ SECTIONS
9292
*py/formatfloat.o*(.literal* .text*)
9393
*py/frozenmod.o*(.literal* .text*)
9494
*py/gc.o*(.literal* .text*)
95+
*py/reader*.o*(.literal* .text*)
9596
*py/lexer*.o*(.literal* .text*)
9697
*py/malloc*.o*(.literal* .text*)
9798
*py/map*.o*(.literal* .text*)

esp8266/esp8266_512k.ld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ SECTIONS
9292
*py/formatfloat.o*(.literal* .text*)
9393
*py/frozenmod.o*(.literal* .text*)
9494
*py/gc.o*(.literal* .text*)
95+
*py/reader*.o*(.literal* .text*)
9596
*py/lexer*.o*(.literal* .text*)
9697
*py/malloc*.o*(.literal* .text*)
9798
*py/map*.o*(.literal* .text*)

esp8266/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define MICROPY_MEM_STATS (0)
1717
#define MICROPY_DEBUG_PRINTERS (1)
1818
#define MICROPY_DEBUG_PRINTER_DEST mp_debug_print
19+
#define MICROPY_READER_FATFS (1)
1920
#define MICROPY_ENABLE_GC (1)
2021
#define MICROPY_STACK_CHECK (1)
2122
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)

examples/embedding/mpconfigport_minimal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define MICROPY_COMP_CONST (0)
3434
#define MICROPY_MEM_STATS (0)
3535
#define MICROPY_DEBUG_PRINTERS (0)
36+
#define MICROPY_READER_POSIX (1)
3637
#define MICROPY_HELPER_REPL (1)
3738
#define MICROPY_HELPER_LEXER_UNIX (1)
3839
#define MICROPY_ENABLE_SOURCE_LINE (0)

extmod/vfs_fat_reader.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2013-2016 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <stdio.h>
28+
#include <assert.h>
29+
30+
#include "py/mperrno.h"
31+
#include "py/reader.h"
32+
33+
#if MICROPY_READER_FATFS
34+
35+
#include "lib/fatfs/ff.h"
36+
#include "extmod/vfs_fat_file.h"
37+
38+
typedef struct _mp_reader_fatfs_t {
39+
FIL fp;
40+
uint16_t len;
41+
uint16_t pos;
42+
byte buf[20];
43+
} mp_reader_fatfs_t;
44+
45+
STATIC mp_uint_t mp_reader_fatfs_readbyte(void *data) {
46+
mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data;
47+
if (reader->pos >= reader->len) {
48+
if (reader->len < sizeof(reader->buf)) {
49+
return MP_READER_EOF;
50+
} else {
51+
UINT n;
52+
f_read(&reader->fp, reader->buf, sizeof(reader->buf), &n);
53+
if (n == 0) {
54+
return MP_READER_EOF;
55+
}
56+
reader->len = n;
57+
reader->pos = 0;
58+
}
59+
}
60+
return reader->buf[reader->pos++];
61+
}
62+
63+
STATIC void mp_reader_fatfs_close(void *data) {
64+
mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data;
65+
f_close(&reader->fp);
66+
m_del_obj(mp_reader_fatfs_t, reader);
67+
}
68+
69+
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
70+
mp_reader_fatfs_t *rf = m_new_obj_maybe(mp_reader_fatfs_t);
71+
if (rf == NULL) {
72+
return MP_ENOMEM;
73+
}
74+
FRESULT res = f_open(&rf->fp, filename, FA_READ);
75+
if (res != FR_OK) {
76+
return fresult_to_errno_table[res];
77+
}
78+
UINT n;
79+
f_read(&rf->fp, rf->buf, sizeof(rf->buf), &n);
80+
rf->len = n;
81+
rf->pos = 0;
82+
reader->data = rf;
83+
reader->readbyte = mp_reader_fatfs_readbyte;
84+
reader->close = mp_reader_fatfs_close;
85+
return 0; // success
86+
}
87+
88+
#endif

py/mpconfig.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,16 @@
381381
/*****************************************************************************/
382382
/* Python internal features */
383383

384+
// Whether to use the POSIX reader for importing files
385+
#ifndef MICROPY_READER_POSIX
386+
#define MICROPY_READER_POSIX (0)
387+
#endif
388+
389+
// Whether to use the FatFS reader for importing files
390+
#ifndef MICROPY_READER_FATFS
391+
#define MICROPY_READER_FATFS (0)
392+
#endif
393+
384394
// Hook for the VM at the start of the opcode loop (can contain variable
385395
// definitions usable by the other hook functions)
386396
#ifndef MICROPY_VM_HOOK_INIT

py/persistentcode.c

Lines changed: 15 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <string.h>
3030
#include <assert.h>
3131

32+
#include "py/reader.h"
3233
#include "py/emitglue.h"
3334
#include "py/persistentcode.h"
3435
#include "py/bc.h"
@@ -98,19 +99,19 @@ STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_
9899
#include "py/bc0.h"
99100

100101
STATIC int read_byte(mp_reader_t *reader) {
101-
return reader->read_byte(reader->data);
102+
return reader->readbyte(reader->data);
102103
}
103104

104105
STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) {
105106
while (len-- > 0) {
106-
*buf++ = reader->read_byte(reader->data);
107+
*buf++ = reader->readbyte(reader->data);
107108
}
108109
}
109110

110111
STATIC mp_uint_t read_uint(mp_reader_t *reader) {
111112
mp_uint_t unum = 0;
112113
for (;;) {
113-
byte b = reader->read_byte(reader->data);
114+
byte b = reader->readbyte(reader->data);
114115
unum = (unum << 7) | (b & 0x7f);
115116
if ((b & 0x80) == 0) {
116117
break;
@@ -214,128 +215,28 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) {
214215
if (header[2] != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits()) {
215216
mp_raise_ValueError("incompatible .mpy file");
216217
}
217-
return load_raw_code(reader);
218-
}
219-
220-
typedef struct _mp_mem_reader_t {
221-
const byte *cur;
222-
const byte *end;
223-
} mp_mem_reader_t;
224-
225-
STATIC mp_uint_t mp_mem_reader_next_byte(void *br_in) {
226-
mp_mem_reader_t *br = br_in;
227-
if (br->cur < br->end) {
228-
return *br->cur++;
229-
} else {
230-
return (mp_uint_t)-1;
231-
}
218+
mp_raw_code_t *rc = load_raw_code(reader);
219+
reader->close(reader->data);
220+
return rc;
232221
}
233222

234223
mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) {
235-
mp_mem_reader_t mr = {buf, buf + len};
236-
mp_reader_t reader = {&mr, mp_mem_reader_next_byte};
237-
return mp_raw_code_load(&reader);
238-
}
239-
240-
// here we define mp_raw_code_load_file depending on the port
241-
// TODO abstract this away properly
242-
243-
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || defined(__unix__)
244-
// unix file reader
245-
246-
#include <sys/stat.h>
247-
#include <fcntl.h>
248-
#include <unistd.h>
249-
250-
typedef struct _mp_lexer_file_buf_t {
251-
int fd;
252-
byte buf[20];
253-
mp_uint_t len;
254-
mp_uint_t pos;
255-
} mp_lexer_file_buf_t;
256-
257-
STATIC mp_uint_t file_buf_next_byte(void *fb_in) {
258-
mp_lexer_file_buf_t *fb = fb_in;
259-
if (fb->pos >= fb->len) {
260-
if (fb->len == 0) {
261-
return (mp_uint_t)-1;
262-
} else {
263-
int n = read(fb->fd, fb->buf, sizeof(fb->buf));
264-
if (n <= 0) {
265-
fb->len = 0;
266-
return (mp_uint_t)-1;
267-
}
268-
fb->len = n;
269-
fb->pos = 0;
270-
}
271-
}
272-
return fb->buf[fb->pos++];
273-
}
274-
275-
mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
276-
mp_lexer_file_buf_t fb;
277-
fb.fd = open(filename, O_RDONLY, 0644);
278-
int n = read(fb.fd, fb.buf, sizeof(fb.buf));
279-
fb.len = n;
280-
fb.pos = 0;
281224
mp_reader_t reader;
282-
reader.data = &fb;
283-
reader.read_byte = file_buf_next_byte;
284-
mp_raw_code_t *rc = mp_raw_code_load(&reader);
285-
close(fb.fd);
286-
return rc;
287-
}
288-
289-
#elif defined(__thumb2__) || defined(__xtensa__)
290-
// fatfs file reader (assume thumb2 arch uses fatfs...)
291-
292-
#include "lib/fatfs/ff.h"
293-
294-
typedef struct _mp_lexer_file_buf_t {
295-
FIL fp;
296-
byte buf[20];
297-
uint16_t len;
298-
uint16_t pos;
299-
} mp_lexer_file_buf_t;
300-
301-
STATIC mp_uint_t file_buf_next_byte(void *fb_in) {
302-
mp_lexer_file_buf_t *fb = fb_in;
303-
if (fb->pos >= fb->len) {
304-
if (fb->len < sizeof(fb->buf)) {
305-
return (mp_uint_t)-1;
306-
} else {
307-
UINT n;
308-
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
309-
if (n == 0) {
310-
return (mp_uint_t)-1;
311-
}
312-
fb->len = n;
313-
fb->pos = 0;
314-
}
225+
if (!mp_reader_new_mem(&reader, buf, len, 0)) {
226+
m_malloc_fail(BYTES_PER_WORD); // we need to raise a MemoryError
315227
}
316-
return fb->buf[fb->pos++];
228+
return mp_raw_code_load(&reader);
317229
}
318230

319231
mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
320-
mp_lexer_file_buf_t fb;
321-
/*FRESULT res =*/ f_open(&fb.fp, filename, FA_READ);
322-
UINT n;
323-
f_read(&fb.fp, fb.buf, sizeof(fb.buf), &n);
324-
fb.len = n;
325-
fb.pos = 0;
326-
327232
mp_reader_t reader;
328-
reader.data = &fb;
329-
reader.read_byte = file_buf_next_byte;
330-
mp_raw_code_t *rc = mp_raw_code_load(&reader);
331-
332-
f_close(&fb.fp);
333-
334-
return rc;
233+
int ret = mp_reader_new_file(&reader, filename);
234+
if (ret != 0) {
235+
mp_raise_OSError(ret);
236+
}
237+
return mp_raw_code_load(&reader);
335238
}
336239

337-
#endif
338-
339240
#endif // MICROPY_PERSISTENT_CODE_LOAD
340241

341242
#if MICROPY_PERSISTENT_CODE_SAVE

py/persistentcode.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,9 @@
2626
#ifndef MICROPY_INCLUDED_PY_PERSISTENTCODE_H
2727
#define MICROPY_INCLUDED_PY_PERSISTENTCODE_H
2828

29-
#include "py/obj.h"
30-
31-
typedef struct _mp_reader_t {
32-
void *data;
33-
mp_uint_t (*read_byte)(void *data);
34-
void (*close)(void *data);
35-
} mp_reader_t;
29+
#include "py/mpprint.h"
30+
#include "py/reader.h"
31+
#include "py/emitglue.h"
3632

3733
mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader);
3834
mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len);

py/py.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ PY_O_BASENAME = \
113113
mpprint.o \
114114
unicode.o \
115115
mpz.o \
116+
reader.o \
116117
lexer.o \
117118
lexerstr.o \
118119
lexerunix.o \
@@ -228,6 +229,7 @@ PY_O_BASENAME = \
228229
../extmod/vfs_fat_ffconf.o \
229230
../extmod/vfs_fat_diskio.o \
230231
../extmod/vfs_fat_file.o \
232+
../extmod/vfs_fat_reader.o \
231233
../extmod/vfs_fat_lexer.o \
232234
../extmod/vfs_fat_misc.o \
233235
../extmod/utime_mphal.o \

0 commit comments

Comments
 (0)