From cd94b384a39a2d7f3efa557ce0bda305d0aa3cc7 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 13 Apr 2014 23:41:49 +0300 Subject: [PATCH 1/6] objdict: Add __setitem__. --- py/builtin.h | 1 + py/objdict.c | 1 + py/opmethods.c | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/py/builtin.h b/py/builtin.h index 743f748da0..337524899a 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -37,6 +37,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); MP_DECLARE_CONST_FUN_OBJ(mp_op_contains_obj); MP_DECLARE_CONST_FUN_OBJ(mp_op_getitem_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_op_setitem_obj); extern const mp_obj_module_t mp_module___main__; extern const mp_obj_module_t mp_module_array; diff --git a/py/objdict.c b/py/objdict.c index 2c56540d15..1bebf08647 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -497,6 +497,7 @@ STATIC const mp_map_elem_t dict_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_update), (mp_obj_t)&dict_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_values), (mp_obj_t)&dict_values_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___getitem__), (mp_obj_t)&mp_op_getitem_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___setitem__), (mp_obj_t)&mp_op_setitem_obj }, }; STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); diff --git a/py/opmethods.c b/py/opmethods.c index af2524cf20..f0f19b6dfb 100644 --- a/py/opmethods.c +++ b/py/opmethods.c @@ -13,6 +13,12 @@ STATIC mp_obj_t op_getitem(mp_obj_t lhs_in, mp_obj_t rhs_in) { } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); +STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) { + mp_store_subscr(self_in, key_in, value_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); + STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_type_t *type = mp_obj_get_type(lhs_in); return type->binary_op(MP_BINARY_OP_IN, lhs_in, rhs_in); From 14de114ba811614ba6e058f6d864129f5c8b73bb Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 13 Apr 2014 23:55:59 +0300 Subject: [PATCH 2/6] objdict: Add __delitem__. --- py/builtin.h | 1 + py/objdict.c | 1 + py/opmethods.c | 6 ++++++ py/qstrdefs.h | 1 + 4 files changed, 9 insertions(+) diff --git a/py/builtin.h b/py/builtin.h index 337524899a..caca71b523 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -38,6 +38,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); MP_DECLARE_CONST_FUN_OBJ(mp_op_contains_obj); MP_DECLARE_CONST_FUN_OBJ(mp_op_getitem_obj); MP_DECLARE_CONST_FUN_OBJ(mp_op_setitem_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_op_delitem_obj); extern const mp_obj_module_t mp_module___main__; extern const mp_obj_module_t mp_module_array; diff --git a/py/objdict.c b/py/objdict.c index 1bebf08647..19d9ae9e9f 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -498,6 +498,7 @@ STATIC const mp_map_elem_t dict_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_values), (mp_obj_t)&dict_values_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___getitem__), (mp_obj_t)&mp_op_getitem_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___setitem__), (mp_obj_t)&mp_op_setitem_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___delitem__), (mp_obj_t)&mp_op_delitem_obj }, }; STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); diff --git a/py/opmethods.c b/py/opmethods.c index f0f19b6dfb..27415fef9b 100644 --- a/py/opmethods.c +++ b/py/opmethods.c @@ -19,6 +19,12 @@ STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) } MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); +STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) { + mp_store_subscr(self_in, key_in, MP_OBJ_NULL); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem); + STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_type_t *type = mp_obj_get_type(lhs_in); return type->binary_op(MP_BINARY_OP_IN, lhs_in, rhs_in); diff --git a/py/qstrdefs.h b/py/qstrdefs.h index df383b776c..c2d538d1f1 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -24,6 +24,7 @@ Q(__len__) Q(__iter__) Q(__getitem__) Q(__setitem__) +Q(__delitem__) Q(__add__) Q(__sub__) Q(__repr__) From 59e269cfec51b6a7933d6e847a38c84c04056675 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 14 Apr 2014 01:43:01 +0300 Subject: [PATCH 3/6] qstr, objstr: Make sure that valid hash != 0, treat 0 as "not computed". This feature was proposed with initial hashing RFC, and is prerequisite for seamless static str object definition. --- py/objstr.c | 3 ++- py/qstr.c | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/py/objstr.c b/py/objstr.c index d933fa5e34..0f9e4fdda4 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1463,7 +1463,8 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { } else { GET_STR_HASH(s1, h1); GET_STR_HASH(s2, h2); - if (h1 != h2) { + // If any of hashes is 0, it means it's not valid + if (h1 != 0 && h2 != 0 && h1 != h2) { return false; } GET_STR_DATA_LEN(s1, d1, l1); diff --git a/py/qstr.c b/py/qstr.c index e4b5c111b5..990ff37727 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -35,7 +35,12 @@ machine_uint_t qstr_compute_hash(const byte *data, uint len) { for (const byte *top = data + len; data < top; data++) { hash = ((hash << 5) + hash) ^ (*data); // hash * 33 ^ data } - return hash & 0xffff; + hash &= 0xffff; + // Make sure that valid hash is never zero, zero means "hash not computed" + if (hash == 0) { + hash++; + } + return hash; } typedef struct _qstr_pool_t { From 58676fc2c75b8dcf1661ee65eb2384bd7f59990b Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 14 Apr 2014 01:45:06 +0300 Subject: [PATCH 4/6] objstr: Allow to define statically allocated str objects. Similar to tuples, lists, dicts. Statically allocated strings don't have hash computed. --- py/objstr.c | 8 +------- py/objstr.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 py/objstr.h diff --git a/py/objstr.c b/py/objstr.c index 0f9e4fdda4..08db2af669 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -10,13 +10,7 @@ #include "runtime0.h" #include "runtime.h" #include "pfenv.h" - -typedef struct _mp_obj_str_t { - mp_obj_base_t base; - machine_uint_t hash : 16; // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c) - machine_uint_t len : 16; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte - const byte *data; -} mp_obj_str_t; +#include "objstr.h" STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, uint n_args, const mp_obj_t *args); const mp_obj_t mp_const_empty_bytes; diff --git a/py/objstr.h b/py/objstr.h new file mode 100644 index 0000000000..a32ba53b1d --- /dev/null +++ b/py/objstr.h @@ -0,0 +1,10 @@ +typedef struct _mp_obj_str_t { + mp_obj_base_t base; + // XXX here we assume the hash size is 16 bits (it is at the moment; see qstr.c) + machine_uint_t hash : 16; + // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte + machine_uint_t len : 16; + const byte *data; +} mp_obj_str_t; + +#define MP_DEFINE_STR_OBJ(obj_name, str) mp_obj_str_t obj_name = {{&mp_type_str}, 0, sizeof(str) - 1, (const byte*)str}; From bbae42d62fd671a4ce50bec280e0cb806469d1cc Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 14 Apr 2014 01:46:45 +0300 Subject: [PATCH 5/6] modsys: Implement sys.version. The logic appears to be that (at least beginning of) sys.versions is the version of reference Python language implemented, not version of particular implementation. Also, bump set versions at 3.4.0, based on @dpgeorge preference. --- py/modsys.c | 5 ++++- py/qstrdefs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/py/modsys.c b/py/modsys.c index 10efd6004d..41ade1f275 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -6,6 +6,7 @@ #include "runtime.h" #include "objlist.h" #include "objtuple.h" +#include "objstr.h" #if MICROPY_ENABLE_MOD_SYS @@ -20,13 +21,15 @@ mp_obj_list_t mp_sys_path_obj; mp_obj_list_t mp_sys_argv_obj; #define I(n) MP_OBJ_NEW_SMALL_INT(n) // TODO: CPython is now at 5-element array, but save 2 els so far... -STATIC const mp_obj_tuple_t mp_sys_version_info_obj = {{&mp_type_tuple}, 3, {I(3), I(3), I(5)}}; +STATIC const mp_obj_tuple_t mp_sys_version_info_obj = {{&mp_type_tuple}, 3, {I(3), I(4), I(0)}}; #undef I +STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0"); STATIC const mp_map_elem_t mp_module_sys_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) }, { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&version_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_version_info), (mp_obj_t)&mp_sys_version_info_obj }, #if MP_ENDIANNESS_LITTLE { MP_OBJ_NEW_QSTR(MP_QSTR_byteorder), MP_OBJ_NEW_QSTR(MP_QSTR_little) }, diff --git a/py/qstrdefs.h b/py/qstrdefs.h index c2d538d1f1..80cf681ae7 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -280,6 +280,7 @@ Q(little) Q(stdin) Q(stdout) Q(stderr) +Q(version) Q(version_info) #endif From 658eae308f6c6156b34718965954eb58034332a6 Mon Sep 17 00:00:00 2001 From: AZ Huang Date: Tue, 15 Apr 2014 01:47:14 +0800 Subject: [PATCH 6/6] Fix parallel build. --- py/mkrules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/mkrules.mk b/py/mkrules.mk index ab4514d1c4..08ba8fc416 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -59,7 +59,7 @@ $(BUILD)/%.pp: %.c # object directories (but only for existance), and the object directories # will be created if they don't exist. OBJ_DIRS = $(sort $(dir $(OBJ))) -$(OBJ): | $(OBJ_DIRS) +$(OBJ): $(PY_BUILD)/qstrdefs.generated.h | $(OBJ_DIRS) $(OBJ_DIRS): $(MKDIR) -p $@