diff options
author | bvernoux <bvernoux@gmail.com> | 2014-06-03 19:26:34 +0200 |
---|---|---|
committer | bvernoux <bvernoux@gmail.com> | 2014-06-03 19:26:34 +0200 |
commit | 82560fce75ab0307182c943d564202e55fca6c09 (patch) | |
tree | d20162c8647ddb2451fdb76024761821b43149e8 /py | |
parent | 0a1dbfe02f4a693c202b97aafcf0b5d0ba050812 (diff) | |
parent | b294a7e3c9b84aad6c331128a51e0d69e7845141 (diff) | |
download | micropython-82560fce75ab0307182c943d564202e55fca6c09.tar.gz micropython-82560fce75ab0307182c943d564202e55fca6c09.zip |
Merge branch 'master' of https://github.com/micropython/micropython
Diffstat (limited to 'py')
-rw-r--r-- | py/bc.h | 2 | ||||
-rw-r--r-- | py/builtintables.c | 2 | ||||
-rw-r--r-- | py/emitbc.c | 4 | ||||
-rw-r--r-- | py/emitglue.c | 16 | ||||
-rw-r--r-- | py/lexer.c | 9 | ||||
-rw-r--r-- | py/lexer.h | 2 | ||||
-rw-r--r-- | py/objdict.c | 105 | ||||
-rw-r--r-- | py/objtype.c | 2 | ||||
-rw-r--r-- | py/runtime.c | 10 | ||||
-rw-r--r-- | py/runtime.h | 2 | ||||
-rw-r--r-- | py/showbc.c | 13 | ||||
-rw-r--r-- | py/vm.c | 12 |
12 files changed, 91 insertions, 88 deletions
@@ -51,7 +51,7 @@ typedef struct _mp_code_state { mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret); mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_obj_t inject_exc); -void mp_bytecode_print(const byte *code, int len); +void mp_bytecode_print(const void *descr, const byte *code, int len); void mp_bytecode_print2(const byte *code, int len); // Helper macros to access pointer with least significant bit holding a flag diff --git a/py/builtintables.c b/py/builtintables.c index 628514da1c..1041c2598c 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -172,7 +172,9 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { #endif #if MICROPY_PY_BUILTINS_FLOAT +#if MICROPY_PY_MATH { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math }, +#endif #if MICROPY_PY_CMATH { MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath }, #endif diff --git a/py/emitbc.c b/py/emitbc.c index cfaea7c88a..841dd4aabb 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -352,6 +352,10 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, int delta) { STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) { //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset); #if MICROPY_ENABLE_SOURCE_LINE + if (mp_optimise_value >= 3) { + // If we compile with -O3, don't store line numbers. + return; + } if (source_line > emit->last_source_line) { uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset; uint lines_to_skip = source_line - emit->last_source_line; diff --git a/py/emitglue.c b/py/emitglue.c index 528c3bd36c..a89ef6766a 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -71,17 +71,17 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint DEBUG_printf(" %s", qstr_str(arg_names[i])); } DEBUG_printf("\n"); - for (int i = 0; i < 128 && i < len; i++) { - if (i > 0 && i % 16 == 0) { - DEBUG_printf("\n"); - } - DEBUG_printf(" %02x", code[i]); - } - DEBUG_printf("\n"); #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag > 0) { - mp_bytecode_print(code, len); + for (int i = 0; i < 128 && i < len; i++) { + if (i > 0 && i % 16 == 0) { + printf("\n"); + } + printf(" %02x", code[i]); + } + printf("\n"); + mp_bytecode_print(rc, code, len); } #endif } diff --git a/py/lexer.c b/py/lexer.c index 4a7ac071b4..26993922eb 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -64,12 +64,7 @@ struct _mp_lexer_t { mp_token_t tok_cur; }; -// debug flag for __debug__ constant -STATIC mp_token_kind_t mp_debug_value; - -void mp_set_debug(bool value) { - mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE; -} +uint mp_optimise_value; // TODO replace with a call to a standard function bool str_strn_equal(const char *str, const char *strn, int len) { @@ -703,7 +698,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { if (i == ARRAY_SIZE(tok_kw) - 1) { // tok_kw[ARRAY_SIZE(tok_kw) - 1] == "__debug__" - tok->kind = mp_debug_value; + tok->kind = (mp_optimise_value == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE); } else { tok->kind = MP_TOKEN_KW_FALSE + i; } diff --git a/py/lexer.h b/py/lexer.h index b302cb2db1..24cae1e252 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -176,3 +176,5 @@ typedef enum { mp_import_stat_t mp_import_stat(const char *path); mp_lexer_t *mp_lexer_new_from_file(const char *filename); + +extern uint mp_optimise_value; diff --git a/py/objdict.c b/py/objdict.c index f41eacd939..8a0a08772a 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -40,7 +40,7 @@ STATIC mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur); STATIC mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in); -STATIC mp_obj_t dict_copy(mp_obj_t self_in); +STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs); STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_dict_t *self = self_in; @@ -61,40 +61,13 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env } STATIC mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - mp_obj_t dict; - switch (n_args) { - case 0: - dict = mp_obj_new_dict(0); - break; - - case 1: { - if (MP_OBJ_IS_TYPE(args[0], &mp_type_dict)) { - return dict_copy(args[0]); - } - // TODO create dict from an arbitrary mapping! - - // Make dict from iterable of pairs - mp_obj_t iterable = mp_getiter(args[0]); - mp_obj_t dict = mp_obj_new_dict(0); - // TODO: support arbitrary seq as a pair - mp_obj_t item; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - mp_obj_t *sub_items; - mp_obj_get_array_fixed_n(item, 2, &sub_items); - mp_obj_dict_store(dict, sub_items[0], sub_items[1]); - } - return dict; - } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "dict takes at most 1 argument")); - } - - // add to the new dict any keyword args - for (const mp_obj_t *a = args + n_args; n_kw > 0; n_kw--, a += 2) { - mp_obj_dict_store(dict, a[0], a[1]); + mp_obj_t dict = mp_obj_new_dict(0); + if (n_args > 0 || n_kw > 0) { + mp_obj_t args2[2] = {dict, args[0]}; // args[0] is always valid, even if it's not a positional arg + mp_map_t kwargs; + mp_map_init_fixed_table(&kwargs, n_kw, args + n_args); + dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2 } - return dict; } @@ -348,31 +321,57 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem); -STATIC mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict)); - mp_obj_dict_t *self = self_in; - /* TODO: check for the "keys" method */ - mp_obj_t iter = mp_getiter(iterable); - mp_obj_t next = NULL; - while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { - mp_obj_t inneriter = mp_getiter(next); - mp_obj_t key = mp_iternext(inneriter); - mp_obj_t value = mp_iternext(inneriter); - mp_obj_t stop = mp_iternext(inneriter); - if (key == MP_OBJ_STOP_ITERATION - || value == MP_OBJ_STOP_ITERATION - || stop != MP_OBJ_STOP_ITERATION) { - nlr_raise(mp_obj_new_exception_msg( - &mp_type_ValueError, - "dictionary update sequence has the wrong length")); +STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) { + assert(MP_OBJ_IS_TYPE(args[0], &mp_type_dict)); + mp_obj_dict_t *self = args[0]; + + mp_arg_check_num(n_args, kwargs->used, 1, 2, true); + + if (n_args == 2) { + // given a positional argument + + if (MP_OBJ_IS_TYPE(args[1], &mp_type_dict)) { + // update from other dictionary (make sure other is not self) + if (args[1] != self) { + // TODO don't allocate heap object for this iterator + mp_obj_t *dict_iter = mp_obj_new_dict_iterator(args[1], 0); + mp_map_elem_t *elem = NULL; + while ((elem = dict_it_iternext_elem(dict_iter)) != MP_OBJ_STOP_ITERATION) { + mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value; + } + } } else { - mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; + // update from a generic iterable of pairs + mp_obj_t iter = mp_getiter(args[1]); + mp_obj_t next = NULL; + while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { + mp_obj_t inneriter = mp_getiter(next); + mp_obj_t key = mp_iternext(inneriter); + mp_obj_t value = mp_iternext(inneriter); + mp_obj_t stop = mp_iternext(inneriter); + if (key == MP_OBJ_STOP_ITERATION + || value == MP_OBJ_STOP_ITERATION + || stop != MP_OBJ_STOP_ITERATION) { + nlr_raise(mp_obj_new_exception_msg( + &mp_type_ValueError, + "dictionary update sequence has the wrong length")); + } else { + mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; + } + } + } + } + + // update the dict with any keyword args + for (machine_uint_t i = 0; i < kwargs->alloc; i++) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(dict_update_obj, dict_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dict_update_obj, 1, dict_update); /******************************************************************************/ diff --git a/py/objtype.c b/py/objtype.c index ebbb6097dd..a51e12f1fd 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -516,7 +516,7 @@ STATIC mp_obj_t instance_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp mp_obj_t member[2] = {MP_OBJ_NULL}; mp_obj_class_lookup(self, self->base.type, MP_QSTR___call__, offsetof(mp_obj_type_t, call), member); if (member[0] == MP_OBJ_NULL) { - return MP_OBJ_NULL; + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); } if (member[0] == MP_OBJ_SENTINEL) { return mp_call_function_n_kw(self->subobj[0], n_args, n_kw, args); diff --git a/py/runtime.c b/py/runtime.c index ecaf40deb4..f13cc1d892 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -45,6 +45,7 @@ #include "bc.h" #include "smallint.h" #include "objgenerator.h" +#include "lexer.h" #if 0 // print debugging info #define DEBUG_PRINT (1) @@ -74,8 +75,8 @@ void mp_init(void) { MICROPY_PORT_INIT_FUNC; #endif - // __debug__ enabled by default - mp_set_debug(true); + // optimization disabled by default + mp_optimise_value = 0; // init global module stuff mp_module_init(); @@ -525,10 +526,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, uint n_args, uint n_kw, const mp // do the call if (type->call != NULL) { - mp_obj_t res = type->call(fun_in, n_args, n_kw, args); - if (res != NULL) { - return res; - } + return type->call(fun_in, n_args, n_kw, args); } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); diff --git a/py/runtime.h b/py/runtime.h index 3c79b48ed0..dbd413180b 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -54,8 +54,6 @@ typedef struct _mp_arg_t { void mp_init(void); void mp_deinit(void); -void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c - void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw); void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); diff --git a/py/showbc.c b/py/showbc.c index 8169368410..5a4e918cd5 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -56,7 +56,7 @@ void mp_bytecode_print2(const byte *ip, int len); -void mp_bytecode_print(const byte *ip, int len) { +void mp_bytecode_print(const void *descr, const byte *ip, int len) { const byte *ip_start = ip; // get code info size @@ -66,7 +66,8 @@ void mp_bytecode_print(const byte *ip, int len) { qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); - printf("File %s, code block '%s' (%d bytes)\n", qstr_str(source_file), qstr_str(block_name), len); + printf("File %s, code block '%s' (descriptor: %p, bytecode @%p %d bytes)\n", + qstr_str(source_file), qstr_str(block_name), descr, code_info, len); // bytecode prelude: state size and exception stack size; 16 bit uints { @@ -434,25 +435,25 @@ void mp_bytecode_print2(const byte *ip, int len) { case MP_BC_MAKE_FUNCTION: DECODE_PTR; - printf("MAKE_FUNCTION " UINT_FMT, unum); + printf("MAKE_FUNCTION %p", (void*)unum); break; case MP_BC_MAKE_FUNCTION_DEFARGS: DECODE_PTR; - printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum); + printf("MAKE_FUNCTION_DEFARGS %p", (void*)unum); break; case MP_BC_MAKE_CLOSURE: { DECODE_PTR; machine_uint_t n_closed_over = *ip++; - printf("MAKE_CLOSURE " UINT_FMT " " UINT_FMT, unum, n_closed_over); + printf("MAKE_CLOSURE %p " UINT_FMT, (void*)unum, n_closed_over); break; } case MP_BC_MAKE_CLOSURE_DEFARGS: { DECODE_PTR; machine_uint_t n_closed_over = *ip++; - printf("MAKE_CLOSURE_DEFARGS " UINT_FMT " " UINT_FMT, unum, n_closed_over); + printf("MAKE_CLOSURE_DEFARGS %p " UINT_FMT, (void*)unum, n_closed_over); break; } @@ -1042,12 +1042,16 @@ exception_handler: machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24); qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); - machine_uint_t source_line = 1; + machine_uint_t source_line = 0; machine_uint_t bc = code_state->ip - code_info - code_info_size; //printf("find %lu %d %d\n", bc, code_info[12], code_info[13]); - for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) { - bc -= *ci & 31; - source_line += *ci >> 5; + const byte* ci = code_info + 12; + if (*ci) { + source_line = 1; + for (; *ci && bc >= ((*ci) & 31); ci++) { + bc -= *ci & 31; + source_line += *ci >> 5; + } } mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name); } |