Skip to content

Commit 82560fc

Browse files
committed
2 parents 0a1dbfe + b294a7e commit 82560fc

16 files changed

+240
-209
lines changed

py/bc.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ typedef struct _mp_code_state {
5151

5252
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);
5353
mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_obj_t inject_exc);
54-
void mp_bytecode_print(const byte *code, int len);
54+
void mp_bytecode_print(const void *descr, const byte *code, int len);
5555
void mp_bytecode_print2(const byte *code, int len);
5656

5757
// Helper macros to access pointer with least significant bit holding a flag

py/builtintables.c

+2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = {
172172
#endif
173173

174174
#if MICROPY_PY_BUILTINS_FLOAT
175+
#if MICROPY_PY_MATH
175176
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math },
177+
#endif
176178
#if MICROPY_PY_CMATH
177179
{ MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath },
178180
#endif

py/emitbc.c

+4
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,10 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, int delta) {
352352
STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) {
353353
//printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset);
354354
#if MICROPY_ENABLE_SOURCE_LINE
355+
if (mp_optimise_value >= 3) {
356+
// If we compile with -O3, don't store line numbers.
357+
return;
358+
}
355359
if (source_line > emit->last_source_line) {
356360
uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
357361
uint lines_to_skip = source_line - emit->last_source_line;

py/emitglue.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint
7171
DEBUG_printf(" %s", qstr_str(arg_names[i]));
7272
}
7373
DEBUG_printf("\n");
74-
for (int i = 0; i < 128 && i < len; i++) {
75-
if (i > 0 && i % 16 == 0) {
76-
DEBUG_printf("\n");
77-
}
78-
DEBUG_printf(" %02x", code[i]);
79-
}
80-
DEBUG_printf("\n");
8174
#endif
8275
#if MICROPY_DEBUG_PRINTERS
8376
if (mp_verbose_flag > 0) {
84-
mp_bytecode_print(code, len);
77+
for (int i = 0; i < 128 && i < len; i++) {
78+
if (i > 0 && i % 16 == 0) {
79+
printf("\n");
80+
}
81+
printf(" %02x", code[i]);
82+
}
83+
printf("\n");
84+
mp_bytecode_print(rc, code, len);
8585
}
8686
#endif
8787
}

py/lexer.c

+2-7
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,7 @@ struct _mp_lexer_t {
6464
mp_token_t tok_cur;
6565
};
6666

67-
// debug flag for __debug__ constant
68-
STATIC mp_token_kind_t mp_debug_value;
69-
70-
void mp_set_debug(bool value) {
71-
mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE;
72-
}
67+
uint mp_optimise_value;
7368

7469
// TODO replace with a call to a standard function
7570
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
703698
if (str_strn_equal(tok_kw[i], tok->str, tok->len)) {
704699
if (i == ARRAY_SIZE(tok_kw) - 1) {
705700
// tok_kw[ARRAY_SIZE(tok_kw) - 1] == "__debug__"
706-
tok->kind = mp_debug_value;
701+
tok->kind = (mp_optimise_value == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE);
707702
} else {
708703
tok->kind = MP_TOKEN_KW_FALSE + i;
709704
}

py/lexer.h

+2
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,5 @@ typedef enum {
176176

177177
mp_import_stat_t mp_import_stat(const char *path);
178178
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
179+
180+
extern uint mp_optimise_value;

py/objdict.c

+52-53
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
STATIC mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur);
4242
STATIC mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in);
43-
STATIC mp_obj_t dict_copy(mp_obj_t self_in);
43+
STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs);
4444

4545
STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
4646
mp_obj_dict_t *self = self_in;
@@ -61,40 +61,13 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
6161
}
6262

6363
STATIC mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
64-
mp_obj_t dict;
65-
switch (n_args) {
66-
case 0:
67-
dict = mp_obj_new_dict(0);
68-
break;
69-
70-
case 1: {
71-
if (MP_OBJ_IS_TYPE(args[0], &mp_type_dict)) {
72-
return dict_copy(args[0]);
73-
}
74-
// TODO create dict from an arbitrary mapping!
75-
76-
// Make dict from iterable of pairs
77-
mp_obj_t iterable = mp_getiter(args[0]);
78-
mp_obj_t dict = mp_obj_new_dict(0);
79-
// TODO: support arbitrary seq as a pair
80-
mp_obj_t item;
81-
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
82-
mp_obj_t *sub_items;
83-
mp_obj_get_array_fixed_n(item, 2, &sub_items);
84-
mp_obj_dict_store(dict, sub_items[0], sub_items[1]);
85-
}
86-
return dict;
87-
}
88-
89-
default:
90-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "dict takes at most 1 argument"));
91-
}
92-
93-
// add to the new dict any keyword args
94-
for (const mp_obj_t *a = args + n_args; n_kw > 0; n_kw--, a += 2) {
95-
mp_obj_dict_store(dict, a[0], a[1]);
64+
mp_obj_t dict = mp_obj_new_dict(0);
65+
if (n_args > 0 || n_kw > 0) {
66+
mp_obj_t args2[2] = {dict, args[0]}; // args[0] is always valid, even if it's not a positional arg
67+
mp_map_t kwargs;
68+
mp_map_init_fixed_table(&kwargs, n_kw, args + n_args);
69+
dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2
9670
}
97-
9871
return dict;
9972
}
10073

@@ -348,31 +321,57 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
348321
}
349322
STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem);
350323

351-
STATIC mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) {
352-
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict));
353-
mp_obj_dict_t *self = self_in;
354-
/* TODO: check for the "keys" method */
355-
mp_obj_t iter = mp_getiter(iterable);
356-
mp_obj_t next = NULL;
357-
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
358-
mp_obj_t inneriter = mp_getiter(next);
359-
mp_obj_t key = mp_iternext(inneriter);
360-
mp_obj_t value = mp_iternext(inneriter);
361-
mp_obj_t stop = mp_iternext(inneriter);
362-
if (key == MP_OBJ_STOP_ITERATION
363-
|| value == MP_OBJ_STOP_ITERATION
364-
|| stop != MP_OBJ_STOP_ITERATION) {
365-
nlr_raise(mp_obj_new_exception_msg(
366-
&mp_type_ValueError,
367-
"dictionary update sequence has the wrong length"));
324+
STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
325+
assert(MP_OBJ_IS_TYPE(args[0], &mp_type_dict));
326+
mp_obj_dict_t *self = args[0];
327+
328+
mp_arg_check_num(n_args, kwargs->used, 1, 2, true);
329+
330+
if (n_args == 2) {
331+
// given a positional argument
332+
333+
if (MP_OBJ_IS_TYPE(args[1], &mp_type_dict)) {
334+
// update from other dictionary (make sure other is not self)
335+
if (args[1] != self) {
336+
// TODO don't allocate heap object for this iterator
337+
mp_obj_t *dict_iter = mp_obj_new_dict_iterator(args[1], 0);
338+
mp_map_elem_t *elem = NULL;
339+
while ((elem = dict_it_iternext_elem(dict_iter)) != MP_OBJ_STOP_ITERATION) {
340+
mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value;
341+
}
342+
}
368343
} else {
369-
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
344+
// update from a generic iterable of pairs
345+
mp_obj_t iter = mp_getiter(args[1]);
346+
mp_obj_t next = NULL;
347+
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
348+
mp_obj_t inneriter = mp_getiter(next);
349+
mp_obj_t key = mp_iternext(inneriter);
350+
mp_obj_t value = mp_iternext(inneriter);
351+
mp_obj_t stop = mp_iternext(inneriter);
352+
if (key == MP_OBJ_STOP_ITERATION
353+
|| value == MP_OBJ_STOP_ITERATION
354+
|| stop != MP_OBJ_STOP_ITERATION) {
355+
nlr_raise(mp_obj_new_exception_msg(
356+
&mp_type_ValueError,
357+
"dictionary update sequence has the wrong length"));
358+
} else {
359+
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
360+
}
361+
}
362+
}
363+
}
364+
365+
// update the dict with any keyword args
366+
for (machine_uint_t i = 0; i < kwargs->alloc; i++) {
367+
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
368+
mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value;
370369
}
371370
}
372371

373372
return mp_const_none;
374373
}
375-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(dict_update_obj, dict_update);
374+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dict_update_obj, 1, dict_update);
376375

377376

378377
/******************************************************************************/

py/objtype.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ STATIC mp_obj_t instance_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp
516516
mp_obj_t member[2] = {MP_OBJ_NULL};
517517
mp_obj_class_lookup(self, self->base.type, MP_QSTR___call__, offsetof(mp_obj_type_t, call), member);
518518
if (member[0] == MP_OBJ_NULL) {
519-
return MP_OBJ_NULL;
519+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in)));
520520
}
521521
if (member[0] == MP_OBJ_SENTINEL) {
522522
return mp_call_function_n_kw(self->subobj[0], n_args, n_kw, args);

py/runtime.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "bc.h"
4646
#include "smallint.h"
4747
#include "objgenerator.h"
48+
#include "lexer.h"
4849

4950
#if 0 // print debugging info
5051
#define DEBUG_PRINT (1)
@@ -74,8 +75,8 @@ void mp_init(void) {
7475
MICROPY_PORT_INIT_FUNC;
7576
#endif
7677

77-
// __debug__ enabled by default
78-
mp_set_debug(true);
78+
// optimization disabled by default
79+
mp_optimise_value = 0;
7980

8081
// init global module stuff
8182
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
525526

526527
// do the call
527528
if (type->call != NULL) {
528-
mp_obj_t res = type->call(fun_in, n_args, n_kw, args);
529-
if (res != NULL) {
530-
return res;
531-
}
529+
return type->call(fun_in, n_args, n_kw, args);
532530
}
533531

534532
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in)));

py/runtime.h

-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ typedef struct _mp_arg_t {
5454
void mp_init(void);
5555
void mp_deinit(void);
5656

57-
void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c
58-
5957
void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw);
6058
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);
6159
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);

py/showbc.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
void mp_bytecode_print2(const byte *ip, int len);
5858

59-
void mp_bytecode_print(const byte *ip, int len) {
59+
void mp_bytecode_print(const void *descr, const byte *ip, int len) {
6060
const byte *ip_start = ip;
6161

6262
// get code info size
@@ -66,7 +66,8 @@ void mp_bytecode_print(const byte *ip, int len) {
6666

6767
qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24);
6868
qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24);
69-
printf("File %s, code block '%s' (%d bytes)\n", qstr_str(source_file), qstr_str(block_name), len);
69+
printf("File %s, code block '%s' (descriptor: %p, bytecode @%p %d bytes)\n",
70+
qstr_str(source_file), qstr_str(block_name), descr, code_info, len);
7071

7172
// bytecode prelude: state size and exception stack size; 16 bit uints
7273
{
@@ -434,25 +435,25 @@ void mp_bytecode_print2(const byte *ip, int len) {
434435

435436
case MP_BC_MAKE_FUNCTION:
436437
DECODE_PTR;
437-
printf("MAKE_FUNCTION " UINT_FMT, unum);
438+
printf("MAKE_FUNCTION %p", (void*)unum);
438439
break;
439440

440441
case MP_BC_MAKE_FUNCTION_DEFARGS:
441442
DECODE_PTR;
442-
printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum);
443+
printf("MAKE_FUNCTION_DEFARGS %p", (void*)unum);
443444
break;
444445

445446
case MP_BC_MAKE_CLOSURE: {
446447
DECODE_PTR;
447448
machine_uint_t n_closed_over = *ip++;
448-
printf("MAKE_CLOSURE " UINT_FMT " " UINT_FMT, unum, n_closed_over);
449+
printf("MAKE_CLOSURE %p " UINT_FMT, (void*)unum, n_closed_over);
449450
break;
450451
}
451452

452453
case MP_BC_MAKE_CLOSURE_DEFARGS: {
453454
DECODE_PTR;
454455
machine_uint_t n_closed_over = *ip++;
455-
printf("MAKE_CLOSURE_DEFARGS " UINT_FMT " " UINT_FMT, unum, n_closed_over);
456+
printf("MAKE_CLOSURE_DEFARGS %p " UINT_FMT, (void*)unum, n_closed_over);
456457
break;
457458
}
458459

py/vm.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -1042,12 +1042,16 @@ mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_
10421042
machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24);
10431043
qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24);
10441044
qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24);
1045-
machine_uint_t source_line = 1;
1045+
machine_uint_t source_line = 0;
10461046
machine_uint_t bc = code_state->ip - code_info - code_info_size;
10471047
//printf("find %lu %d %d\n", bc, code_info[12], code_info[13]);
1048-
for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) {
1049-
bc -= *ci & 31;
1050-
source_line += *ci >> 5;
1048+
const byte* ci = code_info + 12;
1049+
if (*ci) {
1050+
source_line = 1;
1051+
for (; *ci && bc >= ((*ci) & 31); ci++) {
1052+
bc -= *ci & 31;
1053+
source_line += *ci >> 5;
1054+
}
10511055
}
10521056
mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name);
10531057
}

0 commit comments

Comments
 (0)