Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
    }
}