Numworks Epsilon  1.4.1
Graphing Calculator Operating System
runtime.c
Go to the documentation of this file.
1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2013, 2014 Damien P. George
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <assert.h>
30 
31 #include "py/parsenum.h"
32 #include "py/compile.h"
33 #include "py/objstr.h"
34 #include "py/objtuple.h"
35 #include "py/objlist.h"
36 #include "py/objmodule.h"
37 #include "py/objgenerator.h"
38 #include "py/smallint.h"
39 #include "py/runtime.h"
40 #include "py/builtin.h"
41 #include "py/stackctrl.h"
42 #include "py/gc.h"
43 
44 #if MICROPY_DEBUG_VERBOSE // print debugging info
45 #define DEBUG_PRINT (1)
46 #define DEBUG_printf DEBUG_printf
47 #define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__)
48 #else // don't print debugging info
49 #define DEBUG_printf(...) (void)0
50 #define DEBUG_OP_printf(...) (void)0
51 #endif
52 
54  .base = { &mp_type_module },
55  .globals = (mp_obj_dict_t*)&MP_STATE_VM(dict_main),
56 };
57 
58 void mp_init(void) {
59  qstr_init();
60 
61  // no pending exceptions to start with
62  MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
63  #if MICROPY_ENABLE_SCHEDULER
64  MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
65  MP_STATE_VM(sched_sp) = 0;
66  #endif
67 
68 #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
70 #endif
71 
72  #if MICROPY_KBD_EXCEPTION
73  // initialise the exception object for raising KeyboardInterrupt
74  MP_STATE_VM(mp_kbd_exception).base.type = &mp_type_KeyboardInterrupt;
75  MP_STATE_VM(mp_kbd_exception).traceback_alloc = 0;
76  MP_STATE_VM(mp_kbd_exception).traceback_len = 0;
77  MP_STATE_VM(mp_kbd_exception).traceback_data = NULL;
78  MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
79  #endif
80 
81  // call port specific initialization if any
82 #ifdef MICROPY_PORT_INIT_FUNC
83  MICROPY_PORT_INIT_FUNC;
84 #endif
85 
86  // optimization disabled by default
87  MP_STATE_VM(mp_optimise_value) = 0;
88 
89  // init global module dict
90  mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), 3);
91 
92  // initialise the __main__ module
93  mp_obj_dict_init(&MP_STATE_VM(dict_main), 1);
94  mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(dict_main)), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
95 
96  // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
97  mp_locals_set(&MP_STATE_VM(dict_main));
98  mp_globals_set(&MP_STATE_VM(dict_main));
99 
100  #if MICROPY_CAN_OVERRIDE_BUILTINS
101  // start with no extensions to builtins
102  MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
103  #endif
104 
105  #if MICROPY_PY_OS_DUPTERM
106  for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) {
107  MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL;
108  }
109  MP_STATE_VM(dupterm_arr_obj) = MP_OBJ_NULL;
110  #endif
111 
112  #if MICROPY_FSUSERMOUNT
113  // zero out the pointers to the user-mounted devices
114  memset(MP_STATE_VM(fs_user_mount), 0, sizeof(MP_STATE_VM(fs_user_mount)));
115  #endif
116 
117  #if MICROPY_VFS
118  // initialise the VFS sub-system
119  MP_STATE_VM(vfs_cur) = NULL;
120  MP_STATE_VM(vfs_mount_table) = NULL;
121  #endif
122 
123  #if MICROPY_PY_THREAD_GIL
124  mp_thread_mutex_init(&MP_STATE_VM(gil_mutex));
125  #endif
126 
128 }
129 
130 void mp_deinit(void) {
131  //mp_obj_dict_free(&dict_main);
132  //mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map));
133 
134  // call port specific deinitialization if any
135 #ifdef MICROPY_PORT_INIT_FUNC
136  MICROPY_PORT_DEINIT_FUNC;
137 #endif
138 }
139 
141  // logic: search locals, globals, builtins
142  DEBUG_OP_printf("load name %s\n", qstr_str(qst));
143  // If we're at the outer scope (locals == globals), dispatch to load_global right away
144  if (mp_locals_get() != mp_globals_get()) {
145  mp_map_elem_t *elem = mp_map_lookup(&mp_locals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
146  if (elem != NULL) {
147  return elem->value;
148  }
149  }
150  return mp_load_global(qst);
151 }
152 
154  // logic: search globals, builtins
155  DEBUG_OP_printf("load global %s\n", qstr_str(qst));
156  mp_map_elem_t *elem = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
157  if (elem == NULL) {
158  #if MICROPY_CAN_OVERRIDE_BUILTINS
159  if (MP_STATE_VM(mp_module_builtins_override_dict) != NULL) {
160  // lookup in additional dynamic table of builtins first
161  elem = mp_map_lookup(&MP_STATE_VM(mp_module_builtins_override_dict)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
162  if (elem != NULL) {
163  return elem->value;
164  }
165  }
166  #endif
168  if (elem == NULL) {
170  mp_raise_msg(&mp_type_NameError, "name not defined");
171  } else {
173  "name '%q' is not defined", qst));
174  }
175  }
176  }
177  return elem->value;
178 }
179 
181  DEBUG_OP_printf("load_build_class\n");
182  #if MICROPY_CAN_OVERRIDE_BUILTINS
183  if (MP_STATE_VM(mp_module_builtins_override_dict) != NULL) {
184  // lookup in additional dynamic table of builtins first
185  mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_VM(mp_module_builtins_override_dict)->map, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP);
186  if (elem != NULL) {
187  return elem->value;
188  }
189  }
190  #endif
191  return MP_OBJ_FROM_PTR(&mp_builtin___build_class___obj);
192 }
193 
194 void mp_store_name(qstr qst, mp_obj_t obj) {
195  DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qst), obj);
196  mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst), obj);
197 }
198 
199 void mp_delete_name(qstr qst) {
200  DEBUG_OP_printf("delete name %s\n", qstr_str(qst));
201  // TODO convert KeyError to NameError if qst not found
202  mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst));
203 }
204 
205 void mp_store_global(qstr qst, mp_obj_t obj) {
206  DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qst), obj);
207  mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst), obj);
208 }
209 
211  DEBUG_OP_printf("delete global %s\n", qstr_str(qst));
212  // TODO convert KeyError to NameError if qst not found
213  mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst));
214 }
215 
217  DEBUG_OP_printf("unary " UINT_FMT " %p\n", op, arg);
218 
219  if (op == MP_UNARY_OP_NOT) {
220  // "not x" is the negative of whether "x" is true per Python semantics
221  return mp_obj_new_bool(mp_obj_is_true(arg) == 0);
222  } else if (MP_OBJ_IS_SMALL_INT(arg)) {
223  mp_int_t val = MP_OBJ_SMALL_INT_VALUE(arg);
224  switch (op) {
225  case MP_UNARY_OP_BOOL:
226  return mp_obj_new_bool(val != 0);
227  case MP_UNARY_OP_HASH:
228  return arg;
230  return arg;
232  // check for overflow
233  if (val == MP_SMALL_INT_MIN) {
234  return mp_obj_new_int(-val);
235  } else {
236  return MP_OBJ_NEW_SMALL_INT(-val);
237  }
238  case MP_UNARY_OP_ABS:
239  if (val >= 0) {
240  return arg;
241  } else if (val == MP_SMALL_INT_MIN) {
242  // check for overflow
243  return mp_obj_new_int(-val);
244  } else {
245  return MP_OBJ_NEW_SMALL_INT(-val);
246  }
247  default:
248  assert(op == MP_UNARY_OP_INVERT);
249  return MP_OBJ_NEW_SMALL_INT(~val);
250  }
251  } else if (op == MP_UNARY_OP_HASH && MP_OBJ_IS_STR_OR_BYTES(arg)) {
252  // fast path for hashing str/bytes
253  GET_STR_HASH(arg, h);
254  if (h == 0) {
255  GET_STR_DATA_LEN(arg, data, len);
256  h = qstr_compute_hash(data, len);
257  }
258  return MP_OBJ_NEW_SMALL_INT(h);
259  } else {
260  mp_obj_type_t *type = mp_obj_get_type(arg);
261  if (type->unary_op != NULL) {
262  mp_obj_t result = type->unary_op(op, arg);
263  if (result != MP_OBJ_NULL) {
264  return result;
265  }
266  }
268  mp_raise_TypeError("unsupported type for operator");
269  } else {
271  "unsupported type for %q: '%s'",
273  }
274  }
275 }
276 
278  DEBUG_OP_printf("binary " UINT_FMT " %p %p\n", op, lhs, rhs);
279 
280  // TODO correctly distinguish inplace operators for mutable objects
281  // lookup logic that CPython uses for +=:
282  // check for implemented +=
283  // then check for implemented +
284  // then check for implemented seq.inplace_concat
285  // then check for implemented seq.concat
286  // then fail
287  // note that list does not implement + or +=, so that inplace_concat is reached first for +=
288 
289  // deal with is
290  if (op == MP_BINARY_OP_IS) {
291  return mp_obj_new_bool(lhs == rhs);
292  }
293 
294  // deal with == and != for all types
295  if (op == MP_BINARY_OP_EQUAL || op == MP_BINARY_OP_NOT_EQUAL) {
296  if (mp_obj_equal(lhs, rhs)) {
297  if (op == MP_BINARY_OP_EQUAL) {
298  return mp_const_true;
299  } else {
300  return mp_const_false;
301  }
302  } else {
303  if (op == MP_BINARY_OP_EQUAL) {
304  return mp_const_false;
305  } else {
306  return mp_const_true;
307  }
308  }
309  }
310 
311  // deal with exception_match for all types
312  if (op == MP_BINARY_OP_EXCEPTION_MATCH) {
313  // rhs must be issubclass(rhs, BaseException)
314  if (mp_obj_is_exception_type(rhs)) {
315  if (mp_obj_exception_match(lhs, rhs)) {
316  return mp_const_true;
317  } else {
318  return mp_const_false;
319  }
320  } else if (MP_OBJ_IS_TYPE(rhs, &mp_type_tuple)) {
321  mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(rhs);
322  for (size_t i = 0; i < tuple->len; i++) {
323  rhs = tuple->items[i];
324  if (!mp_obj_is_exception_type(rhs)) {
325  goto unsupported_op;
326  }
327  if (mp_obj_exception_match(lhs, rhs)) {
328  return mp_const_true;
329  }
330  }
331  return mp_const_false;
332  }
333  goto unsupported_op;
334  }
335 
336  if (MP_OBJ_IS_SMALL_INT(lhs)) {
337  mp_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
338  if (MP_OBJ_IS_SMALL_INT(rhs)) {
339  mp_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
340  // This is a binary operation: lhs_val op rhs_val
341  // We need to be careful to handle overflow; see CERT INT32-C
342  // Operations that can overflow:
343  // + result always fits in mp_int_t, then handled by SMALL_INT check
344  // - result always fits in mp_int_t, then handled by SMALL_INT check
345  // * checked explicitly
346  // / if lhs=MIN and rhs=-1; result always fits in mp_int_t, then handled by SMALL_INT check
347  // % if lhs=MIN and rhs=-1; result always fits in mp_int_t, then handled by SMALL_INT check
348  // << checked explicitly
349  switch (op) {
350  case MP_BINARY_OP_OR:
351  case MP_BINARY_OP_INPLACE_OR: lhs_val |= rhs_val; break;
352  case MP_BINARY_OP_XOR:
353  case MP_BINARY_OP_INPLACE_XOR: lhs_val ^= rhs_val; break;
354  case MP_BINARY_OP_AND:
355  case MP_BINARY_OP_INPLACE_AND: lhs_val &= rhs_val; break;
356  case MP_BINARY_OP_LSHIFT:
358  if (rhs_val < 0) {
359  // negative shift not allowed
360  mp_raise_ValueError("negative shift count");
361  } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
362  // left-shift will overflow, so use higher precision integer
363  lhs = mp_obj_new_int_from_ll(lhs_val);
364  goto generic_binary_op;
365  } else {
366  // use standard precision
367  lhs_val <<= rhs_val;
368  }
369  break;
370  }
371  case MP_BINARY_OP_RSHIFT:
373  if (rhs_val < 0) {
374  // negative shift not allowed
375  mp_raise_ValueError("negative shift count");
376  } else {
377  // standard precision is enough for right-shift
378  if (rhs_val >= (mp_int_t)BITS_PER_WORD) {
379  // Shifting to big amounts is underfined behavior
380  // in C and is CPU-dependent; propagate sign bit.
381  rhs_val = BITS_PER_WORD - 1;
382  }
383  lhs_val >>= rhs_val;
384  }
385  break;
386  case MP_BINARY_OP_ADD:
387  case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
389  case MP_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break;
392 
393  // If long long type exists and is larger than mp_int_t, then
394  // we can use the following code to perform overflow-checked multiplication.
395  // Otherwise (eg in x64 case) we must use mp_small_int_mul_overflow.
396  #if 0
397  // compute result using long long precision
398  long long res = (long long)lhs_val * (long long)rhs_val;
399  if (res > MP_SMALL_INT_MAX || res < MP_SMALL_INT_MIN) {
400  // result overflowed SMALL_INT, so return higher precision integer
401  return mp_obj_new_int_from_ll(res);
402  } else {
403  // use standard precision
404  lhs_val = (mp_int_t)res;
405  }
406  #endif
407 
408  if (mp_small_int_mul_overflow(lhs_val, rhs_val)) {
409  // use higher precision
410  lhs = mp_obj_new_int_from_ll(lhs_val);
411  goto generic_binary_op;
412  } else {
413  // use standard precision
414  return MP_OBJ_NEW_SMALL_INT(lhs_val * rhs_val);
415  }
416  break;
417  }
420  if (rhs_val == 0) {
421  goto zero_division;
422  }
423  lhs_val = mp_small_int_floor_divide(lhs_val, rhs_val);
424  break;
425 
426  #if MICROPY_PY_BUILTINS_FLOAT
429  if (rhs_val == 0) {
430  goto zero_division;
431  }
432  return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val);
433  #endif
434 
435  case MP_BINARY_OP_MODULO:
437  if (rhs_val == 0) {
438  goto zero_division;
439  }
440  lhs_val = mp_small_int_modulo(lhs_val, rhs_val);
441  break;
442  }
443 
444  case MP_BINARY_OP_POWER:
446  if (rhs_val < 0) {
447  #if MICROPY_PY_BUILTINS_FLOAT
448  lhs = mp_obj_new_float(lhs_val);
449  goto generic_binary_op;
450  #else
451  mp_raise_ValueError("negative power with no float support");
452  #endif
453  } else {
454  mp_int_t ans = 1;
455  while (rhs_val > 0) {
456  if (rhs_val & 1) {
457  if (mp_small_int_mul_overflow(ans, lhs_val)) {
458  goto power_overflow;
459  }
460  ans *= lhs_val;
461  }
462  if (rhs_val == 1) {
463  break;
464  }
465  rhs_val /= 2;
466  if (mp_small_int_mul_overflow(lhs_val, lhs_val)) {
467  goto power_overflow;
468  }
469  lhs_val *= lhs_val;
470  }
471  lhs_val = ans;
472  }
473  break;
474 
475  power_overflow:
476  // use higher precision
478  goto generic_binary_op;
479 
480  case MP_BINARY_OP_DIVMOD: {
481  if (rhs_val == 0) {
482  goto zero_division;
483  }
484  // to reduce stack usage we don't pass a temp array of the 2 items
486  tuple->items[0] = MP_OBJ_NEW_SMALL_INT(mp_small_int_floor_divide(lhs_val, rhs_val));
487  tuple->items[1] = MP_OBJ_NEW_SMALL_INT(mp_small_int_modulo(lhs_val, rhs_val));
488  return MP_OBJ_FROM_PTR(tuple);
489  }
490 
491  case MP_BINARY_OP_LESS: return mp_obj_new_bool(lhs_val < rhs_val); break;
492  case MP_BINARY_OP_MORE: return mp_obj_new_bool(lhs_val > rhs_val); break;
493  case MP_BINARY_OP_LESS_EQUAL: return mp_obj_new_bool(lhs_val <= rhs_val); break;
494  case MP_BINARY_OP_MORE_EQUAL: return mp_obj_new_bool(lhs_val >= rhs_val); break;
495 
496  default:
497  goto unsupported_op;
498  }
499  // TODO: We just should make mp_obj_new_int() inline and use that
500  if (MP_SMALL_INT_FITS(lhs_val)) {
501  return MP_OBJ_NEW_SMALL_INT(lhs_val);
502  } else {
503  return mp_obj_new_int(lhs_val);
504  }
505 #if MICROPY_PY_BUILTINS_FLOAT
506  } else if (mp_obj_is_float(rhs)) {
507  mp_obj_t res = mp_obj_float_binary_op(op, lhs_val, rhs);
508  if (res == MP_OBJ_NULL) {
509  goto unsupported_op;
510  } else {
511  return res;
512  }
513 #if MICROPY_PY_BUILTINS_COMPLEX
514  } else if (MP_OBJ_IS_TYPE(rhs, &mp_type_complex)) {
515  mp_obj_t res = mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
516  if (res == MP_OBJ_NULL) {
517  goto unsupported_op;
518  } else {
519  return res;
520  }
521 #endif
522 #endif
523  }
524  }
525 
526  /* deal with `in`
527  *
528  * NOTE `a in b` is `b.__contains__(a)`, hence why the generic dispatch
529  * needs to go below with swapped arguments
530  */
531  if (op == MP_BINARY_OP_IN) {
532  mp_obj_type_t *type = mp_obj_get_type(rhs);
533  if (type->binary_op != NULL) {
534  mp_obj_t res = type->binary_op(op, rhs, lhs);
535  if (res != MP_OBJ_NULL) {
536  return res;
537  }
538  }
539  if (type->getiter != NULL) {
540  /* second attempt, walk the iterator */
541  mp_obj_iter_buf_t iter_buf;
542  mp_obj_t iter = mp_getiter(rhs, &iter_buf);
543  mp_obj_t next;
544  while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
545  if (mp_obj_equal(next, lhs)) {
546  return mp_const_true;
547  }
548  }
549  return mp_const_false;
550  }
551 
553  mp_raise_TypeError("object not iterable");
554  } else {
556  "'%s' object is not iterable", mp_obj_get_type_str(rhs)));
557  }
558  }
559 
560  // generic binary_op supplied by type
561  mp_obj_type_t *type;
562 generic_binary_op:
563  type = mp_obj_get_type(lhs);
564  if (type->binary_op != NULL) {
565  mp_obj_t result = type->binary_op(op, lhs, rhs);
566  if (result != MP_OBJ_NULL) {
567  return result;
568  }
569  }
570 
571 #if MICROPY_PY_REVERSE_SPECIAL_METHODS
572  if (op >= MP_BINARY_OP_OR && op <= MP_BINARY_OP_REVERSE_POWER) {
573  mp_obj_t t = rhs;
574  rhs = lhs;
575  lhs = t;
576  if (op <= MP_BINARY_OP_POWER) {
577  op += MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
578  goto generic_binary_op;
579  }
580 
581  // Convert __rop__ back to __op__ for error message
582  op -= MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
583  }
584 #endif
585 
586 unsupported_op:
588  mp_raise_TypeError("unsupported type for operator");
589  } else {
591  "unsupported types for %q: '%s', '%s'",
593  }
594 
595 zero_division:
596  mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
597 }
598 
600  return mp_call_function_n_kw(fun, 0, 0, NULL);
601 }
602 
604  return mp_call_function_n_kw(fun, 1, 0, &arg);
605 }
606 
608  mp_obj_t args[2];
609  args[0] = arg1;
610  args[1] = arg2;
611  return mp_call_function_n_kw(fun, 2, 0, args);
612 }
613 
614 // args contains, eg: arg0 arg1 key0 value0 key1 value1
615 mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
616  // TODO improve this: fun object can specify its type and we parse here the arguments,
617  // passing to the function arrays of fixed and keyword arguments
618 
619  DEBUG_OP_printf("calling function %p(n_args=" UINT_FMT ", n_kw=" UINT_FMT ", args=%p)\n", fun_in, n_args, n_kw, args);
620 
621  // get the type
622  mp_obj_type_t *type = mp_obj_get_type(fun_in);
623 
624  // do the call
625  if (type->call != NULL) {
626  return type->call(fun_in, n_args, n_kw, args);
627  }
628 
630  mp_raise_TypeError("object not callable");
631  } else {
633  "'%s' object is not callable", mp_obj_get_type_str(fun_in)));
634  }
635 }
636 
637 // args contains: fun self/NULL arg(0) ... arg(n_args-2) arg(n_args-1) kw_key(0) kw_val(0) ... kw_key(n_kw-1) kw_val(n_kw-1)
638 // if n_args==0 and n_kw==0 then there are only fun and self/NULL
639 mp_obj_t mp_call_method_n_kw(size_t n_args, size_t n_kw, const mp_obj_t *args) {
640  DEBUG_OP_printf("call method (fun=%p, self=%p, n_args=" UINT_FMT ", n_kw=" UINT_FMT ", args=%p)\n", args[0], args[1], n_args, n_kw, args);
641  int adjust = (args[1] == MP_OBJ_NULL) ? 0 : 1;
642  return mp_call_function_n_kw(args[0], n_args + adjust, n_kw, args + 2 - adjust);
643 }
644 
645 // This function only needs to be exposed externally when in stackless mode.
646 #if !MICROPY_STACKLESS
647 STATIC
648 #endif
649 void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args) {
650  mp_obj_t fun = *args++;
651  mp_obj_t self = MP_OBJ_NULL;
652  if (have_self) {
653  self = *args++; // may be MP_OBJ_NULL
654  }
655  uint n_args = n_args_n_kw & 0xff;
656  uint n_kw = (n_args_n_kw >> 8) & 0xff;
657  mp_obj_t pos_seq = args[n_args + 2 * n_kw]; // may be MP_OBJ_NULL
658  mp_obj_t kw_dict = args[n_args + 2 * n_kw + 1]; // may be MP_OBJ_NULL
659 
660  DEBUG_OP_printf("call method var (fun=%p, self=%p, n_args=%u, n_kw=%u, args=%p, seq=%p, dict=%p)\n", fun, self, n_args, n_kw, args, pos_seq, kw_dict);
661 
662  // We need to create the following array of objects:
663  // args[0 .. n_args] unpacked(pos_seq) args[n_args .. n_args + 2 * n_kw] unpacked(kw_dict)
664  // TODO: optimize one day to avoid constructing new arg array? Will be hard.
665 
666  // The new args array
667  mp_obj_t *args2;
668  uint args2_alloc;
669  uint args2_len = 0;
670 
671  // Try to get a hint for the size of the kw_dict
672  uint kw_dict_len = 0;
673  if (kw_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) {
674  kw_dict_len = mp_obj_dict_len(kw_dict);
675  }
676 
677  // Extract the pos_seq sequence to the new args array.
678  // Note that it can be arbitrary iterator.
679  if (pos_seq == MP_OBJ_NULL) {
680  // no sequence
681 
682  // allocate memory for the new array of args
683  args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len);
684  args2 = m_new(mp_obj_t, args2_alloc);
685 
686  // copy the self
687  if (self != MP_OBJ_NULL) {
688  args2[args2_len++] = self;
689  }
690 
691  // copy the fixed pos args
692  mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t);
693  args2_len += n_args;
694 
695  } else if (MP_OBJ_IS_TYPE(pos_seq, &mp_type_tuple) || MP_OBJ_IS_TYPE(pos_seq, &mp_type_list)) {
696  // optimise the case of a tuple and list
697 
698  // get the items
699  size_t len;
700  mp_obj_t *items;
701  mp_obj_get_array(pos_seq, &len, &items);
702 
703  // allocate memory for the new array of args
704  args2_alloc = 1 + n_args + len + 2 * (n_kw + kw_dict_len);
705  args2 = m_new(mp_obj_t, args2_alloc);
706 
707  // copy the self
708  if (self != MP_OBJ_NULL) {
709  args2[args2_len++] = self;
710  }
711 
712  // copy the fixed and variable position args
713  mp_seq_cat(args2 + args2_len, args, n_args, items, len, mp_obj_t);
714  args2_len += n_args + len;
715 
716  } else {
717  // generic iterator
718 
719  // allocate memory for the new array of args
720  args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len) + 3;
721  args2 = m_new(mp_obj_t, args2_alloc);
722 
723  // copy the self
724  if (self != MP_OBJ_NULL) {
725  args2[args2_len++] = self;
726  }
727 
728  // copy the fixed position args
729  mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t);
730  args2_len += n_args;
731 
732  // extract the variable position args from the iterator
733  mp_obj_iter_buf_t iter_buf;
734  mp_obj_t iterable = mp_getiter(pos_seq, &iter_buf);
735  mp_obj_t item;
736  while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
737  if (args2_len >= args2_alloc) {
738  args2 = m_renew(mp_obj_t, args2, args2_alloc, args2_alloc * 2);
739  args2_alloc *= 2;
740  }
741  args2[args2_len++] = item;
742  }
743  }
744 
745  // The size of the args2 array now is the number of positional args.
746  uint pos_args_len = args2_len;
747 
748  // Copy the fixed kw args.
749  mp_seq_copy(args2 + args2_len, args + n_args, 2 * n_kw, mp_obj_t);
750  args2_len += 2 * n_kw;
751 
752  // Extract (key,value) pairs from kw_dict dictionary and append to args2.
753  // Note that it can be arbitrary iterator.
754  if (kw_dict == MP_OBJ_NULL) {
755  // pass
756  } else if (MP_OBJ_IS_TYPE(kw_dict, &mp_type_dict)) {
757  // dictionary
758  mp_map_t *map = mp_obj_dict_get_map(kw_dict);
759  assert(args2_len + 2 * map->used <= args2_alloc); // should have enough, since kw_dict_len is in this case hinted correctly above
760  for (size_t i = 0; i < map->alloc; i++) {
761  if (MP_MAP_SLOT_IS_FILLED(map, i)) {
762  // the key must be a qstr, so intern it if it's a string
763  mp_obj_t key = map->table[i].key;
764  if (MP_OBJ_IS_TYPE(key, &mp_type_str)) {
765  key = mp_obj_str_intern(key);
766  }
767  args2[args2_len++] = key;
768  args2[args2_len++] = map->table[i].value;
769  }
770  }
771  } else {
772  // generic mapping:
773  // - call keys() to get an iterable of all keys in the mapping
774  // - call __getitem__ for each key to get the corresponding value
775 
776  // get the keys iterable
777  mp_obj_t dest[3];
778  mp_load_method(kw_dict, MP_QSTR_keys, dest);
779  mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), NULL);
780 
781  mp_obj_t key;
782  while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
783  // expand size of args array if needed
784  if (args2_len + 1 >= args2_alloc) {
785  uint new_alloc = args2_alloc * 2;
786  if (new_alloc < 4) {
787  new_alloc = 4;
788  }
789  args2 = m_renew(mp_obj_t, args2, args2_alloc, new_alloc);
790  args2_alloc = new_alloc;
791  }
792 
793  // the key must be a qstr, so intern it if it's a string
794  if (MP_OBJ_IS_TYPE(key, &mp_type_str)) {
795  key = mp_obj_str_intern(key);
796  }
797 
798  // get the value corresponding to the key
799  mp_load_method(kw_dict, MP_QSTR___getitem__, dest);
800  dest[2] = key;
801  mp_obj_t value = mp_call_method_n_kw(1, 0, dest);
802 
803  // store the key/value pair in the argument array
804  args2[args2_len++] = key;
805  args2[args2_len++] = value;
806  }
807  }
808 
809  out_args->fun = fun;
810  out_args->args = args2;
811  out_args->n_args = pos_args_len;
812  out_args->n_kw = (args2_len - pos_args_len) / 2;
813  out_args->n_alloc = args2_alloc;
814 }
815 
816 mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args) {
817  mp_call_args_t out_args;
818  mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args);
819 
820  mp_obj_t res = mp_call_function_n_kw(out_args.fun, out_args.n_args, out_args.n_kw, out_args.args);
821  m_del(mp_obj_t, out_args.args, out_args.n_alloc);
822 
823  return res;
824 }
825 
826 // unpacked items are stored in reverse order into the array pointed to by items
827 void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) {
828  size_t seq_len;
829  if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) {
830  mp_obj_t *seq_items;
831  mp_obj_get_array(seq_in, &seq_len, &seq_items);
832  if (seq_len < num) {
833  goto too_short;
834  } else if (seq_len > num) {
835  goto too_long;
836  }
837  for (size_t i = 0; i < num; i++) {
838  items[i] = seq_items[num - 1 - i];
839  }
840  } else {
841  mp_obj_iter_buf_t iter_buf;
842  mp_obj_t iterable = mp_getiter(seq_in, &iter_buf);
843 
844  for (seq_len = 0; seq_len < num; seq_len++) {
845  mp_obj_t el = mp_iternext(iterable);
846  if (el == MP_OBJ_STOP_ITERATION) {
847  goto too_short;
848  }
849  items[num - 1 - seq_len] = el;
850  }
851  if (mp_iternext(iterable) != MP_OBJ_STOP_ITERATION) {
852  goto too_long;
853  }
854  }
855  return;
856 
857 too_short:
859  mp_raise_ValueError("wrong number of values to unpack");
860  } else {
862  "need more than %d values to unpack", (int)seq_len));
863  }
864 too_long:
866  mp_raise_ValueError("wrong number of values to unpack");
867  } else {
869  "too many values to unpack (expected %d)", (int)num));
870  }
871 }
872 
873 // unpacked items are stored in reverse order into the array pointed to by items
874 void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) {
875  size_t num_left = num_in & 0xff;
876  size_t num_right = (num_in >> 8) & 0xff;
877  DEBUG_OP_printf("unpack ex " UINT_FMT " " UINT_FMT "\n", num_left, num_right);
878  size_t seq_len;
879  if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) {
880  mp_obj_t *seq_items;
881  mp_obj_get_array(seq_in, &seq_len, &seq_items);
882  if (seq_len < num_left + num_right) {
883  goto too_short;
884  }
885  for (size_t i = 0; i < num_right; i++) {
886  items[i] = seq_items[seq_len - 1 - i];
887  }
888  items[num_right] = mp_obj_new_list(seq_len - num_left - num_right, seq_items + num_left);
889  for (size_t i = 0; i < num_left; i++) {
890  items[num_right + 1 + i] = seq_items[num_left - 1 - i];
891  }
892  } else {
893  // Generic iterable; this gets a bit messy: we unpack known left length to the
894  // items destination array, then the rest to a dynamically created list. Once the
895  // iterable is exhausted, we take from this list for the right part of the items.
896  // TODO Improve to waste less memory in the dynamically created list.
897  mp_obj_t iterable = mp_getiter(seq_in, NULL);
898  mp_obj_t item;
899  for (seq_len = 0; seq_len < num_left; seq_len++) {
900  item = mp_iternext(iterable);
901  if (item == MP_OBJ_STOP_ITERATION) {
902  goto too_short;
903  }
904  items[num_left + num_right + 1 - 1 - seq_len] = item;
905  }
907  while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
908  mp_obj_list_append(MP_OBJ_FROM_PTR(rest), item);
909  }
910  if (rest->len < num_right) {
911  goto too_short;
912  }
913  items[num_right] = MP_OBJ_FROM_PTR(rest);
914  for (size_t i = 0; i < num_right; i++) {
915  items[num_right - 1 - i] = rest->items[rest->len - num_right + i];
916  }
917  mp_obj_list_set_len(MP_OBJ_FROM_PTR(rest), rest->len - num_right);
918  }
919  return;
920 
921 too_short:
923  mp_raise_ValueError("wrong number of values to unpack");
924  } else {
926  "need more than %d values to unpack", (int)seq_len));
927  }
928 }
929 
931  DEBUG_OP_printf("load attr %p.%s\n", base, qstr_str(attr));
932  // use load_method
933  mp_obj_t dest[2];
934  mp_load_method(base, attr, dest);
935  if (dest[1] == MP_OBJ_NULL) {
936  // load_method returned just a normal attribute
937  return dest[0];
938  } else {
939  // load_method returned a method, so build a bound method object
940  return mp_obj_new_bound_meth(dest[0], dest[1]);
941  }
942 }
943 
944 #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
945 
946 // The following "checked fun" type is local to the mp_convert_member_lookup
947 // function, and serves to check that the first argument to a builtin function
948 // has the correct type.
949 
950 typedef struct _mp_obj_checked_fun_t {
951  mp_obj_base_t base;
952  const mp_obj_type_t *type;
953  mp_obj_t fun;
954 } mp_obj_checked_fun_t;
955 
956 STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
957  mp_obj_checked_fun_t *self = MP_OBJ_TO_PTR(self_in);
958  if (n_args > 0) {
959  const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
960  if (arg0_type != self->type) {
962  mp_raise_TypeError("argument has wrong type");
963  } else {
965  "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name));
966  }
967  }
968  }
969  return mp_call_function_n_kw(self->fun, n_args, n_kw, args);
970 }
971 
972 STATIC const mp_obj_type_t mp_type_checked_fun = {
973  { &mp_type_type },
974  .name = MP_QSTR_function,
975  .call = checked_fun_call,
976 };
977 
978 STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun) {
979  mp_obj_checked_fun_t *o = m_new_obj(mp_obj_checked_fun_t);
980  o->base.type = &mp_type_checked_fun;
981  o->type = type;
982  o->fun = fun;
983  return MP_OBJ_FROM_PTR(o);
984 }
985 
986 #endif // MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
987 
988 // Given a member that was extracted from an instance, convert it correctly
989 // and put the result in the dest[] array for a possible method call.
990 // Conversion means dealing with static/class methods, callables, and values.
991 // see http://docs.python.org/3/howto/descriptor.html
992 void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest) {
993  if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
994  // return just the function
995  dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
996  } else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
997  // return a bound method, with self being the type of this object
998  // this type should be the type of the original instance, not the base
999  // type (which is what is passed in the 'type' argument to this function)
1000  if (self != MP_OBJ_NULL) {
1001  type = mp_obj_get_type(self);
1002  }
1003  dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
1004  dest[1] = MP_OBJ_FROM_PTR(type);
1005  } else if (MP_OBJ_IS_TYPE(member, &mp_type_type)) {
1006  // Don't try to bind types (even though they're callable)
1007  dest[0] = member;
1008  } else if (MP_OBJ_IS_FUN(member)
1009  || (MP_OBJ_IS_OBJ(member)
1010  && (((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_closure
1011  || ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_generator))) {
1012  // only functions, closures and generators objects can be bound to self
1013  #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
1014  const mp_obj_type_t *m_type = ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type;
1015  if (self == MP_OBJ_NULL
1016  && (m_type == &mp_type_fun_builtin_0
1017  || m_type == &mp_type_fun_builtin_1
1018  || m_type == &mp_type_fun_builtin_2
1019  || m_type == &mp_type_fun_builtin_3
1020  || m_type == &mp_type_fun_builtin_var)) {
1021  // we extracted a builtin method without a first argument, so we must
1022  // wrap this function in a type checker
1023  dest[0] = mp_obj_new_checked_fun(type, member);
1024  } else
1025  #endif
1026  {
1027  // return a bound method, with self being this object
1028  dest[0] = member;
1029  dest[1] = self;
1030  }
1031  } else {
1032  // class member is a value, so just return that value
1033  dest[0] = member;
1034  }
1035 }
1036 
1037 // no attribute found, returns: dest[0] == MP_OBJ_NULL, dest[1] == MP_OBJ_NULL
1038 // normal attribute found, returns: dest[0] == <attribute>, dest[1] == MP_OBJ_NULL
1039 // method attribute found, returns: dest[0] == <method>, dest[1] == <self>
1041  // clear output to indicate no attribute/method found yet
1042  dest[0] = MP_OBJ_NULL;
1043  dest[1] = MP_OBJ_NULL;
1044 
1045  // get the type
1046  mp_obj_type_t *type = mp_obj_get_type(obj);
1047 
1048  // look for built-in names
1049  if (0) {
1050 #if MICROPY_CPYTHON_COMPAT
1051  } else if (attr == MP_QSTR___class__) {
1052  // a.__class__ is equivalent to type(a)
1053  dest[0] = MP_OBJ_FROM_PTR(type);
1054 #endif
1055 
1056  } else if (attr == MP_QSTR___next__ && type->iternext != NULL) {
1057  dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj);
1058  dest[1] = obj;
1059 
1060  } else if (type->attr != NULL) {
1061  // this type can do its own load, so call it
1062  type->attr(obj, attr, dest);
1063 
1064  } else if (type->locals_dict != NULL) {
1065  // generic method lookup
1066  // this is a lookup in the object (ie not class or type)
1067  assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now
1068  mp_map_t *locals_map = &type->locals_dict->map;
1070  if (elem != NULL) {
1071  mp_convert_member_lookup(obj, type, elem->value, dest);
1072  }
1073  }
1074 }
1075 
1077  DEBUG_OP_printf("load method %p.%s\n", base, qstr_str(attr));
1078 
1079  mp_load_method_maybe(base, attr, dest);
1080 
1081  if (dest[0] == MP_OBJ_NULL) {
1082  // no attribute/method called attr
1084  mp_raise_msg(&mp_type_AttributeError, "no such attribute");
1085  } else {
1086  // following CPython, we give a more detailed error message for type objects
1087  if (MP_OBJ_IS_TYPE(base, &mp_type_type)) {
1089  "type object '%q' has no attribute '%q'",
1090  ((mp_obj_type_t*)MP_OBJ_TO_PTR(base))->name, attr));
1091  } else {
1093  "'%s' object has no attribute '%q'",
1094  mp_obj_get_type_str(base), attr));
1095  }
1096  }
1097  }
1098 }
1099 
1101  DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value);
1102  mp_obj_type_t *type = mp_obj_get_type(base);
1103  if (type->attr != NULL) {
1104  mp_obj_t dest[2] = {MP_OBJ_SENTINEL, value};
1105  type->attr(base, attr, dest);
1106  if (dest[0] == MP_OBJ_NULL) {
1107  // success
1108  return;
1109  }
1110  }
1112  mp_raise_msg(&mp_type_AttributeError, "no such attribute");
1113  } else {
1115  "'%s' object has no attribute '%q'",
1116  mp_obj_get_type_str(base), attr));
1117  }
1118 }
1119 
1121  assert(o_in);
1122  mp_obj_type_t *type = mp_obj_get_type(o_in);
1123 
1124  // Check for native getiter which is the identity. We handle this case explicitly
1125  // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used.
1126  if (type->getiter == mp_identity_getiter) {
1127  return o_in;
1128  }
1129 
1130  // if caller did not provide a buffer then allocate one on the heap
1131  if (iter_buf == NULL) {
1132  iter_buf = m_new_obj(mp_obj_iter_buf_t);
1133  }
1134 
1135  // check for native getiter (corresponds to __iter__)
1136  if (type->getiter != NULL) {
1137  mp_obj_t iter = type->getiter(o_in, iter_buf);
1138  if (iter != MP_OBJ_NULL) {
1139  return iter;
1140  }
1141  }
1142 
1143  // check for __getitem__
1144  mp_obj_t dest[2];
1145  mp_load_method_maybe(o_in, MP_QSTR___getitem__, dest);
1146  if (dest[0] != MP_OBJ_NULL) {
1147  // __getitem__ exists, create and return an iterator
1148  return mp_obj_new_getitem_iter(dest, iter_buf);
1149  }
1150 
1151  // object not iterable
1153  mp_raise_TypeError("object not iterable");
1154  } else {
1156  "'%s' object is not iterable", mp_obj_get_type_str(o_in)));
1157  }
1158 }
1159 
1160 // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raise StopIteration()
1161 // may also raise StopIteration()
1163  mp_obj_type_t *type = mp_obj_get_type(o_in);
1164  if (type->iternext != NULL) {
1165  return type->iternext(o_in);
1166  } else {
1167  // check for __next__ method
1168  mp_obj_t dest[2];
1169  mp_load_method_maybe(o_in, MP_QSTR___next__, dest);
1170  if (dest[0] != MP_OBJ_NULL) {
1171  // __next__ exists, call it and return its result
1172  return mp_call_method_n_kw(0, 0, dest);
1173  } else {
1175  mp_raise_TypeError("object not an iterator");
1176  } else {
1178  "'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
1179  }
1180  }
1181  }
1182 }
1183 
1184 // will always return MP_OBJ_STOP_ITERATION instead of raising StopIteration() (or any subclass thereof)
1185 // may raise other exceptions
1187  MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext
1188  mp_obj_type_t *type = mp_obj_get_type(o_in);
1189  if (type->iternext != NULL) {
1190  return type->iternext(o_in);
1191  } else {
1192  // check for __next__ method
1193  mp_obj_t dest[2];
1194  mp_load_method_maybe(o_in, MP_QSTR___next__, dest);
1195  if (dest[0] != MP_OBJ_NULL) {
1196  // __next__ exists, call it and return its result
1197  nlr_buf_t nlr;
1198  if (nlr_push(&nlr) == 0) {
1199  mp_obj_t ret = mp_call_method_n_kw(0, 0, dest);
1200  nlr_pop();
1201  return ret;
1202  } else {
1204  return MP_OBJ_STOP_ITERATION;
1205  } else {
1206  nlr_jump(nlr.ret_val);
1207  }
1208  }
1209  } else {
1211  mp_raise_TypeError("object not an iterator");
1212  } else {
1214  "'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
1215  }
1216  }
1217  }
1218 }
1219 
1220 // TODO: Unclear what to do with StopIterarion exception here.
1221 mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
1222  assert((send_value != MP_OBJ_NULL) ^ (throw_value != MP_OBJ_NULL));
1223  mp_obj_type_t *type = mp_obj_get_type(self_in);
1224 
1225  if (type == &mp_type_gen_instance) {
1226  return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val);
1227  }
1228 
1229  if (type->iternext != NULL && send_value == mp_const_none) {
1230  mp_obj_t ret = type->iternext(self_in);
1231  if (ret != MP_OBJ_STOP_ITERATION) {
1232  *ret_val = ret;
1233  return MP_VM_RETURN_YIELD;
1234  } else {
1235  // Emulate raise StopIteration()
1236  // Special case, handled in vm.c
1237  *ret_val = MP_OBJ_NULL;
1238  return MP_VM_RETURN_NORMAL;
1239  }
1240  }
1241 
1242  mp_obj_t dest[3]; // Reserve slot for send() arg
1243 
1244  // Python instance iterator protocol
1245  if (send_value == mp_const_none) {
1246  mp_load_method_maybe(self_in, MP_QSTR___next__, dest);
1247  if (dest[0] != MP_OBJ_NULL) {
1248  nlr_buf_t nlr;
1249  if (nlr_push(&nlr) == 0) {
1250  *ret_val = mp_call_method_n_kw(0, 0, dest);
1251  nlr_pop();
1252  return MP_VM_RETURN_YIELD;
1253  } else {
1254  *ret_val = MP_OBJ_FROM_PTR(nlr.ret_val);
1255  return MP_VM_RETURN_EXCEPTION;
1256  }
1257  }
1258  }
1259 
1260  // Either python instance generator protocol, or native object
1261  // generator protocol.
1262  if (send_value != MP_OBJ_NULL) {
1263  mp_load_method(self_in, MP_QSTR_send, dest);
1264  dest[2] = send_value;
1265  // TODO: This should have exception wrapping like __next__ case
1266  // above. Not done right away to think how to optimize native
1267  // generators better, see:
1268  // https://github.com/micropython/micropython/issues/2628
1269  *ret_val = mp_call_method_n_kw(1, 0, dest);
1270  return MP_VM_RETURN_YIELD;
1271  }
1272 
1273  assert(throw_value != MP_OBJ_NULL);
1274  {
1276  mp_load_method_maybe(self_in, MP_QSTR_close, dest);
1277  if (dest[0] != MP_OBJ_NULL) {
1278  // TODO: Exceptions raised in close() are not propagated,
1279  // printed to sys.stderr
1280  *ret_val = mp_call_method_n_kw(0, 0, dest);
1281  // We assume one can't "yield" from close()
1282  return MP_VM_RETURN_NORMAL;
1283  }
1284  } else {
1285  mp_load_method_maybe(self_in, MP_QSTR_throw, dest);
1286  if (dest[0] != MP_OBJ_NULL) {
1287  dest[2] = throw_value;
1288  *ret_val = mp_call_method_n_kw(1, 0, dest);
1289  // If .throw() method returned, we assume it's value to yield
1290  // - any exception would be thrown with nlr_raise().
1291  return MP_VM_RETURN_YIELD;
1292  }
1293  }
1294  // If there's nowhere to throw exception into, then we assume that object
1295  // is just incapable to handle it, so any exception thrown into it
1296  // will be propagated up. This behavior is approved by test_pep380.py
1297  // test_delegation_of_close_to_non_generator(),
1298  // test_delegating_throw_to_non_generator()
1299  *ret_val = throw_value;
1300  return MP_VM_RETURN_EXCEPTION;
1301  }
1302 }
1303 
1305  DEBUG_printf("raise %p\n", o);
1306  if (mp_obj_is_exception_type(o)) {
1307  // o is an exception type (it is derived from BaseException (or is BaseException))
1308  // create and return a new exception instance by calling o
1309  // TODO could have an option to disable traceback, then builtin exceptions (eg TypeError)
1310  // could have const instances in ROM which we return here instead
1311  return mp_call_function_n_kw(o, 0, 0, NULL);
1312  } else if (mp_obj_is_exception_instance(o)) {
1313  // o is an instance of an exception, so use it as the exception
1314  return o;
1315  } else {
1316  // o cannot be used as an exception, so return a type error (which will be raised by the caller)
1317  return mp_obj_new_exception_msg(&mp_type_TypeError, "exceptions must derive from BaseException");
1318  }
1319 }
1320 
1322  DEBUG_printf("import name '%s' level=%d\n", qstr_str(name), MP_OBJ_SMALL_INT_VALUE(level));
1323 
1324  // build args array
1325  mp_obj_t args[5];
1326  args[0] = MP_OBJ_NEW_QSTR(name);
1327  args[1] = mp_const_none; // TODO should be globals
1328  args[2] = mp_const_none; // TODO should be locals
1329  args[3] = fromlist;
1330  args[4] = level; // must be 0; we don't yet support other values
1331 
1332  // TODO lookup __import__ and call that instead of going straight to builtin implementation
1333  return mp_builtin___import__(5, args);
1334 }
1335 
1337  DEBUG_printf("import from %p %s\n", module, qstr_str(name));
1338 
1339  mp_obj_t dest[2];
1340 
1341  mp_load_method_maybe(module, name, dest);
1342 
1343  if (dest[1] != MP_OBJ_NULL) {
1344  // Hopefully we can't import bound method from an object
1345 import_error:
1346  nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "cannot import name %q", name));
1347  }
1348 
1349  if (dest[0] != MP_OBJ_NULL) {
1350  return dest[0];
1351  }
1352 
1353  // See if it's a package, then can try FS import
1354  if (!mp_obj_is_package(module)) {
1355  goto import_error;
1356  }
1357 
1358  mp_load_method_maybe(module, MP_QSTR___name__, dest);
1359  size_t pkg_name_len;
1360  const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
1361 
1362  const uint dot_name_len = pkg_name_len + 1 + qstr_len(name);
1363  char *dot_name = alloca(dot_name_len);
1364  memcpy(dot_name, pkg_name, pkg_name_len);
1365  dot_name[pkg_name_len] = '.';
1366  memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
1367  qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
1368 
1369  mp_obj_t args[5];
1370  args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
1371  args[1] = mp_const_none; // TODO should be globals
1372  args[2] = mp_const_none; // TODO should be locals
1373  args[3] = mp_const_true; // Pass sentinel "non empty" value to force returning of leaf module
1374  args[4] = MP_OBJ_NEW_SMALL_INT(0);
1375 
1376  // TODO lookup __import__ and call that instead of going straight to builtin implementation
1377  return mp_builtin___import__(5, args);
1378 }
1379 
1380 void mp_import_all(mp_obj_t module) {
1381  DEBUG_printf("import all %p\n", module);
1382 
1383  // TODO: Support __all__
1385  for (size_t i = 0; i < map->alloc; i++) {
1386  if (MP_MAP_SLOT_IS_FILLED(map, i)) {
1387  qstr name = MP_OBJ_QSTR_VALUE(map->table[i].key);
1388  if (*qstr_str(name) != '_') {
1389  mp_store_name(name, map->table[i].value);
1390  }
1391  }
1392  }
1393 }
1394 
1395 #if MICROPY_ENABLE_COMPILER
1396 
1397 // this is implemented in this file so it can optimise access to locals/globals
1399  // save context
1400  mp_obj_dict_t *volatile old_globals = mp_globals_get();
1401  mp_obj_dict_t *volatile old_locals = mp_locals_get();
1402 
1403  // set new context
1404  mp_globals_set(globals);
1405  mp_locals_set(locals);
1406 
1407  nlr_buf_t nlr;
1408  if (nlr_push(&nlr) == 0) {
1409  qstr source_name = lex->source_name;
1410  mp_parse_tree_t parse_tree = mp_parse(lex, parse_input_kind);
1411  mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false);
1412 
1413  mp_obj_t ret;
1414  if (MICROPY_PY_BUILTINS_COMPILE && globals == NULL) {
1415  // for compile only, return value is the module function
1416  ret = module_fun;
1417  } else {
1418  // execute module function and get return value
1419  ret = mp_call_function_0(module_fun);
1420  }
1421 
1422  // finish nlr block, restore context and return value
1423  nlr_pop();
1424  mp_globals_set(old_globals);
1425  mp_locals_set(old_locals);
1426  return ret;
1427  } else {
1428  // exception; restore context and re-raise same exception
1429  mp_globals_set(old_globals);
1430  mp_locals_set(old_locals);
1431  nlr_jump(nlr.ret_val);
1432  }
1433 }
1434 
1435 #endif // MICROPY_ENABLE_COMPILER
1436 
1437 NORETURN void m_malloc_fail(size_t num_bytes) {
1438  DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes);
1439  #if MICROPY_ENABLE_GC
1440  if (gc_is_locked()) {
1441  mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked");
1442  }
1443  #endif
1445  "memory allocation failed, allocating %u bytes", (uint)num_bytes));
1446 }
1447 
1448 NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) {
1449  if (msg == NULL) {
1450  nlr_raise(mp_obj_new_exception(exc_type));
1451  } else {
1452  nlr_raise(mp_obj_new_exception_msg(exc_type, msg));
1453  }
1454 }
1455 
1456 NORETURN void mp_raise_ValueError(const char *msg) {
1458 }
1459 
1460 NORETURN void mp_raise_TypeError(const char *msg) {
1462 }
1463 
1464 NORETURN void mp_raise_OSError(int errno_) {
1466 }
1467 
1470 }
Charge level()
Definition: battery.cpp:20
mp_map_t * mp_obj_dict_get_map(mp_obj_t self_in)
Definition: objdict.c:608
size_t len
Definition: objtuple.h:33
const mp_obj_dict_t mp_module_builtins_globals
const mp_obj_type_t mp_type_fun_builtin_var
Definition: objfun.c:131
mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg)
Definition: runtime.c:216
intptr_t mp_int_t
Definition: mpconfigport.h:73
qstr qstr_from_strn(const char *str, size_t len)
Definition: qstr.c:187
bool mp_obj_is_exception_instance(mp_obj_t self_in)
Definition: objexcept.c:451
#define MP_SMALL_INT_MAX
Definition: smallint.h:62
const mp_obj_type_t mp_type_KeyboardInterrupt
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg)
Definition: runtime.c:1448
void * memset(void *b, int c, size_t len)
Definition: memset.c:3
mp_fun_1_t iternext
Definition: obj.h:521
mp_int_t mp_small_int_modulo(mp_int_t dividend, mp_int_t divisor)
Definition: smallint.c:55
const char * qstr_str(qstr q)
Definition: qstr.c:278
mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items)
Definition: objtuple.c:235
void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest)
Definition: runtime.c:1040
#define assert(e)
Definition: assert.h:9
#define MICROPY_ERROR_REPORTING_TERSE
Definition: mpconfig.h:521
#define mp_const_none
Definition: obj.h:614
NORETURN void mp_raise_NotImplementedError(const char *msg)
Definition: runtime.c:1468
const mp_obj_type_t mp_type_ZeroDivisionError
size_t mp_obj_dict_len(mp_obj_t self_in)
Definition: objdict.c:590
def data
Definition: i18n.py:176
const mp_obj_type_t mp_type_TypeError
mp_obj_t mp_import_from(mp_obj_t module, qstr name)
Definition: runtime.c:1336
size_t len
Definition: objlist.h:34
mp_unary_op_fun_t unary_op
Definition: obj.h:491
mp_obj_t mp_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2)
Definition: runtime.c:607
void mp_init(void)
Definition: runtime.c:58
#define MP_OBJ_IS_TYPE(o, t)
Definition: obj.h:254
STATIC const uint8_t attr[]
Definition: unicode.c:51
#define m_del(type, ptr, num)
Definition: misc.h:77
#define nlr_push(buf)
Definition: nlr.h:73
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt,...)
Definition: objexcept.c:380
mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type)
Definition: objexcept.c:329
void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items)
Definition: runtime.c:827
#define MP_OBJ_IS_FUN(o)
Definition: obj.h:258
#define MP_OBJ_QSTR_VALUE(o)
Definition: obj.h:91
const mp_obj_type_t mp_type_StopIteration
void mp_delete_global(qstr qst)
Definition: runtime.c:210
#define MP_OBJ_SENTINEL
Definition: obj.h:75
mp_obj_type_t * mp_obj_get_type(mp_const_obj_t o_in)
Definition: obj.c:40
#define DEBUG_printf(...)
Definition: runtime.c:49
const mp_obj_type_t mp_type_NotImplementedError
#define MP_OBJ_FROM_PTR(p)
Definition: obj.h:233
mp_binary_op_fun_t binary_op
Definition: obj.h:492
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2)
Definition: obj.c:162
#define MP_OBJ_NEW_QSTR(qst)
Definition: obj.h:92
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr)
Definition: runtime.c:930
const mp_obj_type_t mp_type_ImportError
#define mp_const_true
Definition: obj.h:616
#define MICROPY_ERROR_REPORTING_DETAILED
Definition: mpconfig.h:525
mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items)
Definition: objlist.c:470
mp_obj_t key
Definition: obj.h:342
const mp_obj_type_t mp_type_gen_instance
Definition: objgenerator.c:233
mp_call_fun_t call
Definition: obj.h:487
mp_obj_base_t base
Definition: obj.h:814
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val)
Definition: objgenerator.c:94
#define MP_STATE_VM(x)
Definition: mpstate.h:241
mp_unary_op_t
Definition: runtime0.h:45
bool mp_small_int_mul_overflow(mp_int_t x, mp_int_t y)
Definition: smallint.c:29
size_t alloc
Definition: obj.h:361
mp_obj_t mp_obj_new_int_from_ll(long long val)
Definition: objint.c:332
mp_obj_base_t base
Definition: obj.h:765
mp_obj_dict_t * mp_obj_module_get_globals(mp_obj_t self_in)
Definition: objmodule.c:125
mp_obj_t mp_call_function_0(mp_obj_t fun)
Definition: runtime.c:599
mp_obj_t mp_load_global(qstr qst)
Definition: runtime.c:153
void qstr_init(void)
Definition: qstr.c:119
mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_input_kind, mp_obj_dict_t *globals, mp_obj_dict_t *locals)
#define STATIC
Definition: mpconfig.h:1178
#define MP_OBJ_SMALL_INT_VALUE(o)
Definition: obj.h:86
#define MP_SCHED_IDLE
Definition: mpstate.h:54
mp_obj_t items[]
Definition: objtuple.h:34
const mp_obj_type_t mp_type_NameError
mp_int_t mp_small_int_floor_divide(mp_int_t num, mp_int_t denom)
Definition: smallint.c:64
bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo)
Definition: objtype.c:1143
void mp_store_name(qstr qst, mp_obj_t obj)
Definition: runtime.c:194
#define mp_obj_is_float(o)
Definition: obj.h:745
void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest)
Definition: runtime.c:1076
void mp_deinit(void)
Definition: runtime.c:130
mp_map_elem_t * mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind)
Definition: map.c:138
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg)
Definition: objlist.c:234
void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items)
Definition: obj.c:346
mp_parse_input_kind_t
Definition: parse.h:91
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg)
Definition: objexcept.c:343
void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args)
Definition: objdict.c:579
mp_obj_t mp_load_name(qstr qst)
Definition: runtime.c:140
const mp_obj_type_t mp_type_complex
mp_vm_return_kind_t
Definition: runtime.h:31
mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args)
#define MP_OBJ_NEW_SMALL_INT(small_int)
Definition: obj.h:87
#define MICROPY_ERROR_REPORTING
Definition: mpconfigport.h:32
const mp_obj_type_t mp_type_staticmethod
Definition: objtype.c:1241
mp_obj_t mp_call_function_1(mp_obj_t fun, mp_obj_t arg)
Definition: runtime.c:603
const mp_obj_type_t mp_type_fun_builtin_2
Definition: objfun.c:87
bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type)
Definition: objexcept.c:458
const char * mp_obj_str_get_data(mp_obj_t self_in, size_t *len)
Definition: objstr.c:2105
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt, bool is_repl)
#define NULL
Definition: stddef.h:4
#define MP_OBJ_NULL
Definition: obj.h:73
mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg)
Definition: objexcept.c:334
const byte mp_binary_op_method_name[MP_BINARY_OP_NUM_RUNTIME]
Definition: objtype.c:416
const mp_obj_type_t mp_type_OSError
mp_obj_t * items
Definition: objlist.h:35
#define MP_SMALL_INT_FITS(n)
Definition: smallint.h:40
NORETURN void mp_raise_OSError(int errno_)
Definition: runtime.c:1464
void mp_init_emergency_exception_buf(void)
mp_obj_t mp_obj_str_intern(mp_obj_t str)
Definition: objstr.c:2041
size_t qstr
Definition: qstr.h:48
#define UINT_FMT
Definition: mpconfigport.h:71
bool mp_obj_is_package(mp_obj_t module)
Definition: builtinimport.c:49
const mp_obj_type_t mp_type_str
Definition: objstr.c:1950
mp_binary_op_t
Definition: runtime0.h:67
mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs)
Definition: runtime.c:277
mp_obj_t value
Definition: obj.h:343
const mp_obj_type_t mp_type_ValueError
const mp_obj_type_t mp_type_MemoryError
mp_obj_t mp_load_build_class(void)
Definition: runtime.c:180
const mp_obj_type_t mp_type_GeneratorExit
mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in)
Definition: runtime.c:1162
args
Definition: i18n.py:175
const mp_obj_type_t mp_type_fun_builtin_0
Definition: objfun.c:59
#define NORETURN
Definition: mpconfig.h:1268
mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args)
Definition: runtime.c:816
mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key)
Definition: objdict.c:602
mp_obj_t mp_obj_new_int(mp_int_t value)
Definition: objint.c:353
#define nlr_pop()
Definition: nlr.h:74
mp_obj_t fun
Definition: runtime.h:113
Definition: obj.h:356
void * ret_val
Definition: nlr.h:42
NORETURN void m_malloc_fail(size_t num_bytes)
Definition: runtime.c:1437
#define MICROPY_PY_BUILTINS_COMPILE
Definition: mpconfig.h:792
const mp_obj_type_t mp_type_type
Definition: objtype.c:969
const mp_obj_type_t mp_type_AttributeError
mp_getiter_fun_t getiter
Definition: obj.h:517
const mp_obj_module_t mp_module___main__
Definition: runtime.c:53
#define m_renew(type, ptr, old_num, new_num)
Definition: misc.h:75
mp_parse_tree_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind)
mp_obj_t mp_call_method_n_kw(size_t n_args, size_t n_kw, const mp_obj_t *args)
Definition: runtime.c:639
NORETURN void mp_raise_ValueError(const char *msg)
Definition: runtime.c:1456
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value)
Definition: objdict.c:595
mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf)
Definition: obj.c:507
mp_uint_t qstr_compute_hash(const byte *data, size_t len)
Definition: qstr.c:84
size_t used
Definition: obj.h:360
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self)
Definition: objboundmeth.c:103
#define mp_seq_copy(dest, src, len, item_t)
Definition: obj.h:848
mp_attr_fun_t attr
Definition: obj.h:505
STATIC void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args)
Definition: runtime.c:649
mp_obj_t mp_make_raise_obj(mp_obj_t o)
Definition: runtime.c:1304
#define MP_OBJ_TO_PTR(o)
Definition: obj.h:228
Definition: nlr.h:39
void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest)
Definition: runtime.c:992
const mp_obj_type_t mp_type_tuple
Definition: objtuple.c:220
const mp_obj_type_t mp_type_dict
Definition: objdict.c:552
size_t n_kw
Definition: runtime.h:114
void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items)
Definition: runtime.c:874
const mp_obj_type_t mp_type_module
Definition: objmodule.c:94
mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level)
Definition: runtime.c:1321
mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf)
Definition: runtime.c:1120
#define nlr_raise(val)
Definition: nlr.h:89
const char * mp_obj_get_type_str(mp_const_obj_t o_in)
Definition: obj.c:55
void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value)
Definition: runtime.c:1100
void mp_obj_list_set_len(mp_obj_t self_in, size_t len)
Definition: objlist.c:486
bool mp_obj_is_exception_type(mp_obj_t self_in)
Definition: objexcept.c:439
#define MP_STACK_CHECK()
Definition: stackctrl.h:44
mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val)
Definition: runtime.c:1221
const mp_obj_type_t mp_type_classmethod
Definition: objtype.c:1247
#define alloca(size)
Definition: alloca.h:4
qstr name
Definition: obj.h:478
#define MP_OBJ_STOP_ITERATION
Definition: obj.h:74
mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf)
#define BITS_PER_WORD
Definition: mpconfig.h:1187
mp_map_t map
Definition: obj.h:766
const byte mp_unary_op_method_name[MP_UNARY_OP_NUM_RUNTIME]
Definition: objtype.c:337
#define MP_THREAD_GIL_ENTER()
Definition: mpthread.h:57
uint64_t mp_obj_t
Definition: obj.h:39
mp_obj_t mp_iternext(mp_obj_t o_in)
Definition: runtime.c:1186
mp_map_elem_t * table
Definition: obj.h:362
const mp_obj_type_t mp_type_fun_builtin_3
Definition: objfun.c:101
#define nlr_jump(val)
Definition: nlr.h:75
#define MP_SMALL_INT_MIN
Definition: smallint.h:39
mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, const mp_obj_t *args)
Definition: runtime.c:615
const mp_obj_type_t mp_type_fun_builtin_1
Definition: objfun.c:73
size_t n_args
Definition: runtime.h:114
bool gc_is_locked(void)
void mp_delete_name(qstr qst)
Definition: runtime.c:199
qstr source_name
Definition: lexer.h:149
void mp_store_global(qstr qst, mp_obj_t obj)
Definition: runtime.c:205
NORETURN void mp_raise_TypeError(const char *msg)
Definition: runtime.c:1460
#define MP_OBJ_IS_STR_OR_BYTES(o)
Definition: obj.h:257
#define m_new_obj(type)
Definition: misc.h:60
#define DEBUG_OP_printf(...)
Definition: runtime.c:50
#define GET_STR_DATA_LEN(str_obj_in, str_data, str_len)
Definition: objstr.h:55
size_t n_alloc
Definition: runtime.h:114
const mp_obj_type_t mp_type_list
Definition: objlist.c:444
size_t qstr_len(qstr q)
Definition: qstr.c:273
void mp_import_all(mp_obj_t module)
Definition: runtime.c:1380
bool mp_obj_is_true(mp_obj_t arg)
Definition: obj.c:108
#define GET_STR_HASH(str_obj_in, str_hash)
Definition: objstr.h:43
void * memcpy(void *dst, const void *src, size_t n)
Definition: memcpy.c:3
const struct _mp_obj_tuple_t mp_const_empty_tuple_obj
Definition: objtuple.c:233
#define m_new(type, num)
Definition: misc.h:57
#define mp_const_false
Definition: obj.h:615
struct _mp_obj_dict_t * locals_dict
Definition: obj.h:536
#define mp_seq_cat(dest, src1, len1, src2, len2, item_t)
Definition: obj.h:849
mp_obj_t * args
Definition: runtime.h:115
unsigned int uint
Definition: misc.h:38