py: Pretend frozen files are stored under .frozen rather than the empty path.

This makes it clear when frozen modules are loaded as opposed to the empty path
which represents the current working directory. Furthermore, by splitting the two
apart this allows one to control in what order frozen modules are loaded.

This is a prerequisite for #56.
This commit is contained in:
Scott Shawcroft 2017-08-10 15:46:17 -07:00
parent 5c32a5aa6a
commit f6a702538a
5 changed files with 27 additions and 21 deletions

View File

@ -57,9 +57,11 @@ bool mp_obj_is_package(mp_obj_t module) {
// (whatever is available, if at all).
STATIC mp_import_stat_t mp_import_stat_any(const char *path) {
#if MICROPY_MODULE_FROZEN
mp_import_stat_t st = mp_frozen_stat(path);
if (st != MP_IMPORT_STAT_NO_EXIST) {
return st;
if (strlen(path) > 8 && strncmp(".frozen/", path, 8) == 0) {
mp_import_stat_t st = mp_frozen_stat(path + 8);
if (st != MP_IMPORT_STAT_NO_EXIST) {
return st;
}
}
#endif
return mp_import_stat(path);

View File

@ -44,13 +44,13 @@ extern const uint32_t mp_frozen_str_sizes[];
extern const char mp_frozen_str_content[];
// On input, *len contains size of name, on output - size of content
const char *mp_find_frozen_str(const char *str, size_t *len) {
const char *mp_find_frozen_str(const char *str, size_t str_len, size_t *len) {
const char *name = mp_frozen_str_names;
size_t offset = 0;
for (int i = 0; *name != 0; i++) {
size_t l = strlen(name);
if (l == *len && !memcmp(str, name, l)) {
if (l == str_len && !memcmp(str, name, l)) {
*len = mp_frozen_str_sizes[i];
return mp_frozen_str_content + offset;
}
@ -60,16 +60,16 @@ const char *mp_find_frozen_str(const char *str, size_t *len) {
return NULL;
}
STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) {
size_t name_len = len;
const char *content = mp_find_frozen_str(str, &len);
STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t str_len) {
size_t file_len;
const char *content = mp_find_frozen_str(str, str_len, &file_len);
if (content == NULL) {
return NULL;
}
qstr source = qstr_from_strn(str, name_len);
mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, len, 0);
qstr source = qstr_from_strn(str, str_len);
mp_lexer_t *lex = MICROPY_MODULE_FROZEN_LEXER(source, content, file_len, 0);
return lex;
}
@ -82,11 +82,11 @@ STATIC mp_lexer_t *mp_lexer_frozen_str(const char *str, size_t len) {
extern const char mp_frozen_mpy_names[];
extern const mp_raw_code_t *const mp_frozen_mpy_content[];
STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t len) {
STATIC const mp_raw_code_t *mp_find_frozen_mpy(const char *str, size_t str_len) {
const char *name = mp_frozen_mpy_names;
for (size_t i = 0; *name != 0; i++) {
size_t l = strlen(name);
if (l == len && !memcmp(str, name, l)) {
if (l == str_len && !memcmp(str, name, l)) {
return mp_frozen_mpy_content[i];
}
name += l + 1;
@ -136,15 +136,16 @@ mp_import_stat_t mp_frozen_stat(const char *str) {
}
int mp_find_frozen_module(const char *str, size_t len, void **data) {
// The +8/-8 account for the .frozen/ path prefix used on frozen modules.
#if MICROPY_MODULE_FROZEN_STR
mp_lexer_t *lex = mp_lexer_frozen_str(str, len);
mp_lexer_t *lex = mp_lexer_frozen_str(str + 8, len - 8);
if (lex != NULL) {
*data = lex;
return MP_FROZEN_STR;
}
#endif
#if MICROPY_MODULE_FROZEN_MPY
const mp_raw_code_t *rc = mp_find_frozen_mpy(str, len);
const mp_raw_code_t *rc = mp_find_frozen_mpy(str + 8, len - 8);
if (rc != NULL) {
*data = (void*)rc;
return MP_FROZEN_MPY;

View File

@ -33,5 +33,5 @@ enum {
};
int mp_find_frozen_module(const char *str, size_t len, void **data);
const char *mp_find_frozen_str(const char *str, size_t *len);
const char *mp_find_frozen_str(const char *str, size_t str_len, size_t *len);
mp_import_stat_t mp_frozen_stat(const char *str);

View File

@ -164,14 +164,14 @@ STATIC mp_obj_t resource_stream(mp_obj_t package_in, mp_obj_t path_in) {
const char *path = mp_obj_str_get_data(path_in, &len);
vstr_add_strn(&path_buf, path, len);
len = path_buf.len;
const char *data = mp_find_frozen_str(path_buf.buf, &len);
size_t file_len;
const char *data = mp_find_frozen_str(path_buf.buf, path_buf.len, &file_len);
if (data != NULL) {
mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t);
o->base.type = &mp_type_bytesio;
o->vstr = m_new_obj(vstr_t);
vstr_init_fixed_buf(o->vstr, len + 1, (char*)data);
o->vstr->len = len;
vstr_init_fixed_buf(o->vstr, file_len + 1, (char*)data);
o->vstr->len = file_len;
o->pos = 0;
return MP_OBJ_FROM_PTR(o);
}

View File

@ -453,7 +453,9 @@ MP_NOINLINE int main_(int argc, char **argv) {
path = "~/.micropython/lib:/usr/lib/micropython";
#endif
}
size_t path_num = 1; // [0] is for current dir (or base dir of the script)
size_t path_num = 2; // [0] is for current dir (or base dir of the script)
// [1] is for frozen files.
size_t builtin_path_count = path_num;
if (*path == ':') {
path_num++;
}
@ -467,9 +469,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
mp_obj_t *path_items;
mp_obj_list_get(mp_sys_path, &path_num, &path_items);
path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_);
path_items[1] = MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen);
{
char *p = path;
for (mp_uint_t i = 1; i < path_num; i++) {
for (mp_uint_t i = builtin_path_count; i < path_num; i++) {
char *p1 = strchr(p, PATHLIST_SEP_CHAR);
if (p1 == NULL) {
p1 = p + strlen(p);