mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_byte_t stream_next_byte, mp_lexer_stream_close_t stream_close) { mp_lexer_t *lex = m_new_obj_maybe(mp_lexer_t); // check for memory allocation error if (lex == NULL) { if (stream_close) { stream_close(stream_data); } return NULL; } lex->source_name = src_name; lex->stream_data = stream_data; lex->stream_next_byte = stream_next_byte; lex->stream_close = stream_close; lex->line = 1; lex->column = 1; lex->emit_dent = 0; 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); vstr_init(&lex->vstr, 32); // check for memory allocation error if (lex->indent_level == NULL || vstr_had_error(&lex->vstr)) { mp_lexer_free(lex); return NULL; } // store sentinel for first indentation level lex->indent_level[0] = 0; // preload characters lex->chr0 = stream_next_byte(stream_data); lex->chr1 = stream_next_byte(stream_data); lex->chr2 = stream_next_byte(stream_data); // if input stream is 0, 1 or 2 characters long and doesn't end in a newline, then insert a newline at the end if (lex->chr0 == MP_LEXER_EOF) { lex->chr0 = '\n'; } else if (lex->chr1 == MP_LEXER_EOF) { if (lex->chr0 == '\r') { lex->chr0 = '\n'; } else if (lex->chr0 != '\n') { lex->chr1 = '\n'; } } else if (lex->chr2 == MP_LEXER_EOF) { if (lex->chr1 == '\r') { lex->chr1 = '\n'; } else if (lex->chr1 != '\n') { lex->chr2 = '\n'; } } // preload first token mp_lexer_next_token_into(lex, true); return lex; }
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) { assert(fmt != NULL); // Check that the given type is an exception type assert(exc_type->make_new == mp_obj_exception_make_new); // Try to allocate memory for the message mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); size_t o_str_alloc = strlen(fmt) + 1; byte *o_str_buf = m_new_maybe(byte, o_str_alloc); bool used_emg_buf = false; #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF // If memory allocation failed and there is an emergency buffer then try to use // that buffer to store the string object and its data (at least 16 bytes for // the string data), reserving room at the start for the traceback and 1-tuple. if ((o_str == NULL || o_str_buf == NULL) && mp_emergency_exception_buf_size >= EMG_TRACEBACK_ALLOC * sizeof(size_t) + sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t) + sizeof(mp_obj_str_t) + 16) { used_emg_buf = true; o_str = (mp_obj_str_t*)((uint8_t*)MP_STATE_VM(mp_emergency_exception_buf) + EMG_TRACEBACK_ALLOC * sizeof(size_t) + sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t)); o_str_buf = (byte*)&o_str[1]; o_str_alloc = (uint8_t*)MP_STATE_VM(mp_emergency_exception_buf) + mp_emergency_exception_buf_size - o_str_buf; } #endif if (o_str == NULL) { // No memory for the string object so create the exception with no args return mp_obj_exception_make_new(exc_type, 0, 0, NULL); } if (o_str_buf == NULL) { // No memory for the string buffer: assume that the fmt string is in ROM // and use that data as the data of the string o_str->len = o_str_alloc - 1; // will be equal to strlen(fmt) o_str->data = (const byte*)fmt; } else { // We have some memory to format the string struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf}; mp_print_t print = {&exc_pr, exc_add_strn}; va_list ap; va_start(ap, fmt); mp_vprintf(&print, fmt, ap); va_end(ap); exc_pr.buf[exc_pr.len] = '\0'; o_str->len = exc_pr.len; o_str->data = exc_pr.buf; } // Create the string object and call mp_obj_exception_make_new to create the exception o_str->base.type = &mp_type_str; o_str->hash = qstr_compute_hash(o_str->data, o_str->len); mp_obj_t arg = MP_OBJ_FROM_PTR(o_str); return mp_obj_exception_make_new(exc_type, 1, 0, &arg); }
pb_context_t *irom_make_context(const esp_frozen_t *pp) { pb_context_t *ctx = m_new_obj_maybe(pb_context_t); if (ctx == NULL) { printf("ctx allocation failed\n"); return NULL; } ctx->pp = pp; ctx->base = mp_frozen_qwords + pp->offset; ctx->current_pos = 0; return ctx; }
mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) { mp_lexer_str_buf_t *sb = m_new_obj_maybe(mp_lexer_str_buf_t); if (sb == NULL) { return NULL; } sb->free_len = free_len; sb->src_beg = str; sb->src_cur = str; sb->src_end = str + len; return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_byte_t)str_buf_next_byte, (mp_lexer_stream_close_t)str_buf_free); }
mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); // Try to allocate memory for the exception, with fallback to emergency exception object mp_obj_exception_t *o_exc = m_new_obj_maybe(mp_obj_exception_t); if (o_exc == NULL) { o_exc = &MP_STATE_VM(mp_emergency_exception_obj); } // Populate the exception object o_exc->base.type = type; o_exc->traceback_data = NULL; mp_obj_tuple_t *o_tuple; if (n_args == 0) { // No args, can use the empty tuple straightaway o_tuple = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj; } else { // Try to allocate memory for the tuple containing the args o_tuple = m_new_obj_var_maybe(mp_obj_tuple_t, mp_obj_t, n_args); #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF // If we are called by mp_obj_new_exception_msg_varg then it will have // reserved room (after the traceback data) for a tuple with 1 element. // Otherwise we are free to use the whole buffer after the traceback data. if (o_tuple == NULL && mp_emergency_exception_buf_size >= EMG_TRACEBACK_ALLOC * sizeof(size_t) + sizeof(mp_obj_tuple_t) + n_args * sizeof(mp_obj_t)) { o_tuple = (mp_obj_tuple_t*) ((uint8_t*)MP_STATE_VM(mp_emergency_exception_buf) + EMG_TRACEBACK_ALLOC * sizeof(size_t)); } #endif if (o_tuple == NULL) { // No memory for a tuple, fallback to an empty tuple o_tuple = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj; } else { // Have memory for a tuple so populate it o_tuple->base.type = &mp_type_tuple; o_tuple->len = n_args; memcpy(o_tuple->items, args, n_args * sizeof(mp_obj_t)); } } // Store the tuple of args in the exception object o_exc->args = o_tuple; return MP_OBJ_FROM_PTR(o_exc); }
mp_lexer_t *mp_lexer_new_from_file(const char *filename) { mp_lexer_file_buf_t *fb = m_new_obj_maybe(mp_lexer_file_buf_t); if (fb == NULL) { return NULL; } FRESULT res = f_open(&fb->fp, filename, FA_READ); if (res != FR_OK) { m_del_obj(mp_lexer_file_buf_t, fb); return NULL; } UINT n; f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); fb->len = n; fb->pos = 0; return mp_lexer_new(qstr_from_str(filename), fb, (mp_lexer_stream_next_byte_t)file_buf_next_byte, (mp_lexer_stream_close_t)file_buf_close); }
STATIC void mptask_init_sflash_filesystem (void) { FILINFO fno; // Initialise the local flash filesystem. // init the vfs object fs_user_mount_t *vfs_fat = sflash_vfs_fat; vfs_fat->flags = 0; pyb_flash_init_vfs(vfs_fat); // Create it if needed, and mount in on /flash. FRESULT res = f_mount(&vfs_fat->fatfs); if (res == FR_NO_FILESYSTEM) { // no filesystem, so create a fresh one uint8_t working_buf[FF_MAX_SS]; res = f_mkfs(&vfs_fat->fatfs, FM_FAT | FM_SFD, 0, working_buf, sizeof(working_buf)); if (res == FR_OK) { // success creating fresh LFS } else { __fatal_error("failed to create /flash"); } // create empty main.py mptask_create_main_py(); } else if (res == FR_OK) { // mount sucessful if (FR_OK != f_stat(&vfs_fat->fatfs, "/main.py", &fno)) { // create empty main.py 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) // 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); vfs->next = NULL; MP_STATE_VM(vfs_mount_table) = vfs; // The current directory is used as the boot up directory. // It is set to the internal flash filesystem by default. MP_STATE_PORT(vfs_cur) = vfs; // create /flash/sys, /flash/lib and /flash/cert if they don't exist if (FR_OK != f_chdir(&vfs_fat->fatfs, "/sys")) { f_mkdir(&vfs_fat->fatfs, "/sys"); } if (FR_OK != f_chdir(&vfs_fat->fatfs, "/lib")) { f_mkdir(&vfs_fat->fatfs, "/lib"); } if (FR_OK != f_chdir(&vfs_fat->fatfs, "/cert")) { f_mkdir(&vfs_fat->fatfs, "/cert"); } f_chdir(&vfs_fat->fatfs, "/"); // make sure we have a /flash/boot.py. Create it if needed. res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno); if (res == FR_OK) { if (fno.fattrib & AM_DIR) { // exists as a directory // TODO handle this case // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation } else { // exists as a file, good! } } else { // doesn't exist, create fresh file FIL fp; f_open(&vfs_fat->fatfs, &fp, "/boot.py", FA_WRITE | FA_CREATE_ALWAYS); UINT n; f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n); // TODO check we could write n bytes f_close(&fp); } }