Merge branch 'master' into nrf5_no_sdk

This commit is contained in:
Glenn Ruben Bakke 2017-03-16 22:50:59 +01:00
commit 23163154b9
97 changed files with 968 additions and 432 deletions

View File

@ -39,7 +39,7 @@ script:
- make -C bare-arm
- make -C qemu-arm test
- make -C stmhal
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
- make -C stmhal BOARD=PYBV11 MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
- make -C stmhal BOARD=STM32F7DISC
- make -C stmhal BOARD=STM32L476DISC
- make -C teensy

View File

@ -18,13 +18,13 @@ WARNING: this project is in beta stage and is subject to changes of the
code-base, including project-wide name changes and API changes.
MicroPython implements the entire Python 3.4 syntax (including exceptions,
"with", "yield from", etc., and additionally "async" keyword from Python 3.5).
The following core datatypes are provided: str (including basic Unicode
support), bytes, bytearray, tuple, list, dict, set, frozenset, array.array,
collections.namedtuple, classes and instances. Builtin modules include sys,
time, and struct, etc. Select ports have support for _thread module
(multithreading). Note that only subset of Python 3.4 functionality
implemented for the data types and modules.
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
Python 3.5). The following core datatypes are provided: `str` (including
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
support for `_thread` module (multithreading). Note that only a subset of
Python 3 functionality is implemented for the data types and modules.
See the repository www.github.com/micropython/pyboard for the MicroPython
board (PyBoard), the officially supported reference electronic circuit board.

View File

@ -6,15 +6,12 @@
#include "py/compile.h"
#include "py/runtime.h"
#include "py/repl.h"
#include "py/mperrno.h"
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
return;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
@ -35,7 +32,7 @@ int main(int argc, char **argv) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {

View File

@ -98,7 +98,6 @@ OsiTaskHandle svTaskHandle;
DECLARE PRIVATE DATA
******************************************************************************/
static fs_user_mount_t *sflash_vfs_fat;
static mp_vfs_mount_t sflash_vfs_mount;
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
@ -303,8 +302,6 @@ STATIC void mptask_init_sflash_filesystem (void) {
// Initialise the local flash filesystem.
// init the vfs object
fs_user_mount_t *vfs_fat = sflash_vfs_fat;
vfs_fat->str = NULL;
vfs_fat->len = 0;
vfs_fat->flags = 0;
pyb_flash_init_vfs(vfs_fat);
@ -328,11 +325,16 @@ STATIC void mptask_init_sflash_filesystem (void) {
mptask_create_main_py();
}
} else {
fail:
__fatal_error("failed to create /flash");
}
// mount the flash device (there should be no other devices mounted at this point)
mp_vfs_mount_t *vfs = &sflash_vfs_mount;
// we allocate this structure on the heap because vfs->next is a root pointer
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
if (vfs == NULL) {
goto fail;
}
vfs->str = "/flash";
vfs->len = 6;
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);

View File

@ -39,7 +39,7 @@ Constructors
- `height` is the height of the FrameBuffer in pixels
- `format` specifies the type of pixel used in the FrameBuffer;
valid values are ``framebuf.MVLSB``, ``framebuf.RGB565``
and ``framebuf.GS4_HMSB``. MVLSB is monochrome 8-bit color,
and ``framebuf.GS4_HMSB``. MVLSB is monochrome 1-bit color,
RGB565 is RGB 16-bit color, and GS4_HMSB is grayscale 4-bit color.
Where a color value c is passed to a method, c is a small integer
with an encoding that is dependent on the format of the FrameBuffer.

View File

@ -58,10 +58,7 @@ STATIC void str32_buf_free(void *sb_in) {
}
mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) {
mp_lexer_str32_buf_t *sb = m_new_obj_maybe(mp_lexer_str32_buf_t);
if (sb == NULL) {
return NULL;
}
mp_lexer_str32_buf_t *sb = m_new_obj(mp_lexer_str32_buf_t);
sb->byte_off = (uint32_t)str & 3;
sb->src_cur = (uint32_t*)(str - sb->byte_off);
sb->val = *sb->src_cur++ >> sb->byte_off * 8;

View File

@ -32,6 +32,7 @@
#include "py/runtime0.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/gc.h"
#include "lib/mp-readline/readline.h"
@ -64,7 +65,9 @@ STATIC void mp_reset(void) {
#if MICROPY_MODULE_FROZEN
pyexec_frozen_module("_boot.py");
pyexec_file("boot.py");
pyexec_file("main.py");
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
pyexec_file("main.py");
}
#endif
}
@ -111,7 +114,7 @@ void user_init(void) {
#if !MICROPY_VFS
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {

View File

@ -35,9 +35,10 @@
static char heap[16384];
mp_obj_t execute_from_lexer(mp_lexer_t *lex) {
mp_obj_t execute_from_str(const char *str) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false);
mp_call_function_0(module_fun);
@ -58,8 +59,7 @@ int main() {
mp_init();
const char str[] = "print('Hello world of easy embedding!')";
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
if (execute_from_lexer(lex)) {
if (execute_from_str(str)) {
printf("Error\n");
}
}

View File

@ -43,33 +43,38 @@
// Returns MP_VFS_ROOT for root dir (and then path_out is undefined) and
// MP_VFS_NONE for path not found.
mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) {
if (path[0] == '/' && path[1] == 0) {
return MP_VFS_ROOT;
} else if (MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
// in root dir
if (path[0] == 0) {
return MP_VFS_ROOT;
if (*path == '/' || MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
// an absolute path, or the current volume is root, so search root dir
bool is_abs = 0;
if (*path == '/') {
++path;
is_abs = 1;
}
} else if (*path != '/') {
// a relative path within a mounted device
*path_out = path;
return MP_STATE_VM(vfs_cur);
}
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
if (strncmp(path, vfs->str, vfs->len) == 0) {
if (path[vfs->len] == '/') {
*path_out = path + vfs->len;
return vfs;
} else if (path[vfs->len] == '\0') {
*path_out = "/";
return vfs;
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
size_t len = vfs->len - 1;
if (strncmp(path, vfs->str + 1, len) == 0) {
if (path[len] == '/') {
*path_out = path + len;
return vfs;
} else if (path[len] == '\0') {
*path_out = "/";
return vfs;
}
}
}
if (*path == '\0') {
// path was "" or "/" so return virtual root
return MP_VFS_ROOT;
}
if (is_abs) {
// path began with / and was not found
return MP_VFS_NONE;
}
}
// mount point not found
return MP_VFS_NONE;
// a relative path within a mounted device
*path_out = path;
return MP_STATE_VM(vfs_cur);
}
// Version of mp_vfs_lookup_path that takes and returns uPy string objects.

View File

@ -55,8 +55,6 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
vfs->base.type = type;
vfs->flags = FSUSER_FREE_OBJ;
vfs->str = NULL;
vfs->len = 0;
vfs->fatfs.drv = vfs;
// load block protocol methods

View File

@ -36,8 +36,6 @@
typedef struct _fs_user_mount_t {
mp_obj_base_t base;
const char *str;
uint16_t len; // length of str
uint16_t flags;
mp_obj_t readblocks[4];
mp_obj_t writeblocks[4];

View File

@ -28,7 +28,7 @@
*/
#include "py/mpconfig.h"
#if MICROPY_VFS
#if MICROPY_VFS && MICROPY_VFS_FAT
#include <stdint.h>
#include <stdio.h>
@ -277,4 +277,4 @@ DRESULT disk_ioctl (
}
}
#endif // MICROPY_VFS
#endif // MICROPY_VFS && MICROPY_VFS_FAT

View File

@ -25,7 +25,7 @@
*/
#include "py/mpconfig.h"
#if MICROPY_VFS
#if MICROPY_VFS && MICROPY_VFS_FAT
#include <stdio.h>
#include <errno.h>
@ -37,10 +37,8 @@
#include "lib/oofatfs/ff.h"
#include "extmod/vfs_fat.h"
#if MICROPY_VFS_FAT
#define mp_type_fileio fatfs_type_fileio
#define mp_type_textio fatfs_type_textio
#endif
extern const mp_obj_type_t mp_type_fileio;
extern const mp_obj_type_t mp_type_textio;
@ -300,4 +298,4 @@ mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode)
return file_open(self, &mp_type_textio, arg_vals);
}
#endif // MICROPY_VFS
#endif // MICROPY_VFS && MICROPY_VFS_FAT

View File

@ -27,7 +27,7 @@
#include <stdio.h>
#include <string.h>
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/stream.h"
#include "py/reader.h"
#include "extmod/vfs.h"
@ -69,30 +69,19 @@ STATIC void mp_reader_vfs_close(void *data) {
m_del_obj(mp_reader_vfs_t, reader);
}
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
mp_reader_vfs_t *rf = m_new_obj_maybe(mp_reader_vfs_t);
if (rf == NULL) {
return MP_ENOMEM;
}
// TODO we really should just let this function raise a uPy exception
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
int errcode;
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
nlr_pop();
if (errcode != 0) {
return errcode;
}
} else {
return MP_ENOENT; // assume error was "file not found"
void mp_reader_new_file(mp_reader_t *reader, const char *filename) {
mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t);
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
int errcode;
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
if (errcode != 0) {
mp_raise_OSError(errcode);
}
rf->pos = 0;
reader->data = rf;
reader->readbyte = mp_reader_vfs_readbyte;
reader->close = mp_reader_vfs_close;
return 0; // success
}
#endif // MICROPY_READER_VFS

View File

@ -1,6 +1,8 @@
#include <stdlib.h>
#include "py/lexer.h"
#include "py/runtime.h"
#include "py/mperrno.h"
#include "memzip.h"
mp_lexer_t *mp_lexer_new_from_file(const char *filename)
@ -9,7 +11,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename)
size_t len;
if (memzip_locate(filename, &data, &len) != MZ_OK) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
return mp_lexer_new_from_str_len(qstr_from_str(filename), (const char *)data, (mp_uint_t)len, 0);

View File

@ -52,13 +52,15 @@ STATIC bool repl_display_debugging_info = 0;
#define EXEC_FLAG_ALLOW_DEBUGGING (2)
#define EXEC_FLAG_IS_REPL (4)
#define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
#define EXEC_FLAG_SOURCE_IS_VSTR (16)
#define EXEC_FLAG_SOURCE_IS_FILENAME (32)
// parses, compiles and executes the code in the lexer
// frees the lexer before returning
// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
// EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
// EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
int ret = 0;
uint32_t start = 0;
@ -76,8 +78,16 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
#endif
{
#if MICROPY_ENABLE_COMPILER
mp_lexer_t *lex;
if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) {
const vstr_t *vstr = source;
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0);
} else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) {
lex = mp_lexer_new_from_file(source);
} else {
lex = (mp_lexer_t*)source;
}
// source is a lexer, parse and compile the script
mp_lexer_t *lex = source;
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
@ -202,14 +212,9 @@ STATIC int pyexec_raw_repl_process_char(int c) {
return PYEXEC_FORCED_EXIT;
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, MP_STATE_VM(repl_line)->buf, MP_STATE_VM(repl_line)->len, 0);
if (lex == NULL) {
mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
} else {
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
reset:
@ -285,14 +290,9 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
}
exec: ;
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(MP_STATE_VM(repl_line)), vstr_len(MP_STATE_VM(repl_line)), 0);
if (lex == NULL) {
printf("MemoryError\n");
} else {
int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
input_restart:
@ -361,14 +361,9 @@ raw_repl_reset:
return PYEXEC_FORCED_EXIT;
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
if (lex == NULL) {
printf("\x04MemoryError\n\x04");
} else {
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
}
}
@ -489,14 +484,9 @@ friendly_repl_reset:
}
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
if (lex == NULL) {
printf("MemoryError\n");
} else {
ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
if (ret & PYEXEC_FORCED_EXIT) {
return ret;
}
}
}
@ -505,14 +495,7 @@ friendly_repl_reset:
#endif // MICROPY_ENABLE_COMPILER
int pyexec_file(const char *filename) {
mp_lexer_t *lex = mp_lexer_new_from_file(filename);
if (lex == NULL) {
printf("could not open file '%s' for reading\n", filename);
return false;
}
return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME);
}
#if MICROPY_MODULE_FROZEN

View File

@ -7,18 +7,14 @@
#include "py/runtime.h"
#include "py/repl.h"
#include "py/gc.h"
#include "py/mperrno.h"
#include "lib/utils/pyexec.h"
#if MICROPY_ENABLE_COMPILER
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
printf("MemoryError: lexer could not allocate memory\n");
return;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
@ -74,7 +70,7 @@ void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {

View File

@ -57,14 +57,10 @@ STATIC void stderr_print_strn(void *env, const char *str, mp_uint_t len) {
STATIC const mp_print_t mp_stderr_print = {NULL, stderr_print_strn};
STATIC int compile_and_save(const char *file, const char *output_file, const char *source_file) {
mp_lexer_t *lex = mp_lexer_new_from_file(file);
if (lex == NULL) {
printf("could not open file '%s' for reading\n", file);
return 1;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_file(file);
qstr source_name;
if (source_file == NULL) {
source_name = lex->source_name;

View File

@ -33,6 +33,7 @@
#include "py/runtime.h"
#include "py/gc.h"
#include "py/mphal.h"
#include "py/mperrno.h"
#include "lib/utils/pyexec.h"
#include "readline.h"
#include "board.h"
@ -98,7 +99,7 @@ void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {
@ -111,6 +112,7 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void nlr_jump_fail(void *val) {
while (1);
}
void NORETURN __fatal_error(const char *msg) {

View File

@ -136,9 +136,6 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i
mp_lexer_t *lex;
if (MICROPY_PY_BUILTINS_EXECFILE && parse_input_kind == MP_PARSE_SINGLE_INPUT) {
lex = mp_lexer_new_from_file(str);
if (lex == NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "could not open file '%s'", str));
}
parse_input_kind = MP_PARSE_FILE_INPUT;
} else {
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, str, str_len, 0);

View File

@ -131,18 +131,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d
}
#if MICROPY_ENABLE_COMPILER
STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex, const char *fname) {
if (lex == NULL) {
// we verified the file exists using stat, but lexer could still fail
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_msg(&mp_type_ImportError, "module not found");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%s'", fname));
}
}
STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) {
#if MICROPY_PY___FILE__
qstr source_name = lex->source_name;
mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
@ -207,7 +196,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
// found the filename in the list of frozen files, then load and execute it.
#if MICROPY_MODULE_FROZEN_STR
if (frozen_type == MP_FROZEN_STR) {
do_load_from_lexer(module_obj, modref, file_str);
do_load_from_lexer(module_obj, modref);
return;
}
#endif
@ -235,7 +224,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
#if MICROPY_ENABLE_COMPILER
{
mp_lexer_t *lex = mp_lexer_new_from_file(file_str);
do_load_from_lexer(module_obj, lex, file_str);
do_load_from_lexer(module_obj, lex);
return;
}
#endif

View File

@ -385,11 +385,9 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
ASM_MOV_REG_REG(emit->as, REG_LOCAL_2, REG_ARG_2);
} else if (i == 2) {
ASM_MOV_REG_REG(emit->as, REG_LOCAL_3, REG_ARG_3);
} else if (i == 3) {
ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_4, i - REG_LOCAL_NUM);
} else {
// TODO not implemented
mp_not_implemented("more than 4 viper args");
assert(i == 3); // should be true; max 4 args is checked above
ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_4, i - REG_LOCAL_NUM);
}
}
#endif
@ -527,9 +525,7 @@ STATIC void emit_native_end_pass(emit_t *emit) {
ASM_END_PASS(emit->as);
// check stack is back to zero size
if (emit->stack_size != 0) {
mp_printf(&mp_plat_print, "ERROR: stack size not back to zero; got %d\n", emit->stack_size);
}
assert(emit->stack_size == 0);
if (emit->pass == MP_PASS_EMIT) {
void *f = mp_asm_base_get_code(&emit->as->base);
@ -595,38 +591,9 @@ STATIC void emit_native_set_source_line(emit_t *emit, mp_uint_t source_line) {
(void)source_line;
}
/*
STATIC void emit_pre_raw(emit_t *emit, int stack_size_delta) {
adjust_stack(emit, stack_size_delta);
emit->last_emit_was_return_value = false;
}
*/
// this must be called at start of emit functions
STATIC void emit_native_pre(emit_t *emit) {
emit->last_emit_was_return_value = false;
// settle the stack
/*
if (regs_needed != 0) {
for (int i = 0; i < emit->stack_size; i++) {
switch (emit->stack_info[i].kind) {
case STACK_VALUE:
break;
case STACK_REG:
// TODO only push reg if in regs_needed
emit->stack_info[i].kind = STACK_VALUE;
ASM_MOV_REG_TO_LOCAL(emit->as, emit->stack_info[i].data.u_reg, emit->stack_start + i);
break;
case STACK_IMM:
// don't think we ever need to push imms for settling
//ASM_MOV_IMM_TO_LOCAL(emit->last_imm, emit->stack_start + i);
break;
}
}
}
*/
}
// depth==0 is top, depth==1 is before top, etc
@ -867,7 +834,7 @@ STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_de
break;
default:
// not handled
assert(0);
mp_not_implemented("conversion to object");
}
}
@ -1011,9 +978,7 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) {
// do native array access. For now we just load them as any other object.
/*
if (emit->do_viper_types) {
// not implemented properly
// load a pointer to the asciiz string?
assert(0);
emit_post_push_imm(emit, VTYPE_PTR, (mp_uint_t)qstr_str(qst));
} else
*/
@ -1843,12 +1808,6 @@ STATIC void emit_native_pop_block(emit_t *emit) {
STATIC void emit_native_pop_except(emit_t *emit) {
(void)emit;
/*
emit_native_pre(emit);
emit_call(emit, MP_F_NLR_POP);
adjust_stack(emit, -(mp_int_t)(sizeof(nlr_buf_t) / sizeof(mp_uint_t)));
emit_post(emit);
*/
}
STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
@ -2202,7 +2161,8 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
emit_post_top_set_vtype(emit, vtype_cast);
break;
default:
assert(!"TODO: convert obj to int");
// this can happen when casting a cast: int(int)
mp_not_implemented("casting");
}
} else {
assert(vtype_fun == VTYPE_PYOBJ);
@ -2259,7 +2219,6 @@ STATIC void emit_native_return_value(emit_t *emit) {
assert(vtype == VTYPE_PYOBJ);
}
emit->last_emit_was_return_value = true;
//ASM_BREAK_POINT(emit->as); // to insert a break-point for debugging
ASM_EXIT(emit->as);
}

View File

@ -699,13 +699,7 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
}
mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
mp_lexer_t *lex = m_new_obj_maybe(mp_lexer_t);
// check for memory allocation error
if (lex == NULL) {
reader.close(reader.data);
return NULL;
}
mp_lexer_t *lex = m_new_obj(mp_lexer_t);
lex->source_name = src_name;
lex->reader = reader;
@ -715,16 +709,9 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
lex->nested_bracket_level = 0;
lex->alloc_indent_level = MICROPY_ALLOC_LEXER_INDENT_INIT;
lex->num_indent_level = 1;
lex->indent_level = m_new_maybe(uint16_t, lex->alloc_indent_level);
lex->indent_level = m_new(uint16_t, lex->alloc_indent_level);
vstr_init(&lex->vstr, 32);
// check for memory allocation error
// note: vstr_init above may fail on malloc, but so may mp_lexer_to_next below
if (lex->indent_level == NULL) {
mp_lexer_free(lex);
return NULL;
}
// store sentinel for first indentation level
lex->indent_level[0] = 0;
@ -764,9 +751,7 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len, size_t free_len) {
mp_reader_t reader;
if (!mp_reader_new_mem(&reader, (const byte*)str, len, free_len)) {
return NULL;
}
mp_reader_new_mem(&reader, (const byte*)str, len, free_len);
return mp_lexer_new(src_name, reader);
}
@ -774,10 +759,7 @@ mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
mp_reader_t reader;
int ret = mp_reader_new_file(&reader, filename);
if (ret != 0) {
return NULL;
}
mp_reader_new_file(&reader, filename);
return mp_lexer_new(qstr_from_str(filename), reader);
}
@ -785,10 +767,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
mp_lexer_t *mp_lexer_new_from_fd(qstr filename, int fd, bool close_fd) {
mp_reader_t reader;
int ret = mp_reader_new_file_from_fd(&reader, fd, close_fd);
if (ret != 0) {
return NULL;
}
mp_reader_new_file_from_fd(&reader, fd, close_fd);
return mp_lexer_new(filename, reader);
}

View File

@ -71,12 +71,7 @@ $(OBJ): | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/mpversion.h
$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) | $(HEADER_BUILD)/mpversion.h
$(ECHO) "GEN $@"
$(Q)if [ "$?" = "" ]; then \
echo "QSTR Looks like -B used, trying to emulate"; \
$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $^ >$(HEADER_BUILD)/qstr.i.last; \
else \
$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $? >$(HEADER_BUILD)/qstr.i.last; \
fi
$(Q)$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $? >$(HEADER_BUILD)/qstr.i.last;
$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last
$(ECHO) "GEN $@"

View File

@ -222,7 +222,7 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char
char prefix_buf[4];
char *prefix = prefix_buf;
if (mp_obj_int_sign(x) > 0) {
if (mp_obj_int_sign(x) >= 0) {
if (flags & PF_FLAG_SHOW_SIGN) {
*prefix++ = '+';
} else if (flags & PF_FLAG_SPACE_SIGN) {

View File

@ -61,6 +61,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
#else
__asm volatile (
#if defined(__APPLE__) || defined(__MACH__)
"pop %rbp \n" // undo function's prelude
#endif
"movq (%rsp), %rax \n" // load return %rip
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
@ -70,7 +73,11 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
"movq %r13, 56(%rdi) \n" // store %r13 into nlr_buf
"movq %r14, 64(%rdi) \n" // store %r14 into nlr_buf
"movq %r15, 72(%rdi) \n" // store %r15 into nlr_buf
#if defined(__APPLE__) || defined(__MACH__)
"jmp _nlr_push_tail \n" // do the rest in C
#else
"jmp nlr_push_tail \n" // do the rest in C
#endif
);
#endif

View File

@ -127,11 +127,17 @@ mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
#undef MP_FLOAT_EXP_SHIFT_I32
#endif
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
typedef mp_longint_impl_t fmt_int_t;
#else
typedef mp_int_t fmt_int_t;
#endif
void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
// The size of this buffer is rather arbitrary. If it's not large
// enough, a dynamic one will be allocated.
char stack_buf[sizeof(mp_int_t) * 4];
char stack_buf[sizeof(fmt_int_t) * 4];
char *buf = stack_buf;
size_t buf_size = sizeof(stack_buf);
size_t fmt_size;
@ -144,12 +150,6 @@ void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
}
}
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
typedef mp_longint_impl_t fmt_int_t;
#else
typedef mp_int_t fmt_int_t;
#endif
STATIC const uint8_t log_base2_floor[] = {
0, 1, 1, 2,
2, 2, 2, 3,

View File

@ -54,7 +54,17 @@ const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
#endif
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
mp_not_implemented("");
int delta = 1;
if (!big_endian) {
buf += len - 1;
delta = -1;
}
mp_longint_impl_t value = 0;
for (; len--; buf += delta) {
value = (value << 8) | *buf;
}
return mp_obj_new_int_from_ll(value);
}
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {

View File

@ -354,7 +354,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
switch (op) {
case MP_BINARY_OP_ADD:
case MP_BINARY_OP_INPLACE_ADD: {
if (lhs_len == 0) {
if (lhs_len == 0 && mp_obj_get_type(rhs_in) == lhs_type) {
return rhs_in;
}
if (rhs_len == 0) {

View File

@ -225,18 +225,13 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) {
mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) {
mp_reader_t reader;
if (!mp_reader_new_mem(&reader, buf, len, 0)) {
m_malloc_fail(BYTES_PER_WORD); // we need to raise a MemoryError
}
mp_reader_new_mem(&reader, buf, len, 0);
return mp_raw_code_load(&reader);
}
mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
mp_reader_t reader;
int ret = mp_reader_new_file(&reader, filename);
if (ret != 0) {
mp_raise_OSError(ret);
}
mp_reader_new_file(&reader, filename);
return mp_raw_code_load(&reader);
}

View File

@ -27,6 +27,7 @@
#include <stdio.h>
#include <assert.h>
#include "py/runtime.h"
#include "py/mperrno.h"
#include "py/reader.h"
@ -54,11 +55,8 @@ STATIC void mp_reader_mem_close(void *data) {
m_del_obj(mp_reader_mem_t, reader);
}
bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
mp_reader_mem_t *rm = m_new_obj_maybe(mp_reader_mem_t);
if (rm == NULL) {
return false;
}
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
mp_reader_mem_t *rm = m_new_obj(mp_reader_mem_t);
rm->free_len = free_len;
rm->beg = buf;
rm->cur = buf;
@ -66,7 +64,6 @@ bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t
reader->data = rm;
reader->readbyte = mp_reader_mem_readbyte;
reader->close = mp_reader_mem_close;
return true;
}
#if MICROPY_READER_POSIX
@ -110,14 +107,8 @@ STATIC void mp_reader_posix_close(void *data) {
m_del_obj(mp_reader_posix_t, reader);
}
int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
mp_reader_posix_t *rp = m_new_obj_maybe(mp_reader_posix_t);
if (rp == NULL) {
if (close_fd) {
close(fd);
}
return MP_ENOMEM;
}
void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
mp_reader_posix_t *rp = m_new_obj(mp_reader_posix_t);
rp->close_fd = close_fd;
rp->fd = fd;
int n = read(rp->fd, rp->buf, sizeof(rp->buf));
@ -125,22 +116,21 @@ int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
if (close_fd) {
close(fd);
}
return errno;
mp_raise_OSError(errno);
}
rp->len = n;
rp->pos = 0;
reader->data = rp;
reader->readbyte = mp_reader_posix_readbyte;
reader->close = mp_reader_posix_close;
return 0; // success
}
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
void mp_reader_new_file(mp_reader_t *reader, const char *filename) {
int fd = open(filename, O_RDONLY, 0644);
if (fd < 0) {
return errno;
mp_raise_OSError(errno);
}
return mp_reader_new_file_from_fd(reader, fd, true);
mp_reader_new_file_from_fd(reader, fd, true);
}
#endif

View File

@ -39,8 +39,8 @@ typedef struct _mp_reader_t {
void (*close)(void *data);
} mp_reader_t;
bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len);
int mp_reader_new_file(mp_reader_t *reader, const char *filename);
int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd);
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len);
void mp_reader_new_file(mp_reader_t *reader, const char *filename);
void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd);
#endif // MICROPY_INCLUDED_PY_READER_H

View File

@ -36,10 +36,12 @@ LDFLAGS= --specs=nano.specs --specs=rdimon.specs -Wl,--gc-sections -Wl,-Map=$(@:
SRC_C = \
main.c \
moduos.c \
modmachine.c \
SRC_TEST_C = \
test_main.c \
moduos.c \
modmachine.c \
LIB_SRC_C = $(addprefix lib/,\

View File

@ -12,15 +12,12 @@
#include "py/stackctrl.h"
#include "py/gc.h"
#include "py/repl.h"
#include "py/mperrno.h"
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
return;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
@ -47,7 +44,7 @@ void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {

52
qemu-arm/moduos.c Normal file
View File

@ -0,0 +1,52 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "extmod/vfs.h"
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
// MicroPython extensions
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
};
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
const mp_obj_module_t mp_module_uos = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&os_module_globals,
};

View File

@ -35,6 +35,7 @@
#define MICROPY_PY_UHASHLIB (1)
#define MICROPY_PY_MACHINE (1)
#define MICROPY_USE_INTERNAL_PRINTF (0)
#define MICROPY_VFS (1)
// type definitions for the specific machine
@ -58,7 +59,11 @@ typedef long mp_off_t;
#define MICROPY_PORT_BUILTINS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
// extra built-in modules to add to the list of known ones
extern const struct _mp_obj_module_t mp_module_uos;
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \
{ MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \
// We need to provide a declaration/definition of alloca()

View File

@ -11,7 +11,7 @@
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/gc.h"
#include "py/repl.h"
#include "py/mperrno.h"
#include "tinytest.h"
#include "tinytest_macros.h"
@ -24,13 +24,9 @@ inline void do_str(const char *src) {
gc_init(heap, (char*)heap + HEAP_SIZE);
mp_init();
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
tt_abort_msg("Lexer initialization error");
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false);
@ -80,7 +76,7 @@ void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {

View File

@ -65,7 +65,6 @@ void SystemClock_Config(void);
pyb_thread_t pyb_thread_main;
fs_user_mount_t fs_user_mount_flash;
mp_vfs_mount_t mp_vfs_mount_flash;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
@ -168,8 +167,6 @@ static const char fresh_readme_txt[] =
MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
// init the vfs object
fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
vfs_fat->str = NULL;
vfs_fat->len = 0;
vfs_fat->flags = 0;
pyb_flash_init_vfs(vfs_fat);
@ -219,12 +216,17 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
} else if (res == FR_OK) {
// mount sucessful
} else {
fail:
printf("PYB: can't mount flash\n");
return false;
}
// mount the flash device (there should be no other devices mounted at this point)
mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
// we allocate this structure on the heap because vfs->next is a root pointer
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
if (vfs == NULL) {
goto fail;
}
vfs->str = "/flash";
vfs->len = 6;
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
@ -270,8 +272,6 @@ STATIC bool init_sdcard_fs(bool first_soft_reset) {
if (vfs == NULL || vfs_fat == NULL) {
break;
}
vfs_fat->str = NULL;
vfs_fat->len = 0;
vfs_fat->flags = FSUSER_FREE_OBJ;
sdcard_init_vfs(vfs_fat, part_num);

View File

@ -72,6 +72,10 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
void mp_hal_ticks_cpu_enable(void) {
if (!mp_hal_ticks_cpu_enabled) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
#if defined(__CORTEX_M) && __CORTEX_M == 7
// on Cortex-M7 we must unlock the DWT before writing to its registers
DWT->LAR = 0xc5acce55;
#endif
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
mp_hal_ticks_cpu_enabled = true;

View File

@ -1,11 +1,13 @@
#include <stdio.h>
#include "py/lexer.h"
#include "py/runtime.h"
#include "py/mperrno.h"
mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(MP_ENOENT);
}

View File

@ -1,4 +1,10 @@
# test builtin property
try:
property
except:
import sys
print("SKIP")
sys.exit()
# create a property object explicitly
property()

View File

@ -1,4 +1,11 @@
# test builtin sorted
try:
sorted
set
except:
import sys
print("SKIP")
sys.exit()
print(sorted(set(range(100))))
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))

View File

@ -1,12 +1,6 @@
# test construction of bytearray from different objects
from array import array
# bytes, tuple, list
print(bytearray(b'123'))
print(bytearray((1, 2)))
print(bytearray([1, 2]))
# arrays
print(bytearray(array('b', [1, 2])))
print(bytearray(array('h', [0x101, 0x202])))

View File

@ -0,0 +1,11 @@
# test construction of bytearray from different objects
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
# arrays
print(bytearray(array('b', [1, 2])))
print(bytearray(array('h', [0x101, 0x202])))

View File

@ -1,6 +1,10 @@
# test construction of bytearray from different objects
from array import array
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
# arrays
print(bytearray(array('h', [1, 2])))

View File

@ -3,9 +3,6 @@
print(b"123" + b"456")
print(b"123" + bytearray(2))
import array
# should be byteorder-neutral
print(b"123" + array.array('h', [0x1515]))
print(b"\x01\x02" + array.array('b', [1, 2]))
print(b"123" + b"") # RHS is empty, can be optimised
print(b"" + b"123") # LHS is empty, can be optimised
print(b"" + bytearray(1)) # LHS is empty but can't be optimised

View File

@ -0,0 +1,12 @@
# test bytes + other
try:
import array
except ImportError:
import sys
print("SKIP")
sys.exit()
# should be byteorder-neutral
print(b"123" + array.array('h', [0x1515]))
print(b"\x01\x02" + array.array('b', [1, 2]))

View File

@ -1,5 +1,9 @@
# test bytes + other
import array
try:
import array
except ImportError:
import sys
print("SKIP")
sys.exit()
print(b"123" + array.array('i', [1]))

View File

@ -3,9 +3,3 @@ print(b"123" == bytearray(b"123"))
print(b'123' < bytearray(b"124"))
print(b'123' > bytearray(b"122"))
print(bytearray(b"23") in b"1234")
import array
print(array.array('b', [1, 2]) in b'\x01\x02\x03')
# CPython gives False here
#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))

View File

@ -0,0 +1,10 @@
try:
import array
except ImportError:
import sys
print("SKIP")
sys.exit()
print(array.array('b', [1, 2]) in b'\x01\x02\x03')
# CPython gives False here
#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))

View File

@ -1,16 +1,10 @@
# test construction of bytes from different objects
from array import array
# tuple, list, bytearray
print(bytes((1, 2)))
print(bytes([1, 2]))
print(bytes(bytearray(4)))
# arrays
print(bytes(array('b', [1, 2])))
print(bytes(array('h', [0x101, 0x202])))
# constructor value out of range
try:
bytes([-1])

View File

@ -0,0 +1,11 @@
# test construction of bytes from different objects
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
# arrays
print(bytes(array('b', [1, 2])))
print(bytes(array('h', [0x101, 0x202])))

View File

@ -1,6 +1,11 @@
# test construction of bytes from different objects
from array import array
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
# arrays
print(bytes(array('h', [1, 2])))

View File

@ -7,8 +7,3 @@ d = dict.fromkeys([1, 2, 3, 4], 42)
l = list(d.values())
l.sort()
print(l)
# argument to fromkeys has no __len__
d = dict.fromkeys(reversed(range(1)))
#d = dict.fromkeys((x for x in range(1)))
print(d)

View File

@ -0,0 +1,11 @@
try:
reversed
except:
import sys
print("SKIP")
sys.exit()
# argument to fromkeys has no __len__
d = dict.fromkeys(reversed(range(1)))
#d = dict.fromkeys((x for x in range(1)))
print(d)

View File

@ -27,8 +27,5 @@ test_exc("[].sort(1)", TypeError)
# function with keyword args given extra keyword args
test_exc("[].sort(noexist=1)", TypeError)
# function with keyword args not given a specific keyword arg
test_exc("enumerate()", TypeError)
# kw given for positional, but a different positional is missing
test_exc("def f(x, y): pass\nf(x=1)", TypeError)

View File

@ -0,0 +1,19 @@
# test errors from bad function calls
try:
enumerate
except:
print("SKIP")
import sys
sys.exit()
def test_exc(code, exc):
try:
exec(code)
print("no exception")
except exc:
print("right exception")
except:
print("wrong exception")
# function with keyword args not given a specific keyword arg
test_exc("enumerate()", TypeError)

View File

@ -1,6 +1,6 @@
# comprehensive functionality test for {} format string
int_tests = False # these take a while, and some give wrong results
int_tests = False # these take a while
char_tests = True
str_tests = True

View File

@ -33,38 +33,6 @@ print("%c" % 48)
print("%c" % 'a')
print("%10s" % 'abc')
print("%-10s" % 'abc')
print("%d" % 10)
print("%+d" % 10)
print("% d" % 10)
print("%d" % -10)
print("%d" % True)
print("%i" % -10)
print("%i" % True)
print("%u" % -10)
print("%u" % True)
print("%x" % 18)
print("%o" % 18)
print("%X" % 18)
print("%#x" % 18)
print("%#X" % 18)
print("%#6o" % 18)
print("%#6x" % 18)
print("%#06x" % 18)
print("%*d" % (5, 10))
print("%*.*d" % (2, 2, 20))
print("%*.*d" % (5, 8, 20))
print(">%8.4d<" % -12)
print(">% 8.4d<" % -12)
print(">%+8.4d<" % 12)
print(">%+8.4d<" % -12)
print(">%08.4d<" % -12)
print(">%08.4d<" % 12)
print(">%-8.4d<" % -12)
print(">%-08.4d<" % -12)
print(">%-+08.4d<" % -12)
print(">%-+08.4d<" % 12)
# Should be able to print dicts; in this case they aren't used
# to lookup keywords in formats like %(foo)s

View File

@ -0,0 +1,41 @@
# test string modulo formatting with int values
# basic cases
print("%d" % 10)
print("%+d" % 10)
print("% d" % 10)
print("%d" % -10)
print("%d" % True)
print("%i" % -10)
print("%i" % True)
print("%u" % -10)
print("%u" % True)
print("%x" % 18)
print("%o" % 18)
print("%X" % 18)
print("%#x" % 18)
print("%#X" % 18)
print("%#6o" % 18)
print("%#6x" % 18)
print("%#06x" % 18)
# with *
print("%*d" % (5, 10))
print("%*.*d" % (2, 2, 20))
print("%*.*d" % (5, 8, 20))
# precision
for val in (-12, 12):
print(">%8.4d<" % val)
print(">% 8.4d<" % val)
print(">%+8.4d<" % val)
print(">%08.4d<" % val)
print(">%-8.4d<" % val)
print(">%-08.4d<" % val)
print(">%-+08.4d<" % val)
# test + option with various amount of padding
for pad in ('', ' ', '0'):
for n in (1, 2, 3):
for val in (-1, 0, 1):
print(('%+' + pad + str(n) + 'd') % val)

View File

@ -18,3 +18,16 @@ o = A()
s = struct.pack("<O", o)
o2 = struct.unpack("<O", s)
print(o is o2[0])
# pack and unpack pointer to a string
# This requires uctypes to get the address of the string and instead of
# putting this in a dedicated test that can be skipped we simply pass
# if the import fails.
try:
import uctypes
o = uctypes.addressof('abc')
s = struct.pack("<S", o)
o2 = struct.unpack("<S", s)
assert o2[0] == 'abc'
except ImportError:
pass

View File

@ -72,6 +72,11 @@ m = re.match('^ab$', 'ab'); print(m.group(0))
m = re.match('a|b', 'b'); print(m.group(0))
m = re.match('a|b|c', 'c'); print(m.group(0))
# Case where anchors fail to match
r = re.compile("^b|b$")
m = r.search("abc")
print(m)
try:
re.compile("*")
except:

View File

@ -0,0 +1,52 @@
# very basic test of ssl module, just to test the methods exist
try:
import uio as io
import ussl as ssl
except ImportError:
print("SKIP")
import sys
sys.exit()
# create in client mode
try:
ss = ssl.wrap_socket(io.BytesIO())
except OSError as er:
print('wrap_socket:', repr(er))
# create in server mode (can use this object for further tests)
socket = io.BytesIO()
ss = ssl.wrap_socket(socket, server_side=1)
# print
print(repr(ss)[:12])
# setblocking
try:
ss.setblocking(False)
except NotImplementedError:
print('setblocking: NotImplementedError')
ss.setblocking(True)
# write
print(ss.write(b'aaaa'))
# read (underlying socket has no data)
print(ss.read(8))
# read (underlying socket has data, but it's bad data)
socket.write(b'aaaaaaaaaaaaaaaa')
socket.seek(0)
try:
ss.read(8)
except OSError as er:
print('read:', repr(er))
# close
ss.close()
# write on closed socket
try:
ss.write(b'aaaa')
except OSError as er:
print('write:', repr(er))

View File

@ -0,0 +1,8 @@
ssl_handshake_status: -256
wrap_socket: OSError(5,)
<_SSLSocket
setblocking: NotImplementedError
4
b''
read: OSError(-261,)
write: OSError(-256,)

View File

@ -20,6 +20,16 @@ print(inp.read(1))
print(inp.read())
print(buf.seek(0, 1))
# Check FHCRC field
buf = io.BytesIO(b'\x1f\x8b\x08\x02\x99\x0c\xe5W\x00\x03\x00\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
inp = zlib.DecompIO(buf, 16 + 8)
print(inp.read())
# Check FEXTRA field
buf = io.BytesIO(b'\x1f\x8b\x08\x04\x99\x0c\xe5W\x00\x03\x01\x00X\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
inp = zlib.DecompIO(buf, 16 + 8)
print(inp.read())
# broken header
buf = io.BytesIO(b'\x1f\x8c\x08\x08\x99\x0c\xe5W\x00\x03hello\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
try:

View File

@ -7,5 +7,7 @@ b'lo'
b''
b''
31
b'hello'
b'hello'
ValueError
OSError(22,)

111
tests/extmod/vfs_basic.py Normal file
View File

@ -0,0 +1,111 @@
# test VFS functionality without any particular filesystem type
try:
try:
import uos_vfs as uos
open = uos.vfs_open
except ImportError:
import uos
uos.mount
except (ImportError, AttributeError):
print("SKIP")
import sys
sys.exit()
class Filesystem:
def __init__(self, id):
self.id = id
def mount(self, readonly, mkfs):
print(self.id, 'mount', readonly, mkfs)
def umount(self):
print(self.id, 'umount')
def listdir(self, dir):
print(self.id, 'listdir', dir)
return ['a%d' % self.id]
def chdir(self, dir):
print(self.id, 'chdir', dir)
def getcwd(self):
print(self.id, 'getcwd')
return 'dir%d' % self.id
def mkdir(self, path):
print(self.id, 'mkdir', path)
def remove(self, path):
print(self.id, 'remove', path)
def rename(self, old_path, new_path):
print(self.id, 'rename', old_path, new_path)
def rmdir(self, path):
print(self.id, 'rmdir', path)
def stat(self, path):
print(self.id, 'stat', path)
return (self.id,)
def statvfs(self, path):
print(self.id, 'statvfs', path)
return (self.id,)
def open(self, file, mode):
print(self.id, 'open', file, mode)
# first we umount any existing mount points the target may have
for path in uos.listdir('/'):
uos.umount('/' + path)
# stat root dir
print(uos.stat('/'))
# getcwd when in root dir
print(uos.getcwd())
# basic mounting and listdir
uos.mount(Filesystem(1), '/test_mnt')
print(uos.listdir())
# referencing the mount point in different ways
print(uos.listdir('test_mnt'))
print(uos.listdir('/test_mnt'))
# mounting another filesystem
uos.mount(Filesystem(2), '/test_mnt2', readonly=True)
print(uos.listdir())
print(uos.listdir('/test_mnt2'))
# mounting over an existing mount point
try:
uos.mount(Filesystem(3), '/test_mnt2')
except OSError:
print('OSError')
# mkdir of a mount point
try:
uos.mkdir('/test_mnt')
except OSError:
print('OSError')
# rename across a filesystem
try:
uos.rename('/test_mnt/a', '/test_mnt2/b')
except OSError:
print('OSError')
# delegating to mounted filesystem
uos.chdir('test_mnt')
print(uos.listdir())
print(uos.getcwd())
uos.mkdir('test_dir')
uos.remove('test_file')
uos.rename('test_file', 'test_file2')
uos.rmdir('test_dir')
print(uos.stat('test_file'))
print(uos.statvfs('/test_mnt'))
open('test_file')
open('test_file', 'wb')
# umount
uos.umount('/test_mnt')
uos.umount('/test_mnt2')
# umount a non-existent mount point
try:
uos.umount('/test_mnt')
except OSError:
print('OSError')

View File

@ -0,0 +1,34 @@
(16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
/
1 mount False False
['test_mnt']
1 listdir /
['a1']
1 listdir /
['a1']
2 mount True False
['test_mnt', 'test_mnt2']
2 listdir /
['a2']
3 mount False False
OSError
OSError
OSError
1 chdir /
1 listdir
['a1']
1 getcwd
/test_mntdir1
1 mkdir test_dir
1 remove test_file
1 rename test_file test_file2
1 rmdir test_dir
1 stat test_file
(1,)
1 statvfs /
(1,)
1 open test_file r
1 open test_file wb
1 umount
2 umount
OSError

View File

@ -0,0 +1,61 @@
try:
import uio
import uerrno
import websocket
except ImportError:
import sys
print("SKIP")
sys.exit()
# put raw data in the stream and do a websocket read
def ws_read(msg, sz):
ws = websocket.websocket(uio.BytesIO(msg))
return ws.read(sz)
# do a websocket write and then return the raw data from the stream
def ws_write(msg, sz):
s = uio.BytesIO()
ws = websocket.websocket(s)
ws.write(msg)
s.seek(0)
return s.read(sz)
# basic frame
print(ws_read(b"\x81\x04ping", 4))
print(ws_read(b"\x80\x04ping", 4)) # FRAME_CONT
print(ws_write(b"pong", 6))
# split frames are not supported
# print(ws_read(b"\x01\x04ping", 4))
# extended payloads
print(ws_read(b'\x81~\x00\x80' + b'ping' * 32, 128))
print(ws_write(b"pong" * 32, 132))
# mask (returned data will be 'mask' ^ 'mask')
print(ws_read(b"\x81\x84maskmask", 4))
# close control frame
s = uio.BytesIO(b'\x88\x00') # FRAME_CLOSE
ws = websocket.websocket(s)
print(ws.read(1))
s.seek(2)
print(s.read(4))
# misc control frames
print(ws_read(b"\x89\x00\x81\x04ping", 4)) # FRAME_PING
print(ws_read(b"\x8a\x00\x81\x04pong", 4)) # FRAME_PONG
# close method
ws = websocket.websocket(uio.BytesIO())
ws.close()
# ioctl
ws = websocket.websocket(uio.BytesIO())
print(ws.ioctl(8)) # GET_DATA_OPTS
print(ws.ioctl(9, 2)) # SET_DATA_OPTS
print(ws.ioctl(9))
try:
ws.ioctl(-1)
except OSError as e:
print("ioctl: EINVAL:", e.args[0] == uerrno.EINVAL)

View File

@ -0,0 +1,14 @@
b'ping'
b'ping'
b'\x81\x04pong'
b'pingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingping'
b'\x81~\x00\x80pongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpong'
b'\x00\x00\x00\x00'
b''
b'\x81\x02\x88\x00'
b'ping'
b'pong'
0
1
2
ioctl: EINVAL: True

View File

@ -1,2 +1,2 @@
# Check whether arbitrary-precision integers (MPZ) are supported
1000000000000000000000000000000000000000000000
print(1000000000000000000000000000000000000000000000)

View File

@ -0,0 +1 @@
1000000000000000000000000000000000000000000000

View File

@ -1,6 +1,11 @@
# test construction of array from array with float type
from array import array
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
print(array('f', array('h', [1, 2])))
print(array('d', array('f', [1, 2])))

View File

@ -1,4 +1,11 @@
# test builtin min and max functions with float args
try:
min
max
except:
import sys
print("SKIP")
sys.exit()
print(min(0,1.0))
print(min(1.0,0))

View File

@ -1,4 +1,9 @@
from array import array
try:
from array import array
except ImportError:
import sys
print("SKIP")
sys.exit()
def test(a):
print(a)

View File

@ -1,9 +1,13 @@
# test struct package with floats
try:
import ustruct as struct
except:
import struct
try:
import ustruct as struct
except:
import struct
except ImportError:
import sys
print("SKIP")
sys.exit()
i = 1. + 1/2
# TODO: it looks like '=' format modifier is not yet supported

View File

@ -1,4 +1,10 @@
import uio
try:
import uio
except ImportError:
import sys
print("SKIP")
sys.exit()
import micropython
data = b"1234" * 16

View File

@ -2,7 +2,12 @@
import micropython
import sys
import uio
try:
import uio
except ImportError:
import sys
print("SKIP")
sys.exit()
# preallocate exception instance with some room for a traceback
global_exc = StopIteration()

View File

@ -1,5 +1,5 @@
StopIteration
Traceback (most recent call last):
File , line 18, in test
File , line 23, in test
StopIteration:

View File

@ -14,5 +14,6 @@ exec('print(__debug__)')
exec('assert 0')
# check that level 3 doesn't store line numbers
# the expected output is that any line is printed as "line 1"
micropython.opt_level(3)
exec('try:\n xyz\nexcept NameError as er:\n import sys\n sys.print_exception(er)')

View File

@ -3,13 +3,19 @@
def test(code):
try:
exec(code)
except (SyntaxError, ViperTypeError) as e:
except (SyntaxError, ViperTypeError, NotImplementedError) as e:
print(repr(e))
# viper: annotations must be identifiers
test("@micropython.viper\ndef f(a:1): pass")
test("@micropython.viper\ndef f() -> 1: pass")
# unknown type
test("@micropython.viper\ndef f(x:unknown_type): pass")
# too many arguments
test("@micropython.viper\ndef f(a, b, c, d, e): pass")
# local used before type known
test("""
@micropython.viper
@ -49,6 +55,9 @@ test("@micropython.viper\ndef f(): 1[x]")
# can't store
test("@micropython.viper\ndef f(): 1[0] = 1")
test("@micropython.viper\ndef f(): 1[x] = 1")
test("@micropython.viper\ndef f(x:int): x[0] = x")
test("@micropython.viper\ndef f(x:ptr32): x[0] = None")
test("@micropython.viper\ndef f(x:ptr32): x[x] = None")
# must raise an object
test("@micropython.viper\ndef f(): raise 1")
@ -57,3 +66,16 @@ test("@micropython.viper\ndef f(): raise 1")
test("@micropython.viper\ndef f(x:int): +x")
test("@micropython.viper\ndef f(x:int): -x")
test("@micropython.viper\ndef f(x:int): ~x")
# binary op not implemented
test("@micropython.viper\ndef f(x:int): res = x in x")
# yield (from) not implemented
test("@micropython.viper\ndef f(): yield")
test("@micropython.viper\ndef f(): yield from f")
# passing a ptr to a Python function not implemented
test("@micropython.viper\ndef f(): print(ptr(1))")
# cast of a casting identifier not implemented
test("@micropython.viper\ndef f(): int(int)")

View File

@ -1,5 +1,7 @@
SyntaxError('parameter annotation must be an identifier',)
SyntaxError('return annotation must be an identifier',)
ViperTypeError("unknown type 'unknown_type'",)
ViperTypeError("Viper functions don't currently support more than 4 arguments",)
ViperTypeError("local 'x' used before type known",)
ViperTypeError("local 'x' has type 'int' but source is 'object'",)
ViperTypeError("can't implicitly convert 'ptr' to 'bool'",)
@ -9,7 +11,15 @@ ViperTypeError("can't load from 'int'",)
ViperTypeError("can't load from 'int'",)
ViperTypeError("can't store to 'int'",)
ViperTypeError("can't store to 'int'",)
ViperTypeError("can't store to 'int'",)
ViperTypeError("can't store 'None'",)
ViperTypeError("can't store 'None'",)
ViperTypeError('must raise an object',)
ViperTypeError('unary op __pos__ not implemented',)
ViperTypeError('unary op __neg__ not implemented',)
ViperTypeError('unary op __invert__ not implemented',)
ViperTypeError('binary op __contains__ not implemented',)
NotImplementedError('native yield',)
NotImplementedError('native yield from',)
NotImplementedError('conversion to object',)
NotImplementedError('casting',)

View File

@ -1,7 +1,12 @@
# tests for things that are not implemented, or have non-compliant behaviour
import array
import ustruct
try:
import array
import ustruct
except ImportError:
import sys
print("SKIP")
sys.exit()
# when super can't find self
try:

View File

@ -1,8 +1,13 @@
try:
import uio as io
except ImportError:
import io
import sys
try:
try:
import uio as io
except ImportError:
import io
except ImportError:
print("SKIP")
sys.exit()
if hasattr(sys, 'print_exception'):
print_exception = sys.print_exception
else:

View File

@ -1,5 +1,10 @@
# This tests that printing recursive data structure doesn't lead to segfault.
import uio as io
try:
import uio as io
except ImportError:
import sys
print("SKIP")
sys.exit()
l = [1, 2, 3, None]
l[-1] = l

View File

@ -1,4 +1,14 @@
# This tests that recursion with iternext doesn't lead to segfault.
try:
enumerate
filter
map
max
zip
except:
import sys
print("SKIP")
sys.exit()
# We need to pick an N that is large enough to hit the recursion
# limit, but not too large that we run out of heap memory.

View File

@ -209,7 +209,7 @@ def run_tests(pyb, tests, args):
# Check if arbitrary-precision integers are supported, and skip such tests if it's not
native = run_micropython(pyb, args, 'feature_check/int_big.py')
if native == b'CRASH':
if native != b'1000000000000000000000000000000000000000000000\n':
skip_int_big = True
# Check if set type (and set literals) is supported, and skip such tests if it's not
@ -261,7 +261,7 @@ def run_tests(pyb, tests, args):
if pyb is not None:
skip_tests.add('basics/exception_chain.py') # warning is not printed
skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead
skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work
skip_tests.add('float/float2int_doubleprec_intbig.py') # requires double precision floating point to work
skip_tests.add('micropython/meminfo.py') # output is very different to PC output
skip_tests.add('extmod/machine_mem.py') # raw memory access not supported

View File

@ -43,6 +43,9 @@ Warning: test
?
+1e+00
+1e+00
# binary
122
456
0123456789 b'0123456789'
7300
7300

View File

@ -10,6 +10,7 @@
#include "py/emit.h"
#include "py/formatfloat.h"
#include "py/stream.h"
#include "py/binary.h"
#if defined(MICROPY_UNIX_COVERAGE)
@ -278,6 +279,19 @@ STATIC mp_obj_t extra_coverage(void) {
mp_printf(&mp_plat_print, "%s\n", buf2);
}
// binary
{
mp_printf(&mp_plat_print, "# binary\n");
// call function with float and double typecodes
float far[1];
double dar[1];
mp_binary_set_val_array_from_int('f', far, 0, 123);
mp_printf(&mp_plat_print, "%.0f\n", (double)far[0]);
mp_binary_set_val_array_from_int('d', dar, 0, 456);
mp_printf(&mp_plat_print, "%.0lf\n", dar[0]);
}
mp_obj_streamtest_t *s = m_new_obj(mp_obj_streamtest_t);
s->base.type = &mp_type_stest_fileio;
s->buf = NULL;

View File

@ -90,19 +90,33 @@ STATIC int handle_uncaught_exception(mp_obj_base_t *exc) {
return 1;
}
#define LEX_SRC_STR (1)
#define LEX_SRC_VSTR (2)
#define LEX_SRC_FILENAME (3)
#define LEX_SRC_STDIN (4)
// Returns standard error codes: 0 for success, 1 for all other errors,
// except if FORCED_EXIT bit is set then script raised SystemExit and the
// value of the exit is in the lower 8 bits of the return value
STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
if (lex == NULL) {
printf("MemoryError: lexer could not allocate memory\n");
return 1;
}
STATIC int execute_from_lexer(int source_kind, const void *source, mp_parse_input_kind_t input_kind, bool is_repl) {
mp_hal_set_interrupt_char(CHAR_CTRL_C);
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// create lexer based on source kind
mp_lexer_t *lex;
if (source_kind == LEX_SRC_STR) {
const char *line = source;
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
} else if (source_kind == LEX_SRC_VSTR) {
const vstr_t *vstr = source;
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, false);
} else if (source_kind == LEX_SRC_FILENAME) {
lex = mp_lexer_new_from_file((const char*)source);
} else { // LEX_SRC_STDIN
lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false);
}
qstr source_name = lex->source_name;
#if MICROPY_PY___FILE__
@ -240,8 +254,7 @@ STATIC int do_repl(void) {
mp_hal_stdio_mode_orig();
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, false);
ret = execute_from_lexer(lex, parse_input_kind, true);
ret = execute_from_lexer(LEX_SRC_VSTR, &line, parse_input_kind, true);
if (ret & FORCED_EXIT) {
return ret;
}
@ -268,8 +281,7 @@ STATIC int do_repl(void) {
line = line3;
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
int ret = execute_from_lexer(lex, MP_PARSE_SINGLE_INPUT, true);
int ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true);
if (ret & FORCED_EXIT) {
return ret;
}
@ -280,13 +292,11 @@ STATIC int do_repl(void) {
}
STATIC int do_file(const char *file) {
mp_lexer_t *lex = mp_lexer_new_from_file(file);
return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
return execute_from_lexer(LEX_SRC_FILENAME, file, MP_PARSE_FILE_INPUT, false);
}
STATIC int do_str(const char *str) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, str, strlen(str), false);
return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
return execute_from_lexer(LEX_SRC_STR, str, MP_PARSE_FILE_INPUT, false);
}
STATIC int usage(char **argv) {
@ -585,8 +595,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
ret = do_repl();
prompt_write_history();
} else {
mp_lexer_t *lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false);
ret = execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
ret = execute_from_lexer(LEX_SRC_STDIN, NULL, MP_PARSE_FILE_INPUT, false);
}
}

View File

@ -5,17 +5,10 @@
# recursively Makefile.zephyr to build complete application binary
# using Zephyr build system.
#
# To build a "minimal" configuration, use "make-minimal" wrapper.
BOARD ?= qemu_x86
ifeq ($(MAKECMDGOALS), minimal)
# For minimal, CONF_FILE must be overriden early due to $(Z_EXPORTS) target
CONF_FILE = prj_minimal.conf
else
CONF_FILE = prj.conf
endif
# Zephyr 1.5.0
#OUTDIR_PREFIX =
# Zephyr 1.6.0
OUTDIR_PREFIX = $(BOARD)
# Default heap size is 16KB, which is on conservative side, to let
@ -42,6 +35,7 @@ INC += -I$(ZEPHYR_BASE)/net/ip/contiki/os
SRC_C = main.c \
help.c \
modutime.c \
modzephyr.c \
modmachine.c \
machine_pin.c \
uart_core.c \
@ -65,7 +59,7 @@ include ../py/mkrules.mk
$(Z_EXPORTS): $(CONF_FILE)
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=$(CONF_FILE) initconfig outputexports
GENERIC_TARGETS = all zephyr qemu qemugdb flash debug
GENERIC_TARGETS = all zephyr run qemu qemugdb flash debug
KCONFIG_TARGETS = \
initconfig config nconfig menuconfig xconfig gconfig \
oldconfig silentoldconfig defconfig savedefconfig \
@ -87,12 +81,6 @@ $(Z_SYSGEN_H):
rm -f $(LIBMICROPYTHON)
-$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=$(CONF_FILE)
minimal:
$(MAKE) BOARD=$(BOARD) CONF_FILE=prj_minimal.conf CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_minimal.h>"' FROZEN_DIR=
qemu-minimal:
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=prj_minimal.conf QEMU_NET=0 run
# Clean Zephyr things too
clean: z_clean
@ -101,5 +89,4 @@ z_clean:
.PHONY: prj.conf
prj.conf: prj_base.conf
cat $< >$@
if [ -f prj_$(BOARD).conf ]; then cat prj_$(BOARD).conf >>$@; fi
$(PYTHON) makeprj.py prj_base.conf prj_$(BOARD).conf $@

View File

@ -98,17 +98,17 @@ below 128KB, as long as Zephyr project is committed to maintain stable
minimal size of their kernel (which they appear to be). Note that at such
size, there is no support for any Zephyr features beyond REPL over UART,
and only very minimal set of builtin Python modules. Thus, this build
is more suitable for code size control and quick demonstrations even on
is more suitable for code size control and quick demonstrations on
smaller systems. It's also suitable for careful enabling of features one
by one to achieve needed functionality and code size. This is in contrast
to the "default" build, which may get more and more features enabled by
default over time.
by one to achieve needed functionality and code size. This is in a
contrast to the "default" build, which may get more and more features
enabled over time.
To make a minimal build:
make BOARD=<board> minimal
./make-minimal BOARD=<board>
To run a minimal build in QEMU without requiring TAP networking setup
run the following after you built image with the previous command:
make BOARD=<qemu_x86|qemu_cortex_m3> qemu-minimal
./make-minimal BOARD=<qemu_x86|qemu_cortex_m3> qemu

View File

@ -44,14 +44,9 @@
#include "lib/mp-readline/readline.h"
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
printf("MemoryError: lexer could not allocate memory\n");
return;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
@ -130,7 +125,7 @@ void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
mp_raise_OSError(ENOENT);
}
mp_import_stat_t mp_import_stat(const char *path) {
@ -142,10 +137,7 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void nlr_jump_fail(void *val) {
}
void NORETURN __fatal_error(const char *msg) {
NORETURN void nlr_jump_fail(void *val) {
while (1);
}

16
zephyr/make-minimal Executable file
View File

@ -0,0 +1,16 @@
#!/bin/sh
#
# This is a wrapper for make to build a "minimal" Zephyr port.
# It should be run just like make (i.e. extra vars can be passed on the
# command line, etc.), e.g.:
#
# ./make-minimal BOARD=qemu_cortex_m3
# ./make-minimal BOARD=qemu_cortex_m3 run
#
make \
CONF_FILE=prj_minimal.conf \
CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_minimal.h>"' \
FROZEN_DIR= \
QEMU_NET=0 \
"$@"

29
zephyr/makeprj.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
import sys
import os
import hashlib
def hash_file(fname):
if not os.path.exists(fname):
return b""
hasher = hashlib.md5()
with open(fname, "rb") as f:
hasher.update(f.read())
return hasher.digest()
old_digest = hash_file(sys.argv[3])
with open(sys.argv[3] + ".tmp", "wb") as f:
f.write(open(sys.argv[1], "rb").read())
if os.path.exists(sys.argv[2]):
f.write(open(sys.argv[2], "rb").read())
new_digest = hash_file(sys.argv[3] + ".tmp")
if new_digest != old_digest:
print("Replacing")
os.rename(sys.argv[3] + ".tmp", sys.argv[3])
else:
os.remove(sys.argv[3] + ".tmp")

51
zephyr/modzephyr.c Normal file
View File

@ -0,0 +1,51 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Linaro Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h"
#if MICROPY_PY_ZEPHYR
#include <zephyr.h>
#include "py/runtime.h"
STATIC mp_obj_t mod_is_preempt_thread(void) {
return mp_obj_new_bool(k_is_preempt_thread());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_is_preempt_thread_obj, mod_is_preempt_thread);
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_zephyr) },
{ MP_ROM_QSTR(MP_QSTR_is_preempt_thread), MP_ROM_PTR(&mod_is_preempt_thread_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
const mp_obj_module_t mp_module_zephyr = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_time_globals,
};
#endif // MICROPY_PY_ZEPHYR

View File

@ -60,6 +60,7 @@
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_UTIME (1)
#define MICROPY_PY_UTIME_MP_HAL (1)
#define MICROPY_PY_ZEPHYR (1)
#define MICROPY_PY_SYS_MODULES (0)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
@ -100,6 +101,7 @@ typedef long mp_off_t;
extern const struct _mp_obj_module_t mp_module_machine;
extern const struct _mp_obj_module_t mp_module_time;
extern const struct _mp_obj_module_t mp_module_zephyr;
#if MICROPY_PY_UTIME
#define MICROPY_PY_UTIME_DEF { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_time) },
@ -107,9 +109,16 @@ extern const struct _mp_obj_module_t mp_module_time;
#define MICROPY_PY_UTIME_DEF
#endif
#if MICROPY_PY_ZEPHYR
#define MICROPY_PY_ZEPHYR_DEF { MP_ROM_QSTR(MP_QSTR_zephyr), MP_ROM_PTR(&mp_module_zephyr) },
#else
#define MICROPY_PY_ZEPHYR_DEF
#endif
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \
MICROPY_PY_UTIME_DEF \
MICROPY_PY_ZEPHYR_DEF \
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_time) }, \