|
|
@ -167,6 +167,110 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i |
|
|
|
volatile mp_obj_t inject_exc) { |
|
|
|
// careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think)
|
|
|
|
|
|
|
|
#ifdef MICROPY_USE_COMPUTED_GOTO |
|
|
|
|
|
|
|
# define DISPATCH() do { \ |
|
|
|
save_ip = ip; \ |
|
|
|
op = *ip++; \ |
|
|
|
goto *entry_table[op]; \ |
|
|
|
} while(0) |
|
|
|
# define ENTRY(op) entry_##op |
|
|
|
# define ENTRY_DEFAULT entry_default |
|
|
|
|
|
|
|
static void* entry_table[256] = { |
|
|
|
[0 ... 255] = &&entry_default, |
|
|
|
[MP_BC_LOAD_CONST_FALSE] = &&entry_MP_BC_LOAD_CONST_FALSE, |
|
|
|
[MP_BC_LOAD_CONST_NONE] = &&entry_MP_BC_LOAD_CONST_NONE, |
|
|
|
[MP_BC_LOAD_CONST_TRUE] = &&entry_MP_BC_LOAD_CONST_TRUE, |
|
|
|
[MP_BC_LOAD_CONST_ELLIPSIS] = &&entry_MP_BC_LOAD_CONST_ELLIPSIS, |
|
|
|
[MP_BC_LOAD_CONST_SMALL_INT] = &&entry_MP_BC_LOAD_CONST_SMALL_INT, |
|
|
|
[MP_BC_LOAD_CONST_INT] = &&entry_MP_BC_LOAD_CONST_INT, |
|
|
|
[MP_BC_LOAD_CONST_DEC] = &&entry_MP_BC_LOAD_CONST_DEC, |
|
|
|
[MP_BC_LOAD_CONST_ID] = &&entry_MP_BC_LOAD_CONST_ID, |
|
|
|
[MP_BC_LOAD_CONST_BYTES] = &&entry_MP_BC_LOAD_CONST_BYTES, |
|
|
|
[MP_BC_LOAD_CONST_STRING] = &&entry_MP_BC_LOAD_CONST_STRING, |
|
|
|
[MP_BC_LOAD_NULL] = &&entry_MP_BC_LOAD_NULL, |
|
|
|
[MP_BC_LOAD_FAST_0] = &&entry_MP_BC_LOAD_FAST_0, |
|
|
|
[MP_BC_LOAD_FAST_1] = &&entry_MP_BC_LOAD_FAST_1, |
|
|
|
[MP_BC_LOAD_FAST_2] = &&entry_MP_BC_LOAD_FAST_2, |
|
|
|
[MP_BC_LOAD_FAST_N] = &&entry_MP_BC_LOAD_FAST_N, |
|
|
|
[MP_BC_LOAD_DEREF] = &&entry_MP_BC_LOAD_DEREF, |
|
|
|
[MP_BC_LOAD_NAME] = &&entry_MP_BC_LOAD_NAME, |
|
|
|
[MP_BC_LOAD_GLOBAL] = &&entry_MP_BC_LOAD_GLOBAL, |
|
|
|
[MP_BC_LOAD_ATTR] = &&entry_MP_BC_LOAD_ATTR, |
|
|
|
[MP_BC_LOAD_METHOD] = &&entry_MP_BC_LOAD_METHOD, |
|
|
|
[MP_BC_LOAD_BUILD_CLASS] = &&entry_MP_BC_LOAD_BUILD_CLASS, |
|
|
|
[MP_BC_STORE_FAST_0] = &&entry_MP_BC_STORE_FAST_0, |
|
|
|
[MP_BC_STORE_FAST_1] = &&entry_MP_BC_STORE_FAST_1, |
|
|
|
[MP_BC_STORE_FAST_2] = &&entry_MP_BC_STORE_FAST_2, |
|
|
|
[MP_BC_STORE_FAST_N] = &&entry_MP_BC_STORE_FAST_N, |
|
|
|
[MP_BC_STORE_DEREF] = &&entry_MP_BC_STORE_DEREF, |
|
|
|
[MP_BC_STORE_NAME] = &&entry_MP_BC_STORE_NAME, |
|
|
|
[MP_BC_STORE_GLOBAL] = &&entry_MP_BC_STORE_GLOBAL, |
|
|
|
[MP_BC_STORE_ATTR] = &&entry_MP_BC_STORE_ATTR, |
|
|
|
[MP_BC_STORE_SUBSCR] = &&entry_MP_BC_STORE_SUBSCR, |
|
|
|
[MP_BC_DELETE_FAST] = &&entry_MP_BC_DELETE_FAST, |
|
|
|
[MP_BC_DELETE_DEREF] = &&entry_MP_BC_DELETE_DEREF, |
|
|
|
[MP_BC_DELETE_NAME] = &&entry_MP_BC_DELETE_NAME, |
|
|
|
[MP_BC_DELETE_GLOBAL] = &&entry_MP_BC_DELETE_GLOBAL, |
|
|
|
[MP_BC_DUP_TOP] = &&entry_MP_BC_DUP_TOP, |
|
|
|
[MP_BC_DUP_TOP_TWO] = &&entry_MP_BC_DUP_TOP_TWO, |
|
|
|
[MP_BC_POP_TOP] = &&entry_MP_BC_POP_TOP, |
|
|
|
[MP_BC_ROT_TWO] = &&entry_MP_BC_ROT_TWO, |
|
|
|
[MP_BC_ROT_THREE] = &&entry_MP_BC_ROT_THREE, |
|
|
|
[MP_BC_JUMP] = &&entry_MP_BC_JUMP, |
|
|
|
[MP_BC_POP_JUMP_IF_TRUE] = &&entry_MP_BC_POP_JUMP_IF_TRUE, |
|
|
|
[MP_BC_POP_JUMP_IF_FALSE] = &&entry_MP_BC_POP_JUMP_IF_FALSE, |
|
|
|
[MP_BC_JUMP_IF_TRUE_OR_POP] = &&entry_MP_BC_JUMP_IF_TRUE_OR_POP, |
|
|
|
[MP_BC_JUMP_IF_FALSE_OR_POP] = &&entry_MP_BC_JUMP_IF_FALSE_OR_POP, |
|
|
|
// [MP_BC_SETUP_LOOP] = &&entry_MP_BC_SETUP_LOOP,
|
|
|
|
[MP_BC_SETUP_WITH] = &&entry_MP_BC_SETUP_WITH, |
|
|
|
[MP_BC_WITH_CLEANUP] = &&entry_MP_BC_WITH_CLEANUP, |
|
|
|
[MP_BC_UNWIND_JUMP] = &&entry_MP_BC_UNWIND_JUMP, |
|
|
|
[MP_BC_SETUP_EXCEPT] = &&entry_MP_BC_SETUP_EXCEPT, |
|
|
|
[MP_BC_SETUP_FINALLY] = &&entry_MP_BC_SETUP_FINALLY, |
|
|
|
[MP_BC_END_FINALLY] = &&entry_MP_BC_END_FINALLY, |
|
|
|
[MP_BC_GET_ITER] = &&entry_MP_BC_GET_ITER, |
|
|
|
[MP_BC_FOR_ITER] = &&entry_MP_BC_FOR_ITER, |
|
|
|
[MP_BC_POP_BLOCK] = &&entry_MP_BC_POP_BLOCK, |
|
|
|
[MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT, |
|
|
|
[MP_BC_NOT] = &&entry_MP_BC_NOT, |
|
|
|
[MP_BC_UNARY_OP] = &&entry_MP_BC_UNARY_OP, |
|
|
|
[MP_BC_BINARY_OP] = &&entry_MP_BC_BINARY_OP, |
|
|
|
[MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE, |
|
|
|
[MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST, |
|
|
|
[MP_BC_LIST_APPEND] = &&entry_MP_BC_LIST_APPEND, |
|
|
|
[MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP, |
|
|
|
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP, |
|
|
|
[MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD, |
|
|
|
[MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET, |
|
|
|
[MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD, |
|
|
|
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE, |
|
|
|
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE, |
|
|
|
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX, |
|
|
|
[MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION, |
|
|
|
[MP_BC_MAKE_FUNCTION_DEFARGS] = &&entry_MP_BC_MAKE_FUNCTION_DEFARGS, |
|
|
|
[MP_BC_MAKE_CLOSURE] = &&entry_MP_BC_MAKE_CLOSURE, |
|
|
|
[MP_BC_MAKE_CLOSURE_DEFARGS] = &&entry_MP_BC_MAKE_CLOSURE_DEFARGS, |
|
|
|
[MP_BC_CALL_FUNCTION] = &&entry_MP_BC_CALL_FUNCTION, |
|
|
|
[MP_BC_CALL_FUNCTION_VAR_KW] = &&entry_MP_BC_CALL_FUNCTION_VAR_KW, |
|
|
|
[MP_BC_CALL_METHOD] = &&entry_MP_BC_CALL_METHOD, |
|
|
|
[MP_BC_CALL_METHOD_VAR_KW] = &&entry_MP_BC_CALL_METHOD_VAR_KW, |
|
|
|
[MP_BC_RETURN_VALUE] = &&entry_MP_BC_RETURN_VALUE, |
|
|
|
[MP_BC_RAISE_VARARGS] = &&entry_MP_BC_RAISE_VARARGS, |
|
|
|
[MP_BC_YIELD_VALUE] = &&entry_MP_BC_YIELD_VALUE, |
|
|
|
[MP_BC_YIELD_FROM] = &&entry_MP_BC_YIELD_FROM, |
|
|
|
[MP_BC_IMPORT_NAME] = &&entry_MP_BC_IMPORT_NAME, |
|
|
|
[MP_BC_IMPORT_FROM] = &&entry_MP_BC_IMPORT_FROM, |
|
|
|
[MP_BC_IMPORT_STAR] = &&entry_MP_BC_IMPORT_STAR, |
|
|
|
}; |
|
|
|
#else |
|
|
|
# define DISPATCH() break |
|
|
|
# define ENTRY(op) case op |
|
|
|
# define ENTRY_DEFAULT default |
|
|
|
#endif |
|
|
|
|
|
|
|
int op = 0; |
|
|
|
const byte *ip = *ip_in_out; |
|
|
|
mp_obj_t *sp = *sp_in_out; |
|
|
|
machine_uint_t unum; |
|
|
@ -195,27 +299,33 @@ outer_dispatch_loop: |
|
|
|
// loop to execute byte code
|
|
|
|
for (;;) { |
|
|
|
dispatch_loop: |
|
|
|
#ifdef MICROPY_USE_COMPUTED_GOTO |
|
|
|
DISPATCH(); |
|
|
|
#else |
|
|
|
save_ip = ip; |
|
|
|
int op = *ip++; |
|
|
|
//printf("ip=%p sp=%p op=%u\n", save_ip, sp, op);
|
|
|
|
op = *ip++; |
|
|
|
|
|
|
|
switch (op) { |
|
|
|
case MP_BC_LOAD_CONST_FALSE: |
|
|
|
#endif |
|
|
|
//printf("ip=%p sp=%p op=%u\n", save_ip, sp, op);
|
|
|
|
|
|
|
|
ENTRY(MP_BC_LOAD_CONST_FALSE): |
|
|
|
PUSH(mp_const_false); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_NONE: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_NONE): |
|
|
|
PUSH(mp_const_none); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_TRUE: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_TRUE): |
|
|
|
PUSH(mp_const_true); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_ELLIPSIS: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_ELLIPSIS): |
|
|
|
PUSH((mp_obj_t)&mp_const_ellipsis_obj); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_SMALL_INT: { |
|
|
|
ENTRY(MP_BC_LOAD_CONST_SMALL_INT): { |
|
|
|
machine_int_t num = 0; |
|
|
|
if ((ip[0] & 0x40) != 0) { |
|
|
|
// Number is negative
|
|
|
@ -225,51 +335,51 @@ dispatch_loop: |
|
|
|
num = (num << 7) | (*ip & 0x7f); |
|
|
|
} while ((*ip++ & 0x80) != 0); |
|
|
|
PUSH(MP_OBJ_NEW_SMALL_INT(num)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
} |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_INT: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_INT): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_obj_new_int_from_long_str(qstr_str(qst))); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_DEC: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_DEC): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_const_dec(qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_ID: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_ID): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_const_str(qst)); // TODO
|
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_BYTES: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_BYTES): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_const_bytes(qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_CONST_STRING: |
|
|
|
ENTRY(MP_BC_LOAD_CONST_STRING): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_const_str(qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_NULL: |
|
|
|
ENTRY(MP_BC_LOAD_NULL): |
|
|
|
PUSH(MP_OBJ_NULL); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_FAST_0: |
|
|
|
ENTRY(MP_BC_LOAD_FAST_0): |
|
|
|
obj1 = fastn[0]; |
|
|
|
goto load_check; |
|
|
|
|
|
|
|
case MP_BC_LOAD_FAST_1: |
|
|
|
ENTRY(MP_BC_LOAD_FAST_1): |
|
|
|
obj1 = fastn[-1]; |
|
|
|
goto load_check; |
|
|
|
|
|
|
|
case MP_BC_LOAD_FAST_2: |
|
|
|
ENTRY(MP_BC_LOAD_FAST_2): |
|
|
|
obj1 = fastn[-2]; |
|
|
|
goto load_check; |
|
|
|
|
|
|
|
case MP_BC_LOAD_FAST_N: |
|
|
|
ENTRY(MP_BC_LOAD_FAST_N): |
|
|
|
DECODE_UINT; |
|
|
|
obj1 = fastn[-unum]; |
|
|
|
load_check: |
|
|
@ -278,189 +388,189 @@ dispatch_loop: |
|
|
|
nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment")); |
|
|
|
} |
|
|
|
PUSH(obj1); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_DEREF: |
|
|
|
ENTRY(MP_BC_LOAD_DEREF): |
|
|
|
DECODE_UINT; |
|
|
|
obj1 = mp_obj_cell_get(fastn[-unum]); |
|
|
|
goto load_check; |
|
|
|
|
|
|
|
case MP_BC_LOAD_NAME: |
|
|
|
ENTRY(MP_BC_LOAD_NAME): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_name(qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_GLOBAL: |
|
|
|
ENTRY(MP_BC_LOAD_GLOBAL): |
|
|
|
DECODE_QSTR; |
|
|
|
PUSH(mp_load_global(qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_ATTR: |
|
|
|
ENTRY(MP_BC_LOAD_ATTR): |
|
|
|
DECODE_QSTR; |
|
|
|
SET_TOP(mp_load_attr(TOP(), qst)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_METHOD: |
|
|
|
ENTRY(MP_BC_LOAD_METHOD): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_load_method(*sp, qst, sp); |
|
|
|
sp += 1; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LOAD_BUILD_CLASS: |
|
|
|
ENTRY(MP_BC_LOAD_BUILD_CLASS): |
|
|
|
PUSH(mp_load_build_class()); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_FAST_0: |
|
|
|
ENTRY(MP_BC_STORE_FAST_0): |
|
|
|
fastn[0] = POP(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_FAST_1: |
|
|
|
ENTRY(MP_BC_STORE_FAST_1): |
|
|
|
fastn[-1] = POP(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_FAST_2: |
|
|
|
ENTRY(MP_BC_STORE_FAST_2): |
|
|
|
fastn[-2] = POP(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_FAST_N: |
|
|
|
ENTRY(MP_BC_STORE_FAST_N): |
|
|
|
DECODE_UINT; |
|
|
|
fastn[-unum] = POP(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_DEREF: |
|
|
|
ENTRY(MP_BC_STORE_DEREF): |
|
|
|
DECODE_UINT; |
|
|
|
mp_obj_cell_set(fastn[-unum], POP()); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_NAME: |
|
|
|
ENTRY(MP_BC_STORE_NAME): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_store_name(qst, POP()); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_GLOBAL: |
|
|
|
ENTRY(MP_BC_STORE_GLOBAL): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_store_global(qst, POP()); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_ATTR: |
|
|
|
ENTRY(MP_BC_STORE_ATTR): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_store_attr(sp[0], qst, sp[-1]); |
|
|
|
sp -= 2; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_SUBSCR: |
|
|
|
ENTRY(MP_BC_STORE_SUBSCR): |
|
|
|
mp_store_subscr(sp[-1], sp[0], sp[-2]); |
|
|
|
sp -= 3; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DELETE_FAST: |
|
|
|
ENTRY(MP_BC_DELETE_FAST): |
|
|
|
DECODE_UINT; |
|
|
|
if (fastn[-unum] == MP_OBJ_NULL) { |
|
|
|
goto local_name_error; |
|
|
|
} |
|
|
|
fastn[-unum] = MP_OBJ_NULL; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DELETE_DEREF: |
|
|
|
ENTRY(MP_BC_DELETE_DEREF): |
|
|
|
DECODE_UINT; |
|
|
|
if (mp_obj_cell_get(fastn[-unum]) == MP_OBJ_NULL) { |
|
|
|
goto local_name_error; |
|
|
|
} |
|
|
|
mp_obj_cell_set(fastn[-unum], MP_OBJ_NULL); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DELETE_NAME: |
|
|
|
ENTRY(MP_BC_DELETE_NAME): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_delete_name(qst); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DELETE_GLOBAL: |
|
|
|
ENTRY(MP_BC_DELETE_GLOBAL): |
|
|
|
DECODE_QSTR; |
|
|
|
mp_delete_global(qst); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DUP_TOP: |
|
|
|
ENTRY(MP_BC_DUP_TOP): |
|
|
|
obj1 = TOP(); |
|
|
|
PUSH(obj1); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_DUP_TOP_TWO: |
|
|
|
ENTRY(MP_BC_DUP_TOP_TWO): |
|
|
|
sp += 2; |
|
|
|
sp[0] = sp[-2]; |
|
|
|
sp[-1] = sp[-3]; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_POP_TOP: |
|
|
|
ENTRY(MP_BC_POP_TOP): |
|
|
|
sp -= 1; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_ROT_TWO: |
|
|
|
ENTRY(MP_BC_ROT_TWO): |
|
|
|
obj1 = sp[0]; |
|
|
|
sp[0] = sp[-1]; |
|
|
|
sp[-1] = obj1; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_ROT_THREE: |
|
|
|
ENTRY(MP_BC_ROT_THREE): |
|
|
|
obj1 = sp[0]; |
|
|
|
sp[0] = sp[-1]; |
|
|
|
sp[-1] = sp[-2]; |
|
|
|
sp[-2] = obj1; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_JUMP: |
|
|
|
ENTRY(MP_BC_JUMP): |
|
|
|
DECODE_SLABEL; |
|
|
|
ip += unum; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_POP_JUMP_IF_TRUE: |
|
|
|
ENTRY(MP_BC_POP_JUMP_IF_TRUE): |
|
|
|
DECODE_SLABEL; |
|
|
|
if (mp_obj_is_true(POP())) { |
|
|
|
ip += unum; |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_POP_JUMP_IF_FALSE: |
|
|
|
ENTRY(MP_BC_POP_JUMP_IF_FALSE): |
|
|
|
DECODE_SLABEL; |
|
|
|
if (!mp_obj_is_true(POP())) { |
|
|
|
ip += unum; |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_JUMP_IF_TRUE_OR_POP: |
|
|
|
ENTRY(MP_BC_JUMP_IF_TRUE_OR_POP): |
|
|
|
DECODE_SLABEL; |
|
|
|
if (mp_obj_is_true(TOP())) { |
|
|
|
ip += unum; |
|
|
|
} else { |
|
|
|
sp--; |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_JUMP_IF_FALSE_OR_POP: |
|
|
|
ENTRY(MP_BC_JUMP_IF_FALSE_OR_POP): |
|
|
|
DECODE_SLABEL; |
|
|
|
if (mp_obj_is_true(TOP())) { |
|
|
|
sp--; |
|
|
|
} else { |
|
|
|
ip += unum; |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
/* we are trying to get away without using this opcode
|
|
|
|
case MP_BC_SETUP_LOOP: |
|
|
|
ENTRY(MP_BC_SETUP_LOOP): |
|
|
|
DECODE_UINT; |
|
|
|
// push_block(MP_BC_SETUP_LOOP, ip + unum, sp)
|
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
*/ |
|
|
|
|
|
|
|
case MP_BC_SETUP_WITH: |
|
|
|
ENTRY(MP_BC_SETUP_WITH): |
|
|
|
obj1 = TOP(); |
|
|
|
SET_TOP(mp_load_attr(obj1, MP_QSTR___exit__)); |
|
|
|
mp_load_method(obj1, MP_QSTR___enter__, sp + 1); |
|
|
|
obj2 = mp_call_method_n_kw(0, 0, sp + 1); |
|
|
|
PUSH_EXC_BLOCK(); |
|
|
|
PUSH(obj2); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_WITH_CLEANUP: { |
|
|
|
ENTRY(MP_BC_WITH_CLEANUP): { |
|
|
|
// Arriving here, there's "exception control block" on top of stack,
|
|
|
|
// and __exit__ bound method underneath it. Bytecode calls __exit__,
|
|
|
|
// and "deletes" it off stack, shifting "exception control block"
|
|
|
@ -517,10 +627,10 @@ dispatch_loop: |
|
|
|
} else { |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
} |
|
|
|
|
|
|
|
case MP_BC_UNWIND_JUMP: |
|
|
|
ENTRY(MP_BC_UNWIND_JUMP): |
|
|
|
DECODE_SLABEL; |
|
|
|
PUSH((void*)(ip + unum)); // push destination ip for jump
|
|
|
|
PUSH((void*)(machine_uint_t)(*ip)); // push number of exception handlers to unwind
|
|
|
@ -543,15 +653,15 @@ unwind_jump: |
|
|
|
exc_sp--; |
|
|
|
} |
|
|
|
ip = (const byte*)POP(); // pop destination ip for jump
|
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
// matched against: POP_BLOCK or POP_EXCEPT (anything else?)
|
|
|
|
case MP_BC_SETUP_EXCEPT: |
|
|
|
case MP_BC_SETUP_FINALLY: |
|
|
|
ENTRY(MP_BC_SETUP_EXCEPT): |
|
|
|
ENTRY(MP_BC_SETUP_FINALLY): |
|
|
|
PUSH_EXC_BLOCK(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_END_FINALLY: |
|
|
|
ENTRY(MP_BC_END_FINALLY): |
|
|
|
// not fully implemented
|
|
|
|
// if TOS is an exception, reraises the exception (3 values on TOS)
|
|
|
|
// if TOS is None, just pops it and continues
|
|
|
@ -576,13 +686,13 @@ unwind_jump: |
|
|
|
} else { |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_GET_ITER: |
|
|
|
ENTRY(MP_BC_GET_ITER): |
|
|
|
SET_TOP(mp_getiter(TOP())); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_FOR_ITER: |
|
|
|
ENTRY(MP_BC_FOR_ITER): |
|
|
|
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
|
|
|
|
obj1 = mp_iternext_allow_raise(TOP()); |
|
|
|
if (obj1 == MP_OBJ_NULL) { |
|
|
@ -591,17 +701,17 @@ unwind_jump: |
|
|
|
} else { |
|
|
|
PUSH(obj1); // push the next iteration value
|
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
// matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH
|
|
|
|
case MP_BC_POP_BLOCK: |
|
|
|
ENTRY(MP_BC_POP_BLOCK): |
|
|
|
// we are exiting an exception handler, so pop the last one of the exception-stack
|
|
|
|
assert(exc_sp >= exc_stack); |
|
|
|
POP_EXC_BLOCK(); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
// matched against: SETUP_EXCEPT
|
|
|
|
case MP_BC_POP_EXCEPT: |
|
|
|
ENTRY(MP_BC_POP_EXCEPT): |
|
|
|
// TODO need to work out how blocks work etc
|
|
|
|
// pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
|
|
|
|
assert(exc_sp >= exc_stack); |
|
|
@ -610,79 +720,79 @@ unwind_jump: |
|
|
|
//exc_sp--; // discard ip
|
|
|
|
POP_EXC_BLOCK(); |
|
|
|
//sp -= 3; // pop 3 exception values
|
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_NOT: |
|
|
|
ENTRY(MP_BC_NOT): |
|
|
|
if (TOP() == mp_const_true) { |
|
|
|
SET_TOP(mp_const_false); |
|
|
|
} else { |
|
|
|
SET_TOP(mp_const_true); |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_UNARY_OP: |
|
|
|
ENTRY(MP_BC_UNARY_OP): |
|
|
|
unum = *ip++; |
|
|
|
SET_TOP(mp_unary_op(unum, TOP())); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_BINARY_OP: |
|
|
|
ENTRY(MP_BC_BINARY_OP): |
|
|
|
unum = *ip++; |
|
|
|
obj2 = POP(); |
|
|
|
obj1 = TOP(); |
|
|
|
SET_TOP(mp_binary_op(unum, obj1, obj2)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_BUILD_TUPLE: |
|
|
|
ENTRY(MP_BC_BUILD_TUPLE): |
|
|
|
DECODE_UINT; |
|
|
|
sp -= unum - 1; |
|
|
|
SET_TOP(mp_obj_new_tuple(unum, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_BUILD_LIST: |
|
|
|
ENTRY(MP_BC_BUILD_LIST): |
|
|
|
DECODE_UINT; |
|
|
|
sp -= unum - 1; |
|
|
|
SET_TOP(mp_obj_new_list(unum, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_LIST_APPEND: |
|
|
|
ENTRY(MP_BC_LIST_APPEND): |
|
|
|
DECODE_UINT; |
|
|
|
// I think it's guaranteed by the compiler that sp[unum] is a list
|
|
|
|
mp_obj_list_append(sp[-unum], sp[0]); |
|
|
|
sp--; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_BUILD_MAP: |
|
|
|
ENTRY(MP_BC_BUILD_MAP): |
|
|
|
DECODE_UINT; |
|
|
|
PUSH(mp_obj_new_dict(unum)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_STORE_MAP: |
|
|
|
ENTRY(MP_BC_STORE_MAP): |
|
|
|
sp -= 2; |
|
|
|
mp_obj_dict_store(sp[0], sp[2], sp[1]); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_MAP_ADD: |
|
|
|
ENTRY(MP_BC_MAP_ADD): |
|
|
|
DECODE_UINT; |
|
|
|
// I think it's guaranteed by the compiler that sp[-unum - 1] is a map
|
|
|
|
mp_obj_dict_store(sp[-unum - 1], sp[0], sp[-1]); |
|
|
|
sp -= 2; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_BUILD_SET: |
|
|
|
ENTRY(MP_BC_BUILD_SET): |
|
|
|
DECODE_UINT; |
|
|
|
sp -= unum - 1; |
|
|
|
SET_TOP(mp_obj_new_set(unum, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_SET_ADD: |
|
|
|
ENTRY(MP_BC_SET_ADD): |
|
|
|
DECODE_UINT; |
|
|
|
// I think it's guaranteed by the compiler that sp[-unum] is a set
|
|
|
|
mp_obj_set_store(sp[-unum], sp[0]); |
|
|
|
sp--; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
#if MICROPY_ENABLE_SLICE |
|
|
|
case MP_BC_BUILD_SLICE: |
|
|
|
ENTRY(MP_BC_BUILD_SLICE): |
|
|
|
DECODE_UINT; |
|
|
|
if (unum == 2) { |
|
|
|
obj2 = POP(); |
|
|
@ -694,56 +804,56 @@ unwind_jump: |
|
|
|
fastn[0] = obj1; |
|
|
|
return MP_VM_RETURN_EXCEPTION; |
|
|
|
} |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
#endif |
|
|
|
|
|
|
|
case MP_BC_UNPACK_SEQUENCE: |
|
|
|
ENTRY(MP_BC_UNPACK_SEQUENCE): |
|
|
|
DECODE_UINT; |
|
|
|
mp_unpack_sequence(sp[0], unum, sp); |
|
|
|
sp += unum - 1; |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_UNPACK_EX: |
|
|
|
ENTRY(MP_BC_UNPACK_EX): |
|
|
|
DECODE_UINT; |
|
|
|
mp_unpack_ex(sp[0], unum, sp); |
|
|
|
sp += (unum & 0xff) + ((unum >> 8) & 0xff); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_MAKE_FUNCTION: |
|
|
|
ENTRY(MP_BC_MAKE_FUNCTION): |
|
|
|
DECODE_PTR; |
|
|
|
PUSH(mp_make_function_from_raw_code((mp_raw_code_t*)unum, MP_OBJ_NULL, MP_OBJ_NULL)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_MAKE_FUNCTION_DEFARGS: |
|
|
|
ENTRY(MP_BC_MAKE_FUNCTION_DEFARGS): |
|
|
|
DECODE_PTR; |
|
|
|
// Stack layout: def_tuple def_dict <- TOS
|
|
|
|
obj1 = POP(); |
|
|
|
SET_TOP(mp_make_function_from_raw_code((mp_raw_code_t*)unum, TOP(), obj1)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_MAKE_CLOSURE: |
|
|
|
ENTRY(MP_BC_MAKE_CLOSURE): |
|
|
|
DECODE_PTR; |
|
|
|
// Stack layout: closure_tuple <- TOS
|
|
|
|
SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_MAKE_CLOSURE_DEFARGS: |
|
|
|
ENTRY(MP_BC_MAKE_CLOSURE_DEFARGS): |
|
|
|
DECODE_PTR; |
|
|
|
// Stack layout: def_tuple def_dict closure_tuple <- TOS
|
|
|
|
obj1 = POP(); |
|
|
|
obj2 = POP(); |
|
|
|
SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, obj1, TOP(), obj2)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_CALL_FUNCTION: |
|
|
|
ENTRY(MP_BC_CALL_FUNCTION): |
|
|
|
DECODE_UINT; |
|
|
|
// unum & 0xff == n_positional
|
|
|
|
// (unum >> 8) & 0xff == n_keyword
|
|
|
|
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe); |
|
|
|
SET_TOP(mp_call_function_n_kw(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_CALL_FUNCTION_VAR_KW: |
|
|
|
ENTRY(MP_BC_CALL_FUNCTION_VAR_KW): |
|
|
|
DECODE_UINT; |
|
|
|
// unum & 0xff == n_positional
|
|
|
|
// (unum >> 8) & 0xff == n_keyword
|
|
|
@ -751,17 +861,17 @@ unwind_jump: |
|
|
|
// fun arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
|
|
|
|
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2; |
|
|
|
SET_TOP(mp_call_method_n_kw_var(false, unum, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_CALL_METHOD: |
|
|
|
ENTRY(MP_BC_CALL_METHOD): |
|
|
|
DECODE_UINT; |
|
|
|
// unum & 0xff == n_positional
|
|
|
|
// (unum >> 8) & 0xff == n_keyword
|
|
|
|
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 1; |
|
|
|
SET_TOP(mp_call_method_n_kw(unum & 0xff, (unum >> 8) & 0xff, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_CALL_METHOD_VAR_KW: |
|
|
|
ENTRY(MP_BC_CALL_METHOD_VAR_KW): |
|
|
|
DECODE_UINT; |
|
|
|
// unum & 0xff == n_positional
|
|
|
|
// (unum >> 8) & 0xff == n_keyword
|
|
|
@ -769,9 +879,9 @@ unwind_jump: |
|
|
|
// fun self arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
|
|
|
|
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 3; |
|
|
|
SET_TOP(mp_call_method_n_kw_var(true, unum, sp)); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_RETURN_VALUE: |
|
|
|
ENTRY(MP_BC_RETURN_VALUE): |
|
|
|
unwind_return: |
|
|
|
while (exc_sp >= exc_stack) { |
|
|
|
if (exc_sp->opcode == MP_BC_SETUP_FINALLY || exc_sp->opcode == MP_BC_SETUP_WITH) { |
|
|
@ -794,7 +904,7 @@ unwind_return: |
|
|
|
assert(exc_sp == exc_stack - 1); |
|
|
|
return MP_VM_RETURN_NORMAL; |
|
|
|
|
|
|
|
case MP_BC_RAISE_VARARGS: |
|
|
|
ENTRY(MP_BC_RAISE_VARARGS): |
|
|
|
unum = *ip++; |
|
|
|
assert(unum <= 1); |
|
|
|
if (unum == 0) { |
|
|
@ -814,7 +924,7 @@ unwind_return: |
|
|
|
} |
|
|
|
nlr_raise(mp_make_raise_obj(obj1)); |
|
|
|
|
|
|
|
case MP_BC_YIELD_VALUE: |
|
|
|
ENTRY(MP_BC_YIELD_VALUE): |
|
|
|
yield: |
|
|
|
nlr_pop(); |
|
|
|
*ip_in_out = ip; |
|
|
@ -822,7 +932,7 @@ yield: |
|
|
|
*exc_sp_in_out = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block); |
|
|
|
return MP_VM_RETURN_YIELD; |
|
|
|
|
|
|
|
case MP_BC_YIELD_FROM: { |
|
|
|
ENTRY(MP_BC_YIELD_FROM): { |
|
|
|
//#define EXC_MATCH(exc, type) MP_OBJ_IS_TYPE(exc, type)
|
|
|
|
#define EXC_MATCH(exc, type) mp_obj_exception_match(exc, type) |
|
|
|
#define GENERATOR_EXIT_IF_NEEDED(t) if (t != MP_OBJ_NULL && EXC_MATCH(t, &mp_type_GeneratorExit)) { nlr_raise(t); } |
|
|
@ -856,7 +966,7 @@ yield: |
|
|
|
// If we injected GeneratorExit downstream, then even
|
|
|
|
// if it was swallowed, we re-raise GeneratorExit
|
|
|
|
GENERATOR_EXIT_IF_NEEDED(t_exc); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
} |
|
|
|
if (ret_kind == MP_VM_RETURN_EXCEPTION) { |
|
|
|
// Pop exhausted gen
|
|
|
@ -866,36 +976,38 @@ yield: |
|
|
|
// If we injected GeneratorExit downstream, then even
|
|
|
|
// if it was swallowed, we re-raise GeneratorExit
|
|
|
|
GENERATOR_EXIT_IF_NEEDED(t_exc); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
} else { |
|
|
|
nlr_raise(obj2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
case MP_BC_IMPORT_NAME: |
|
|
|
ENTRY(MP_BC_IMPORT_NAME): |
|
|
|
DECODE_QSTR; |
|
|
|
obj1 = POP(); |
|
|
|
SET_TOP(mp_import_name(qst, obj1, TOP())); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_IMPORT_FROM: |
|
|
|
ENTRY(MP_BC_IMPORT_FROM): |
|
|
|
DECODE_QSTR; |
|
|
|
obj1 = mp_import_from(TOP(), qst); |
|
|
|
PUSH(obj1); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
case MP_BC_IMPORT_STAR: |
|
|
|
ENTRY(MP_BC_IMPORT_STAR): |
|
|
|
mp_import_all(POP()); |
|
|
|
break; |
|
|
|
DISPATCH(); |
|
|
|
|
|
|
|
default: |
|
|
|
ENTRY_DEFAULT: |
|
|
|
printf("code %p, byte code 0x%02x not implemented\n", ip, op); |
|
|
|
obj1 = mp_obj_new_exception_msg(&mp_type_NotImplementedError, "byte code not implemented"); |
|
|
|
nlr_pop(); |
|
|
|
fastn[0] = obj1; |
|
|
|
return MP_VM_RETURN_EXCEPTION; |
|
|
|
#ifndef MICROPY_USE_COMPUTED_GOTO |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|