Change object representation from 1 big union to individual structs.

A big change.  Micro Python objects are allocated as individual structs
with the first element being a pointer to the type information (which
is itself an object).  This scheme follows CPython.  Much more flexible,
not necessarily slower, uses same heap memory, and can allocate objects
statically.

Also change name prefix, from py_ to mp_ (mp for Micro Python).
crypto-aes
Damien 9 years ago
parent e2880aa2fd
commit d99b05282d

@ -4,7 +4,7 @@
#include <string.h>
#include "misc.h"
#include "mpyconfig.h"
#include "mpconfig.h"
#include "asmthumb.h"
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)

@ -1,101 +1,2 @@
#define PYBC_LOAD_CONST_FALSE (0x10)
#define PYBC_LOAD_CONST_NONE (0x11)
#define PYBC_LOAD_CONST_TRUE (0x12)
#define PYBC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess
#define PYBC_LOAD_CONST_INT (0x14) // qstr
#define PYBC_LOAD_CONST_DEC (0x15) // qstr
#define PYBC_LOAD_CONST_ID (0x16) // qstr
#define PYBC_LOAD_CONST_BYTES (0x17) // qstr
#define PYBC_LOAD_CONST_STRING (0x18) // qstr
#define PYBC_LOAD_FAST_0 (0x20)
#define PYBC_LOAD_FAST_1 (0x21)
#define PYBC_LOAD_FAST_2 (0x22)
#define PYBC_LOAD_FAST_N (0x23) // uint
#define PYBC_LOAD_DEREF (0x24) // uint
#define PYBC_LOAD_CLOSURE (0x25) // uint
#define PYBC_LOAD_NAME (0x26) // qstr
#define PYBC_LOAD_GLOBAL (0x27) // qstr
#define PYBC_LOAD_ATTR (0x28) // qstr
#define PYBC_LOAD_METHOD (0x29) // qstr
#define PYBC_LOAD_BUILD_CLASS (0x2a)
#define PYBC_STORE_FAST_0 (0x30)
#define PYBC_STORE_FAST_1 (0x31)
#define PYBC_STORE_FAST_2 (0x32)
#define PYBC_STORE_FAST_N (0x33) // uint
#define PYBC_STORE_DEREF (0x34) // uint
#define PYBC_STORE_NAME (0x35) // qstr
#define PYBC_STORE_GLOBAL (0x36) // qstr
#define PYBC_STORE_ATTR (0x37) // qstr
#define PYBC_STORE_SUBSCR (0x38)
#define PYBC_DELETE_FAST_N (0x39) // uint
#define PYBC_DELETE_DEREF (0x3a) // uint
#define PYBC_DELETE_NAME (0x3b) // qstr
#define PYBC_DELETE_GLOBAL (0x3c) // qstr
#define PYBC_DELETE_ATTR (0x3d) // qstr
#define PYBC_DELETE_SUBSCR (0x3e)
#define PYBC_DUP_TOP (0x40)
#define PYBC_DUP_TOP_TWO (0x41)
#define PYBC_POP_TOP (0x42)
#define PYBC_ROT_TWO (0x43)
#define PYBC_ROT_THREE (0x44)
#define PYBC_JUMP (0x45) // rel byte code offset, 16-bit signed, in excess
#define PYBC_POP_JUMP_IF_TRUE (0x46) // rel byte code offset, 16-bit signed, in excess
#define PYBC_POP_JUMP_IF_FALSE (0x47) // rel byte code offset, 16-bit signed, in excess
#define PYBC_JUMP_IF_TRUE_OR_POP (0x48) // rel byte code offset, 16-bit signed, in excess
#define PYBC_JUMP_IF_FALSE_OR_POP (0x49) // rel byte code offset, 16-bit signed, in excess
#define PYBC_SETUP_LOOP (0x4a) // rel byte code offset, 16-bit unsigned
#define PYBC_BREAK_LOOP (0x4b) // rel byte code offset, 16-bit unsigned
#define PYBC_CONTINUE_LOOP (0x4c) // rel byte code offset, 16-bit unsigned
#define PYBC_SETUP_WITH (0x4d) // rel byte code offset, 16-bit unsigned
#define PYBC_WITH_CLEANUP (0x4e)
#define PYBC_SETUP_EXCEPT (0x4f) // rel byte code offset, 16-bit unsigned
#define PYBC_SETUP_FINALLY (0x50) // rel byte code offset, 16-bit unsigned
#define PYBC_END_FINALLY (0x51)
#define PYBC_GET_ITER (0x52)
#define PYBC_FOR_ITER (0x53) // rel byte code offset, 16-bit unsigned
#define PYBC_POP_BLOCK (0x54)
#define PYBC_POP_EXCEPT (0x55)
#define PYBC_UNARY_OP (0x60) // byte
#define PYBC_BINARY_OP (0x61) // byte
#define PYBC_COMPARE_OP (0x62) // byte
#define PYBC_BUILD_TUPLE (0x70) // uint
#define PYBC_BUILD_LIST (0x71) // uint
#define PYBC_LIST_APPEND (0x72) // uint
#define PYBC_BUILD_MAP (0x73) // uint
#define PYBC_STORE_MAP (0x74)
#define PYBC_MAP_ADD (0x75) // uint
#define PYBC_BUILD_SET (0x76) // uint
#define PYBC_SET_ADD (0x77) // uint
#define PYBC_BUILD_SLICE (0x78) // uint
#define PYBC_UNPACK_SEQUENCE (0x79) // uint
#define PYBC_UNPACK_EX (0x7a) // uint
#define PYBC_RETURN_VALUE (0x80)
#define PYBC_RAISE_VARARGS (0x81) // uint
#define PYBC_YIELD_VALUE (0x82)
#define PYBC_YIELD_FROM (0x83)
#define PYBC_MAKE_FUNCTION (0x90) // uint
#define PYBC_MAKE_CLOSURE (0x91) // uint
#define PYBC_CALL_FUNCTION (0x92) // uint
#define PYBC_CALL_FUNCTION_VAR (0x93) // uint
#define PYBC_CALL_FUNCTION_KW (0x94) // uint
#define PYBC_CALL_FUNCTION_VAR_KW (0x95) // uint
#define PYBC_CALL_METHOD (0x96) // uint
#define PYBC_CALL_METHOD_VAR (0x97) // uint
#define PYBC_CALL_METHOD_KW (0x98) // uint
#define PYBC_CALL_METHOD_VAR_KW (0x99) // uint
#define PYBC_IMPORT_NAME (0xe0) // qstr
#define PYBC_IMPORT_FROM (0xe1) // qstr
#define PYBC_IMPORT_STAR (0xe2)
py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_args, uint n_state);
bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **sp_in_out);
mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state);
bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out);

@ -0,0 +1,98 @@
#define MP_BC_LOAD_CONST_FALSE (0x10)
#define MP_BC_LOAD_CONST_NONE (0x11)
#define MP_BC_LOAD_CONST_TRUE (0x12)
#define MP_BC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess
#define MP_BC_LOAD_CONST_INT (0x14) // qstr
#define MP_BC_LOAD_CONST_DEC (0x15) // qstr
#define MP_BC_LOAD_CONST_ID (0x16) // qstr
#define MP_BC_LOAD_CONST_BYTES (0x17) // qstr
#define MP_BC_LOAD_CONST_STRING (0x18) // qstr
#define MP_BC_LOAD_FAST_0 (0x20)
#define MP_BC_LOAD_FAST_1 (0x21)
#define MP_BC_LOAD_FAST_2 (0x22)
#define MP_BC_LOAD_FAST_N (0x23) // uint
#define MP_BC_LOAD_DEREF (0x24) // uint
#define MP_BC_LOAD_CLOSURE (0x25) // uint
#define MP_BC_LOAD_NAME (0x26) // qstr
#define MP_BC_LOAD_GLOBAL (0x27) // qstr
#define MP_BC_LOAD_ATTR (0x28) // qstr
#define MP_BC_LOAD_METHOD (0x29) // qstr
#define MP_BC_LOAD_BUILD_CLASS (0x2a)
#define MP_BC_STORE_FAST_0 (0x30)
#define MP_BC_STORE_FAST_1 (0x31)
#define MP_BC_STORE_FAST_2 (0x32)
#define MP_BC_STORE_FAST_N (0x33) // uint
#define MP_BC_STORE_DEREF (0x34) // uint
#define MP_BC_STORE_NAME (0x35) // qstr
#define MP_BC_STORE_GLOBAL (0x36) // qstr
#define MP_BC_STORE_ATTR (0x37) // qstr
#define MP_BC_STORE_SUBSCR (0x38)
#define MP_BC_DELETE_FAST_N (0x39) // uint
#define MP_BC_DELETE_DEREF (0x3a) // uint
#define MP_BC_DELETE_NAME (0x3b) // qstr
#define MP_BC_DELETE_GLOBAL (0x3c) // qstr
#define MP_BC_DELETE_ATTR (0x3d) // qstr
#define MP_BC_DELETE_SUBSCR (0x3e)
#define MP_BC_DUP_TOP (0x40)
#define MP_BC_DUP_TOP_TWO (0x41)
#define MP_BC_POP_TOP (0x42)
#define MP_BC_ROT_TWO (0x43)
#define MP_BC_ROT_THREE (0x44)
#define MP_BC_JUMP (0x45) // rel byte code offset, 16-bit signed, in excess
#define MP_BC_POP_JUMP_IF_TRUE (0x46) // rel byte code offset, 16-bit signed, in excess
#define MP_BC_POP_JUMP_IF_FALSE (0x47) // rel byte code offset, 16-bit signed, in excess
#define MP_BC_JUMP_IF_TRUE_OR_POP (0x48) // rel byte code offset, 16-bit signed, in excess
#define MP_BC_JUMP_IF_FALSE_OR_POP (0x49) // rel byte code offset, 16-bit signed, in excess
#define MP_BC_SETUP_LOOP (0x4a) // rel byte code offset, 16-bit unsigned
#define MP_BC_BREAK_LOOP (0x4b) // rel byte code offset, 16-bit unsigned
#define MP_BC_CONTINUE_LOOP (0x4c) // rel byte code offset, 16-bit unsigned
#define MP_BC_SETUP_WITH (0x4d) // rel byte code offset, 16-bit unsigned
#define MP_BC_WITH_CLEANUP (0x4e)
#define MP_BC_SETUP_EXCEPT (0x4f) // rel byte code offset, 16-bit unsigned
#define MP_BC_SETUP_FINALLY (0x50) // rel byte code offset, 16-bit unsigned
#define MP_BC_END_FINALLY (0x51)
#define MP_BC_GET_ITER (0x52)
#define MP_BC_FOR_ITER (0x53) // rel byte code offset, 16-bit unsigned
#define MP_BC_POP_BLOCK (0x54)
#define MP_BC_POP_EXCEPT (0x55)
#define MP_BC_UNARY_OP (0x60) // byte
#define MP_BC_BINARY_OP (0x61) // byte
#define MP_BC_COMPARE_OP (0x62) // byte
#define MP_BC_BUILD_TUPLE (0x70) // uint
#define MP_BC_BUILD_LIST (0x71) // uint
#define MP_BC_LIST_APPEND (0x72) // uint
#define MP_BC_BUILD_MAP (0x73) // uint
#define MP_BC_STORE_MAP (0x74)
#define MP_BC_MAP_ADD (0x75) // uint
#define MP_BC_BUILD_SET (0x76) // uint
#define MP_BC_SET_ADD (0x77) // uint
#define MP_BC_BUILD_SLICE (0x78) // uint
#define MP_BC_UNPACK_SEQUENCE (0x79) // uint
#define MP_BC_UNPACK_EX (0x7a) // uint
#define MP_BC_RETURN_VALUE (0x80)
#define MP_BC_RAISE_VARARGS (0x81) // uint
#define MP_BC_YIELD_VALUE (0x82)
#define MP_BC_YIELD_FROM (0x83)
#define MP_BC_MAKE_FUNCTION (0x90) // uint
#define MP_BC_MAKE_CLOSURE (0x91) // uint
#define MP_BC_CALL_FUNCTION (0x92) // uint
#define MP_BC_CALL_FUNCTION_VAR (0x93) // uint
#define MP_BC_CALL_FUNCTION_KW (0x94) // uint
#define MP_BC_CALL_FUNCTION_VAR_KW (0x95) // uint
#define MP_BC_CALL_METHOD (0x96) // uint
#define MP_BC_CALL_METHOD_VAR (0x97) // uint
#define MP_BC_CALL_METHOD_KW (0x98) // uint
#define MP_BC_CALL_METHOD_VAR_KW (0x99) // uint
#define MP_BC_IMPORT_NAME (0xe0) // qstr
#define MP_BC_IMPORT_FROM (0xe1) // qstr
#define MP_BC_IMPORT_STAR (0xe2)

@ -7,253 +7,258 @@
#include "nlr.h"
#include "misc.h"
#include "mpyconfig.h"
#include "mpconfig.h"
#include "obj.h"
#include "runtime0.h"
#include "runtime.h"
#include "bc.h"
//#include "bc.h"
#include "map.h"
#include "obj.h"
#include "objprivate.h"
#include "builtin.h"
py_obj_t py_builtin___build_class__(py_obj_t o_class_fun, py_obj_t o_class_name) {
mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name) {
// we differ from CPython: we set the new __locals__ object here
py_map_t *old_locals = rt_get_map_locals();
py_map_t *class_locals = py_map_new(MAP_QSTR, 0);
mp_map_t *old_locals = rt_get_map_locals();
mp_map_t *class_locals = mp_map_new(MP_MAP_QSTR, 0);
rt_set_map_locals(class_locals);
// call the class code
rt_call_function_1(o_class_fun, (py_obj_t)0xdeadbeef);
rt_call_function_1(o_class_fun, (mp_obj_t)0xdeadbeef);
// restore old __locals__ object
rt_set_map_locals(old_locals);
// create and return the new class
py_obj_base_t *o = m_new(py_obj_base_t, 1);
o->kind = O_CLASS;
o->u_class.locals = class_locals;
return o;
return mp_obj_new_class(class_locals);
}
py_obj_t py_builtin___import__(int n, py_obj_t *args) {
mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
printf("import:\n");
for (int i = 0; i < n; i++) {
printf(" ");
py_obj_print(args[i]);
mp_obj_print(args[i]);
printf("\n");
}
return py_const_none;
return mp_const_none;
}
py_obj_t py_builtin___repl_print__(py_obj_t o) {
if (o != py_const_none) {
py_obj_print(o);
mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
if (o != mp_const_none) {
mp_obj_print(o);
printf("\n");
}
return py_const_none;
return mp_const_none;
}
py_obj_t py_builtin_abs(py_obj_t o_in) {
if (IS_SMALL_INT(o_in)) {
py_small_int_t val = FROM_SMALL_INT(o_in);
mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o_in);
if (val < 0) {
val = -val;
}
return TO_SMALL_INT(val);
return MP_OBJ_NEW_SMALL_INT(val);
#if MICROPY_ENABLE_FLOAT
} else if (IS_O(o_in, O_FLOAT)) {
py_obj_base_t *o = o_in;
} else if (MP_OBJ_IS_TYPE(o_in, &float_type)) {
mp_float_t value = mp_obj_float_get(o_in);
// TODO check for NaN etc
if (o->u_float < 0) {
return py_obj_new_float(-o->u_float);
if (value < 0) {
return mp_obj_new_float(-value);
} else {
return o_in;
}
} else if (IS_O(o_in, O_COMPLEX)) {
py_obj_base_t *o = o_in;
return py_obj_new_float(machine_sqrt(o->u_complex.real*o->u_complex.real + o->u_complex.imag*o->u_complex.imag));
} else if (MP_OBJ_IS_TYPE(o_in, &complex_type)) {
mp_float_t real, imag;
mp_obj_complex_get(o_in, &real, &imag);
return mp_obj_new_float(machine_sqrt(real*real + imag*imag));
#endif
} else {
assert(0);
return py_const_none;
return mp_const_none;
}
}
py_obj_t py_builtin_all(py_obj_t o_in) {
py_obj_t iterable = rt_getiter(o_in);
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
mp_obj_t mp_builtin_all(mp_obj_t o_in) {
mp_obj_t iterable = rt_getiter(o_in);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
if (!rt_is_true(item)) {
return py_const_false;
return mp_const_false;
}
}
return py_const_true;
return mp_const_true;
}
py_obj_t py_builtin_any(py_obj_t o_in) {
py_obj_t iterable = rt_getiter(o_in);
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
mp_obj_t mp_builtin_any(mp_obj_t o_in) {
mp_obj_t iterable = rt_getiter(o_in);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
if (rt_is_true(item)) {
return py_const_true;
return mp_const_true;
}
}
return py_const_false;
return mp_const_false;
}
py_obj_t py_builtin_bool(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_bool(int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0: return py_const_false;
case 1: if (rt_is_true(args[0])) { return py_const_true; } else { return py_const_false; }
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "bool() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args, NULL));
case 0: return mp_const_false;
case 1: if (rt_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "bool() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args));
}
}
py_obj_t py_builtin_callable(py_obj_t o_in) {
if (py_obj_is_callable(o_in)) {
return py_const_true;
mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
if (mp_obj_is_callable(o_in)) {
return mp_const_true;
} else {
return py_const_false;
return mp_const_false;
}
}
#if MICROPY_ENABLE_FLOAT
py_obj_t py_builtin_complex(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_complex(int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0:
return py_obj_new_complex(0, 0);
return mp_obj_new_complex(0, 0);
case 1:
// TODO allow string as first arg
if (IS_O(args[0], O_COMPLEX)) {
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
return args[0];
} else {
return py_obj_new_complex(py_obj_get_float(args[0]), 0);
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
}
case 2:
{
py_float_t real, imag;
if (IS_O(args[0], O_COMPLEX)) {
py_obj_get_complex(args[0], &real, &imag);
mp_float_t real, imag;
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
mp_obj_get_complex(args[0], &real, &imag);
} else {
real = py_obj_get_float(args[0]);
real = mp_obj_get_float(args[0]);
imag = 0;
}
if (IS_O(args[1], O_COMPLEX)) {
py_float_t real2, imag2;
py_obj_get_complex(args[1], &real2, &imag2);
if (MP_OBJ_IS_TYPE(args[1], &complex_type)) {
mp_float_t real2, imag2;
mp_obj_get_complex(args[1], &real2, &imag2);
real -= imag2;
imag += real2;
} else {
imag += py_obj_get_float(args[1]);
imag += mp_obj_get_float(args[1]);
}
return py_obj_new_complex(real, imag);
return mp_obj_new_complex(real, imag);
}
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "comlpex() takes at most 2 arguments (%d given)", (void*)(machine_int_t)n_args, NULL));
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "comlpex() takes at most 2 arguments (%d given)", (void*)(machine_int_t)n_args));
}
}
#endif
py_obj_t py_builtin_chr(py_obj_t o_in) {
int ord = py_obj_get_int(o_in);
mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
int ord = mp_obj_get_int(o_in);
if (0 <= ord && ord <= 0x10ffff) {
char *str = m_new(char, 2);
str[0] = ord;
str[1] = '\0';
return py_obj_new_str(qstr_from_str_take(str));
return mp_obj_new_str(qstr_from_str_take(str));
} else {
nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "chr() arg not in range(0x110000)", NULL, NULL));
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "chr() arg not in range(0x110000)"));
}
}
py_obj_t py_builtin_dict(void) {
mp_obj_t mp_builtin_dict(void) {
// TODO create from an iterable!
return rt_build_map(0);
}
py_obj_t py_builtin_divmod(py_obj_t o1_in, py_obj_t o2_in) {
if (IS_SMALL_INT(o1_in) && IS_SMALL_INT(o2_in)) {
py_small_int_t i1 = FROM_SMALL_INT(o1_in);
py_small_int_t i2 = FROM_SMALL_INT(o2_in);
py_obj_t revs_args[2];
revs_args[1] = TO_SMALL_INT(i1 / i2);
revs_args[0] = TO_SMALL_INT(i1 % i2);
mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) {
mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in);
mp_small_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2_in);
mp_obj_t revs_args[2];
revs_args[1] = MP_OBJ_NEW_SMALL_INT(i1 / i2);
revs_args[0] = MP_OBJ_NEW_SMALL_INT(i1 % i2);
return rt_build_tuple(2, revs_args);
} else {
nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", py_obj_get_type_str(o1_in), py_obj_get_type_str(o2_in)));
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
}
}
py_obj_t py_builtin_hash(py_obj_t o_in) {
static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
// TODO hash will generally overflow small integer; can we safely truncate it?
return py_obj_new_int(py_obj_hash(o_in));
return mp_obj_new_int(mp_obj_hash(o_in));
}
py_obj_t py_builtin_iter(py_obj_t o_in) {
return rt_getiter(o_in);
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hash_obj, mp_builtin_hash);
py_obj_t py_builtin_next(py_obj_t o_in) {
return rt_gen_instance_next(o_in);
static mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
return rt_getiter(o_in);
}
py_obj_t py_builtin_len(py_obj_t o_in) {
py_small_int_t len = 0;
if (IS_O(o_in, O_STR)) {
py_obj_base_t *o = o_in;
len = strlen(qstr_str(o->u_str));
} else if (IS_O(o_in, O_TUPLE) || IS_O(o_in, O_LIST)) {
py_obj_base_t *o = o_in;
len = o->u_tuple_list.len;
} else if (IS_O(o_in, O_MAP)) {
py_obj_base_t *o = o_in;
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter);
mp_obj_t mp_builtin_len(mp_obj_t o_in) {
mp_small_int_t len = 0;
if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
len = strlen(qstr_str(mp_obj_str_get(o_in)));
} else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) {
uint seq_len;
mp_obj_t *seq_items;
mp_obj_tuple_get(o_in, &seq_len, &seq_items);
len = seq_len;
} else if (MP_OBJ_IS_TYPE(o_in, &list_type)) {
uint seq_len;
mp_obj_t *seq_items;
mp_obj_list_get(o_in, &seq_len, &seq_items);
len = seq_len;
/* TODO
} else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) {
mp_obj_base_t *o = o_in;
len = o->u_map.used;
*/
} else {
nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "object of type '%s' has no len()", py_obj_get_type_str(o_in), NULL));
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
}
return TO_SMALL_INT(len);
return MP_OBJ_NEW_SMALL_INT(len);
}
py_obj_t py_builtin_list(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0: return rt_build_list(0, NULL);
case 1:
{
// make list from iterable
py_obj_t iterable = rt_getiter(args[0]);
py_obj_t list = rt_build_list(0, NULL);
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t list = rt_build_list(0, NULL);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
rt_list_append(list, item);
}
return list;
}
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "list() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args, NULL));
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "list() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args));
}
}
py_obj_t py_builtin_max(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
if (n_args == 1) {
// given an iterable
py_obj_t iterable = rt_getiter(args[0]);
py_obj_t max_obj = NULL;
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
if (max_obj == NULL || py_obj_less(max_obj, item)) {
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t max_obj = NULL;
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
if (max_obj == NULL || mp_obj_less(max_obj, item)) {
max_obj = item;
}
}
if (max_obj == NULL) {
nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "max() arg is an empty sequence", NULL, NULL));
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "max() arg is an empty sequence"));
}
return max_obj;
} else {
// given many args
py_obj_t max_obj = args[0];
mp_obj_t max_obj = args[0];
for (int i = 1; i < n_args; i++) {
if (py_obj_less(max_obj, args[i])) {
if (mp_obj_less(max_obj, args[i])) {
max_obj = args[i];
}
}
@ -261,26 +266,26 @@ py_obj_t py_builtin_max(int n_args, const py_obj_t *args) {
}
}
py_obj_t py_builtin_min(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
if (n_args == 1) {
// given an iterable
py_obj_t iterable = rt_getiter(args[0]);
py_obj_t min_obj = NULL;
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
if (min_obj == NULL || py_obj_less(item, min_obj)) {
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t min_obj = NULL;
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
if (min_obj == NULL || mp_obj_less(item, min_obj)) {
min_obj = item;
}
}
if (min_obj == NULL) {
nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "min() arg is an empty sequence", NULL, NULL));
nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "min() arg is an empty sequence"));
}
return min_obj;
} else {
// given many args
py_obj_t min_obj = args[0];
mp_obj_t min_obj = args[0];
for (int i = 1; i < n_args; i++) {
if (py_obj_less(args[i], min_obj)) {
if (mp_obj_less(args[i], min_obj)) {
min_obj = args[i];
}
}
@ -288,59 +293,85 @@ py_obj_t py_builtin_min(int n_args, const py_obj_t *args) {
}
}
py_obj_t py_builtin_ord(py_obj_t o_in) {
const char *str = qstr_str(py_obj_get_qstr(o_in));
static mp_obj_t mp_builtin_next(mp_obj_t o_in) {
return mp_obj_gen_instance_next(o_in);
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next);
mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
const char *str = qstr_str(mp_obj_get_qstr(o_in));
if (strlen(str) == 1) {
return py_obj_new_int(str[0]);
return mp_obj_new_int(str[0]);
} else {
nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str), NULL));
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str)));
}
}
py_obj_t py_builtin_pow(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) {
switch (n_args) {
case 2: return rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]);
case 3: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise...
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args, NULL));
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
}
}
py_obj_t py_builtin_print(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args) {
for (int i = 0; i < n_args; i++) {
if (i > 0) {
printf(" ");
}
if (IS_O(args[i], O_STR)) {
if (MP_OBJ_IS_TYPE(args[i], &str_type)) {
// special case, print string raw
printf("%s", qstr_str(((py_obj_base_t*)args[i])->u_str));
printf("%s", qstr_str(mp_obj_str_get(args[i])));
} else {
// print the object Python style
py_obj_print(args[i]);
mp_obj_print(args[i]);
}
}
printf("\n");
return py_const_none;
return mp_const_none;
}
py_obj_t py_builtin_range(int n_args, const py_obj_t *args) {
mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args) {
switch (n_args) {
case 1: return py_obj_new_range(0, py_obj_get_int(args[0]), 1);
case 2: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), 1);
case 3: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), py_obj_get_int(args[2]));
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args, NULL));
case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1);
case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1);
case 3: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args));
}
}
static mp_obj_t mp_builtin_set(int n_args, const mp_obj_t *args) {
assert(0 <= n_args && n_args <= 1);
if (n_args == 0) {
// return a new, empty set
return mp_obj_new_set(0, NULL);
} else {
// 1 argument, an iterable from which we make a new set
mp_obj_t set = mp_obj_new_set(0, NULL);
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
mp_obj_set_store(set, item);
}
return set;
}
}
py_obj_t py_builtin_sum(int n_args, const py_obj_t *args) {
py_obj_t value;
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_set_obj, 0, 1, mp_builtin_set);
mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
mp_obj_t value;
switch (n_args) {
case 1: value = py_obj_new_int(0); break;
case 1: value = mp_obj_new_int(0); break;
case 2: value = args[1]; break;
default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args, NULL));
default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args));
}
py_obj_t iterable = rt_getiter(args[0]);
py_obj_t item;
while ((item = rt_iternext(iterable)) != py_const_stop_iteration) {
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
value = rt_binary_op(RT_BINARY_OP_ADD, value, item);
}
return value;

@ -1,24 +1,27 @@
py_obj_t py_builtin___build_class__(py_obj_t o_class_fun, py_obj_t o_class_name);
py_obj_t py_builtin___import__(int n, py_obj_t *args);
py_obj_t py_builtin___repl_print__(py_obj_t o);
py_obj_t py_builtin_abs(py_obj_t o_in);
py_obj_t py_builtin_all(py_obj_t o_in);
py_obj_t py_builtin_any(py_obj_t o_in);
py_obj_t py_builtin_bool(int n_args, const py_obj_t *args);
py_obj_t py_builtin_callable(py_obj_t o_in);
py_obj_t py_builtin_complex(int n_args, const py_obj_t *args);
py_obj_t py_builtin_chr(py_obj_t o_in);
py_obj_t py_builtin_dict(void);
py_obj_t py_builtin_divmod(py_obj_t o1_in, py_obj_t o2_in);
py_obj_t py_builtin_hash(py_obj_t o_in);
py_obj_t py_builtin_iter(py_obj_t o_in);
py_obj_t py_builtin_len(py_obj_t o_in);
py_obj_t py_builtin_list(int n_args, const py_obj_t *args);
py_obj_t py_builtin_max(int n_args, const py_obj_t *args);
py_obj_t py_builtin_min(int n_args, const py_obj_t *args);
py_obj_t py_builtin_next(py_obj_t o_in);
py_obj_t py_builtin_ord(py_obj_t o_in);
py_obj_t py_builtin_pow(int n_args, const py_obj_t *args);
py_obj_t py_builtin_print(int n_args, const py_obj_t *args);
py_obj_t py_builtin_range(int n_args, const py_obj_t *args);
py_obj_t py_builtin_sum(int n_args, const py_obj_t *args);
// TODO convert all these to objects using MP_DECLARE and MP_DEFINE
mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name);
mp_obj_t mp_builtin___import__(int n, mp_obj_t *args);
mp_obj_t mp_builtin___repl_print__(mp_obj_t o);
mp_obj_t mp_builtin_abs(mp_obj_t o_in);
mp_obj_t mp_builtin_all(mp_obj_t o_in);
mp_obj_t mp_builtin_any(mp_obj_t o_in);
mp_obj_t mp_builtin_bool(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_callable(mp_obj_t o_in);
mp_obj_t mp_builtin_complex(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_chr(mp_obj_t o_in);
mp_obj_t mp_builtin_dict(void);
mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_iter_obj);
mp_obj_t mp_builtin_len(mp_obj_t o_in);
mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_next_obj);
mp_obj_t mp_builtin_ord(mp_obj_t o_in);
mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args);
mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_set_obj);
mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args);

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
bool py_compile(py_parse_node_t pn, bool is_repl);
bool mp_compile(mp_parse_node_t pn, bool is_repl);

@ -32,7 +32,7 @@ typedef struct _emit_method_table_t {
void (*import_name)(emit_t *emit, qstr qstr);
void (*import_from)(emit_t *emit, qstr qstr);
void (*import_star)(emit_t *emit);
void (*load_const_tok)(emit_t *emit, py_token_kind_t tok);
void (*load_const_tok)(emit_t *emit, mp_token_kind_t tok);
void (*load_const_small_int)(emit_t *emit, int arg);
void (*load_const_int)(emit_t *emit, qstr qstr);
void (*load_const_dec)(emit_t *emit, qstr qstr);
@ -129,9 +129,9 @@ typedef struct _emit_inline_asm_t emit_inline_asm_t;
typedef struct _emit_inline_asm_method_table_t {
void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope);
void (*end_pass)(emit_inline_asm_t *emit);
int (*count_params)(emit_inline_asm_t *emit, int n_params, py_parse_node_t *pn_params);
int (*count_params)(emit_inline_asm_t *emit, int n_params, mp_parse_node_t *pn_params);
void (*label)(emit_inline_asm_t *emit, int label_num, qstr label_id);
void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, py_parse_node_t *pn_args);
void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args);
} emit_inline_asm_method_table_t;
extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table;

@ -6,14 +6,14 @@
#include <assert.h>
#include "misc.h"
#include "mpyconfig.h"
#include "mpconfig.h"
#include "lexer.h"
#include "parse.h"
#include "compile.h"
#include "scope.h"
#include "runtime.h"
#include "runtime0.h"
#include "emit.h"
#include "bc.h"
#include "bc0.h"
struct _emit_t {
pass_kind_t pass;
@ -214,55 +214,55 @@ static void emit_bc_label_assign(emit_t *emit, int l) {
static void emit_bc_import_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
emit_write_byte_1_qstr(emit, PYBC_IMPORT_NAME, qstr);
emit_write_byte_1_qstr(emit, MP_BC_IMPORT_NAME, qstr);
}
static void emit_bc_import_from(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_IMPORT_FROM, qstr);
emit_write_byte_1_qstr(emit, MP_BC_IMPORT_FROM, qstr);
}
static void emit_bc_import_star(emit_t *emit) {
emit_pre(emit, -1);
emit_write_byte_1(emit, PYBC_IMPORT_STAR);
emit_write_byte_1(emit, MP_BC_IMPORT_STAR);
}
static void emit_bc_load_const_tok(emit_t *emit, py_token_kind_t tok) {
static void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
emit_pre(emit, 1);
switch (tok) {
case PY_TOKEN_KW_FALSE: emit_write_byte_1(emit, PYBC_LOAD_CONST_FALSE); break;
case PY_TOKEN_KW_NONE: emit_write_byte_1(emit, PYBC_LOAD_CONST_NONE); break;
case PY_TOKEN_KW_TRUE: emit_write_byte_1(emit, PYBC_LOAD_CONST_TRUE); break;
case MP_TOKEN_KW_FALSE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_FALSE); break;
case MP_TOKEN_KW_NONE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_NONE); break;
case MP_TOKEN_KW_TRUE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_TRUE); break;
default: assert(0);
}
}
static void emit_bc_load_const_small_int(emit_t *emit, int arg) {
emit_pre(emit, 1);
emit_write_byte_1_int(emit, PYBC_LOAD_CONST_SMALL_INT, arg);
emit_write_byte_1_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg);
}
static void emit_bc_load_const_int(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_INT, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_INT, qstr);
}
static void emit_bc_load_const_dec(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_DEC, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr);
}
static void emit_bc_load_const_id(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_ID, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_ID, qstr);
}
static void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
emit_pre(emit, 1);
if (bytes) {
emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_BYTES, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr);
} else {
emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_STRING, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr);
}
}
@ -275,219 +275,219 @@ static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) {
assert(local_num >= 0);
emit_pre(emit, 1);
switch (local_num) {
case 0: emit_write_byte_1(emit, PYBC_LOAD_FAST_0); break;
case 1: emit_write_byte_1(emit, PYBC_LOAD_FAST_1); break;
case 2: emit_write_byte_1(emit, PYBC_LOAD_FAST_2); break;
default: emit_write_byte_1_uint(emit, PYBC_LOAD_FAST_N, local_num); break;
case 0: emit_write_byte_1(emit, MP_BC_LOAD_FAST_0); break;
case 1: emit_write_byte_1(emit, MP_BC_LOAD_FAST_1); break;
case 2: emit_write_byte_1(emit, MP_BC_LOAD_FAST_2); break;
default: emit_write_byte_1_uint(emit, MP_BC_LOAD_FAST_N, local_num); break;
}
}
static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1);
emit_write_byte_1_uint(emit, PYBC_LOAD_DEREF, local_num);
emit_write_byte_1_uint(emit, MP_BC_LOAD_DEREF, local_num);
}
static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 1);
emit_write_byte_1_uint(emit, PYBC_LOAD_CLOSURE, local_num);
emit_write_byte_1_uint(emit, MP_BC_LOAD_CLOSURE, local_num);
}
static void emit_bc_load_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_NAME, qstr);
}
static void emit_bc_load_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 1);
emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_GLOBAL, qstr);
}
static void emit_bc_load_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_LOAD_ATTR, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_ATTR, qstr);
}
static void emit_bc_load_method(emit_t *emit, qstr qstr) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_LOAD_METHOD, qstr);
emit_write_byte_1_qstr(emit, MP_BC_LOAD_METHOD, qstr);
}
static void emit_bc_load_build_class(emit_t *emit) {
emit_pre(emit, 1);
emit_write_byte_1(emit, PYBC_LOAD_BUILD_CLASS);
emit_write_byte_1(emit, MP_BC_LOAD_BUILD_CLASS);
}
static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) {
assert(local_num >= 0);
emit_pre(emit, -1);
switch (local_num) {
case 0: emit_write_byte_1(emit, PYBC_STORE_FAST_0); break;
case 1: emit_write_byte_1(emit, PYBC_STORE_FAST_1); break;
case 2: emit_write_byte_1(emit, PYBC_STORE_FAST_2); break;
default: emit_write_byte_1_uint(emit, PYBC_STORE_FAST_N, local_num); break;
case 0: emit_write_byte_1(emit, MP_BC_STORE_FAST_0); break;
case 1: emit_write_byte_1(emit, MP_BC_STORE_FAST_1); break;
case 2: emit_write_byte_1(emit, MP_BC_STORE_FAST_2); break;
default: emit_write_byte_1_uint(emit, MP_BC_STORE_FAST_N, local_num); break;
}
}
static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, -1);
emit_write_byte_1_uint(emit, PYBC_STORE_DEREF, local_num);
emit_write_byte_1_uint(emit, MP_BC_STORE_DEREF, local_num);
}
static void emit_bc_store_name(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr);
emit_write_byte_1_qstr(emit, MP_BC_STORE_NAME, qstr);
}
static void emit_bc_store_global(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr);
emit_write_byte_1_qstr(emit, MP_BC_STORE_GLOBAL, qstr);
}
static void emit_bc_store_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -2);
emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr);
emit_write_byte_1_qstr(emit, MP_BC_STORE_ATTR, qstr);
}
static void emit_bc_store_subscr(emit_t *emit) {
emit_pre(emit, -3);
emit_write_byte_1(emit, PYBC_STORE_SUBSCR);
emit_write_byte_1(emit, MP_BC_STORE_SUBSCR);
}
static void emit_bc_store_locals(emit_t *emit) {
// not needed
emit_pre(emit, -1);
emit_write_byte_1(emit, PYBC_POP_TOP);
emit_write_byte_1(emit, MP_BC_POP_TOP);
}
static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) {
assert(local_num >= 0);
emit_pre(emit, 0);
emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num);
emit_write_byte_1_uint(emit, MP_BC_DELETE_FAST_N, local_num);
}
static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, local_num);
emit_write_byte_1_qstr(emit, MP_BC_DELETE_DEREF, local_num);
}
static void emit_bc_delete_name(emit_t *emit, qstr qstr) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr);
emit_write_byte_1_qstr(emit, MP_BC_DELETE_NAME, qstr);
}
static void emit_bc_delete_global(emit_t *emit, qstr qstr) {
emit_pre(emit, 0);
emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr);
emit_write_byte_1_qstr(emit, MP_BC_DELETE_GLOBAL, qstr);
}
static void emit_bc_delete_attr(emit_t *emit, qstr qstr) {
emit_pre(emit, -1);
emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr);
emit_write_byte_1_qstr(emit, MP_BC_DELETE_ATTR, qstr);
}
static void emit_bc_delete_subscr(emit_t *emit) {
emit_pre(emit, -2);
emit_write_byte_1(emit, PYBC_DELETE_SUBSCR);
emit_write_byte_1(emit, MP_BC_DELETE_SUBSCR);
}
static void emit_bc_dup_top(emit_t *emit) {
emit_pre(emit, 1);
emit_write_byte_1(emit, PYBC_DUP_TOP);
emit_write_byte_1(emit, MP_BC_DUP_TOP);
}
static void emit_bc_dup_top_two(emit_t *emit) {
emit_pre(emit, 2);
emit_write_byte_1(emit, PYBC_DUP_TOP_TWO);
emit_write_byte_1(emit, MP_BC_DUP_TOP_TWO);
}
static void emit_bc_pop_top(emit_t *emit) {
emit_pre(emit, -1);
emit_write_byte_1(emit, PYBC_POP_TOP);
emit_write_byte_1(emit, MP_BC_POP_TOP);
}
static void emit_bc_rot_two(emit_t *emit) {
emit_pre(emit, 0);
emit_write_byte_1(emit, PYBC_ROT_TWO);
emit_write_byte_1(emit, MP_BC_ROT_TWO);
}
static void emit_bc_rot_three(emit_t *emit) {
emit_pre(emit, 0);
emit_write_byte_1(emit, PYBC_ROT_THREE);
emit_write_byte_1(emit, MP_BC_ROT_THREE);
}
static void emit_bc_jump(emit_t *emit, int label) {
emit_pre(emit, 0);
emit_write_byte_1_signed_label(emit, PYBC_JUMP, label);
emit_write_byte_1_signed_label(emit, MP_BC_JUMP, label);
}
static void emit_bc_pop_jump_if_true(emit_t *emit, int label) {
emit_pre(emit, -1);
emit_write_byte_1_signed_label(emit, PYBC_POP_JUMP_IF_TRUE, label);
emit_write_byte_1_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label);
}
static void emit_bc_pop_jump_if_false(emit_t *emit, int label) {
emit_pre(emit, -1);
emit_write_byte_1_signed_label(emit, PYBC_POP_JUMP_IF_FALSE, label);
emit_write_byte_1_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label);
}
static void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) {
emit_pre(emit, -1);
emit_write_byte_1_signed_label(emit, PYBC_JUMP_IF_TRUE_OR_POP, label);
emit_write_byte_1_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label);
}
static void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) {
emit_pre(emit, -1);
emit_write_byte_1_signed_label(emit, PYBC_JUMP_IF_FALSE_OR_POP, label);
emit_write_byte_1_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label);
}
static void emit_bc_setup_loop(emit_t *emit, int label) {
emit_pre(emit, 0);
emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_LOOP, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_LOOP, label);
}
static void emit_bc_break_loop(emit_t *emit, int label) {
emit_pre(emit, 0);
emit_write_byte_1_unsigned_label(emit, PYBC_BREAK_LOOP, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_BREAK_LOOP, label);
}
static void emit_bc_continue_loop(emit_t *emit, int label) {
emit_pre(emit, 0);
emit_write_byte_1_unsigned_label(emit, PYBC_CONTINUE_LOOP, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_CONTINUE_LOOP, label);
}
static void emit_bc_setup_with(emit_t *emit, int label) {
emit_pre(emit, 7);
emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_WITH, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_WITH, label);
}
static void emit_bc_with_cleanup(emit_t *emit) {
emit_pre(emit, -7);
emit_write_byte_1(emit, PYBC_WITH_CLEANUP);
emit_write_byte_1(emit, MP_BC_WITH_CLEANUP);
}
static void emit_bc_setup_except(emit_t *emit, int label) {
emit_pre(emit, 6);
emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_EXCEPT, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label);
}
static void emit_bc_setup_finally(emit_t *emit, int label) {
emit_pre(emit, 6);
emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_FINALLY, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_FINALLY, label);
}
static void emit_bc_end_finally(emit_t *emit) {
emit_pre(emit, -1);
emit_write_byte_1(emit, PYBC_END_FINALLY);
emit_write_byte_1(emit, MP_BC_END_FINALLY);
}
static void emit_bc_get_iter(emit_t *emit) {
emit_pre(emit, 0);
emit_write_byte_1(emit, PYBC_GET_ITER);
emit_write_byte_1(emit, MP_BC_GET_ITER);
}
static void emit_bc_for_iter(emit_t *emit, int label) {
emit_pre(emit, 1);
emit_write_byte_1_unsigned_label(emit, PYBC_FOR_ITER, label);
emit_write_byte_1_unsigned_label(emit, MP_BC_FOR_ITER, label);
}
static void emit_bc_for_iter_end(emit_t *emit) {
@ -496,104 +496,104 @@ static void emit_bc_for_iter_end(emit_t *emit) {
static void emit_bc_pop_block(emit_t *emit) {
emit_pre(emit, 0);
emit_write_byte_1(emit, PYBC_POP_BLOCK);
emit_write_byte_1(emit, MP_BC_POP_BLOCK);
}
static void emit_bc_pop_except(emit_t *emit) {
emit_pre(emit, 0);
emit_write_byte_1(emit, PYBC_POP_EXCEPT);
emit_write_byte_1(emit, MP_BC_POP_EXCEPT);
}
static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) {
emit_pre(emit, 0);
emit_write_byte_1_byte(emit, PYBC_UNARY_OP, op);
emit_write_byte_1_byte(emit, MP_BC_UNARY_OP, op);
}
static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
emit_pre(emit, -1);
emit_write_byte_1_byte(emit, PYBC_BINARY_OP, op);
emit_write_byte_1_byte(emit, MP_BC_BINARY_OP, op);
}
static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) {
emit_pre(emit, -1);
emit_write_byte_1_byte(emit, PYBC_COMPARE_OP, op);
emit_write_byte_1_byte(emit, MP_BC_COMPARE_OP, op);
}
static void emit_bc_build_tuple(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, 1 - n_args);
emit_write_byte_1_uint(emit, PYBC_BUILD_TUPLE, n_args);
emit_write_byte_1_uint(emit, MP_BC_BUILD_TUPLE, n_args);
}
static void emit_bc_build_list(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, 1 - n_args);
emit_write_byte_1_uint(emit, PYBC_BUILD_LIST, n_args);
emit_write_byte_1_uint(emit, MP_BC_BUILD_LIST, n_args);
}
static void emit_bc_list_append(emit_t *emit, int list_stack_index) {
assert(list_stack_index >= 0);
emit_pre(emit, -1);
emit_write_byte_1_uint(emit, PYBC_LIST_APPEND, list_stack_index);
emit_write_byte_1_uint(emit, MP_BC_LIST_APPEND, list_stack_index);
}
static void emit_bc_build_map(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, 1);
emit_write_byte_1_uint(emit, PYBC_BUILD_MAP, n_args);
emit_write_byte_1_uint(emit, MP_BC_BUILD_MAP, n_args);
}
static void emit_bc_store_map(emit_t *emit) {
emit_pre(emit, -2);
emit_write_byte_1(emit, PYBC_STORE_MAP);
emit_write_byte_1(emit, MP_BC_STORE_MAP);
}
static void emit_bc_map_add(emit_t *emit, int map_stack_index) {
assert(map_stack_index >= 0);
emit_pre(emit, -2);
emit_write_byte_1_uint(emit, PYBC_MAP_ADD, map_stack_index);
emit_write_byte_1_uint(emit, MP_BC_MAP_ADD, map_stack_index);
}
static void emit_bc_build_set(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, 1 - n_args);
emit_write_byte_1_uint(emit, PYBC_BUILD_SET, n_args);
emit_write_byte_1_uint(emit, MP_BC_BUILD_SET, n_args);
}
static void emit_bc_set_add(emit_t *emit, int set_stack_index) {
assert(set_stack_index >= 0);
emit_pre(emit, -1);
emit_write_byte_1_uint(emit, PYBC_SET_ADD, set_stack_index);
emit_write_byte_1_uint(emit, MP_BC_SET_ADD, set_stack_index);
}
static void emit_bc_build_slice(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, 1 - n_args);
emit_write_byte_1_uint(emit, PYBC_BUILD_SLICE, n_args);
emit_write_byte_1_uint(emit, MP_BC_BUILD_SLICE, n_args);
}
static void emit_bc_unpack_sequence(emit_t *emit, int n_args) {
assert(n_args >= 0);
emit_pre(emit, -1 + n_args);
emit_write_byte_1_uint(emit, PYBC_UNPACK_SEQUENCE, n_args);
emit_write_byte_1_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args);
}
static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
assert(n_left >=0 && n_right >= 0);
emit_pre(emit, -1 + n_left + n_right + 1);
emit_write_byte_1_uint(emit, PYBC_UNPACK_EX, n_left | (n_right << 8));
emit_write_byte_1_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8));
}
static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
assert(n_default_params == 0 && n_dict_params == 0);
emit_pre(emit, 1);
emit_write_byte_1_uint(emit, PYBC_MAKE_FUNCTION, scope->unique_code_id);
emit_write_byte_1_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
}
static void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
assert(n_default_params == 0 && n_dict_params == 0);
emit_pre(emit, 0);
emit_write_byte_1_uint(emit, PYBC_MAKE_CLOSURE, scope->unique_code_id);
emit_write_byte_1_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
}
static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
@ -608,15 +608,15 @@ static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword,
int op;
if (have_star_arg) {
if (have_dbl_star_arg) {
op = PYBC_CALL_FUNCTION_VAR_KW;
op = MP_BC_CALL_FUNCTION_VAR_KW;
} else {
op = PYBC_CALL_FUNCTION_VAR;
op = MP_BC_CALL_FUNCTION_VAR;
}
} else {
if (have_dbl_star_arg) {
op = PYBC_CALL_FUNCTION_KW;
op = MP_BC_CALL_FUNCTION_KW;
} else {
op = PYBC_CALL_FUNCTION;
op = MP_BC_CALL_FUNCTION;
}
}
emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
@ -634,15 +634,15 @@ static void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, b
int op;
if (have_star_arg) {
if (have_dbl_star_arg) {
op = PYBC_CALL_METHOD_VAR_KW;
op = MP_BC_CALL_METHOD_VAR_KW;
} else {
op = PYBC_CALL_METHOD_VAR;
op = MP_BC_CALL_METHOD_VAR;
}
} else {
if (have_dbl_star_arg) {
op = PYBC_CALL_METHOD_KW;
op = MP_BC_CALL_METHOD_KW;
} else {
op = PYBC_CALL_METHOD;
op = MP_BC_CALL_METHOD;
}
}
emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints
@ -651,13 +651,13 @@ static void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, b
static void emit_bc_return_value(emit_t *emit) {
emit_pre(emit, -1);
emit->last_emit_was_return_value = true;
emit_write_byte_1(