Skip to content
Snippets Groups Projects
Commit f03001f8 authored by Damien's avatar Damien
Browse files

Add function to decode and show byte code.

parent 0446a0d7
No related branches found
No related tags found
No related merge requests found
......@@ -1027,7 +1027,8 @@ void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, i
DEBUG_printf(" %02x", code[i]);
}
DEBUG_printf("\n");
py_un_byte_code(code, len);
extern void py_show_byte_code(const byte *code, int len);
py_show_byte_code(code, len);
#ifdef WRITE_CODE
if (fp_write_code != NULL) {
......
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "misc.h"
#include "mpyconfig.h"
#include "runtime.h"
#include "bc.h"
#define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0)
#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0)
#define DECODE_QSTR do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0)
void py_show_byte_code(const byte *ip, int len) {
const byte *ip_start = ip;
machine_uint_t unum;
qstr qstr;
while (ip - ip_start < len) {
printf("%02u ", (uint)(ip - ip_start));
int op = *ip++;
switch (op) {
case PYBC_LOAD_CONST_FALSE:
printf("LOAD_CONST_FALSE");
break;
case PYBC_LOAD_CONST_NONE:
printf("LOAD_CONST_NONE");
break;
case PYBC_LOAD_CONST_TRUE:
printf("LOAD_CONST_TRUE");
break;
case PYBC_LOAD_CONST_SMALL_INT:
unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000;
ip += 3;
printf("LOAD_CONST_SMALL_INT %d", (int)unum);
break;
/*
case PYBC_LOAD_CONST_DEC:
DECODE_QSTR;
PUSH(rt_load_const_dec(qstr));
break;
case PYBC_LOAD_CONST_ID:
DECODE_QSTR;
PUSH(rt_load_const_str(qstr)); // TODO
break;
case PYBC_LOAD_CONST_STRING:
DECODE_QSTR;
PUSH(rt_load_const_str(qstr));
break;
*/
case PYBC_LOAD_FAST_0:
printf("LOAD_FAST_0");
break;
case PYBC_LOAD_FAST_1:
printf("LOAD_FAST_1");
break;
case PYBC_LOAD_FAST_2:
printf("LOAD_FAST_2");
break;
/*
case PYBC_LOAD_FAST_N:
DECODE_UINT;
PUSH(fastn[unum]);
break;
*/
case PYBC_LOAD_NAME:
DECODE_QSTR;
printf("LOAD_NAME %s", qstr_str(qstr));
break;
case PYBC_LOAD_GLOBAL:
DECODE_QSTR;
printf("LOAD_GLOBAL %s", qstr_str(qstr));
break;
/*
case PYBC_LOAD_ATTR:
DECODE_QSTR;
*sp = rt_load_attr(*sp, qstr);
break;
*/
case PYBC_LOAD_METHOD:
DECODE_QSTR;
printf("LOAD_METHOD %s", qstr_str(qstr));
break;
/*
case PYBC_LOAD_BUILD_CLASS:
PUSH(rt_load_build_class());
break;
*/
case PYBC_STORE_FAST_0:
printf("STORE_FAST_0");
break;
case PYBC_STORE_FAST_1:
printf("STORE_FAST_1");
break;
case PYBC_STORE_FAST_2:
printf("STORE_FAST_2");
break;
/*
case PYBC_STORE_FAST_N:
DECODE_UINT;
fastn[unum] = POP();
break;
*/
case PYBC_STORE_NAME:
DECODE_QSTR;
printf("STORE_NAME %s", qstr_str(qstr));
break;
/*
case PYBC_STORE_GLOBAL:
DECODE_QSTR;
rt_store_global(qstr, POP());
break;
case PYBC_STORE_ATTR:
DECODE_QSTR;
rt_store_attr(sp[0], qstr, sp[1]);
sp += 2;
break;
case PYBC_STORE_SUBSCR:
rt_store_subscr(sp[1], sp[0], sp[2]);
sp += 3;
break;
case PYBC_DUP_TOP:
obj1 = *sp;
PUSH(obj1);
break;
case PYBC_DUP_TOP_TWO:
sp -= 2;
sp[0] = sp[2];
sp[1] = sp[3];
break;
*/
case PYBC_POP_TOP:
printf("POP_TOP");
break;
/*
case PYBC_ROT_TWO:
obj1 = sp[0];
sp[0] = sp[1];
sp[1] = obj1;
break;
case PYBC_ROT_THREE:
obj1 = sp[0];
sp[0] = sp[1];
sp[1] = sp[2];
sp[2] = obj1;
break;
*/
case PYBC_JUMP:
DECODE_SLABEL;
printf("JUMP %lu", ip + unum - ip_start);
break;
case PYBC_POP_JUMP_IF_TRUE:
DECODE_SLABEL;
printf("POP_JUMP_IF_TRUE %lu", ip + unum - ip_start);
break;
/*
case PYBC_POP_JUMP_IF_FALSE:
DECODE_SLABEL;
if (!rt_is_true(POP())) {
ip += unum;
}
break;
case PYBC_JUMP_IF_TRUE_OR_POP:
DECODE_SLABEL;
if (rt_is_true(*sp)) {
ip += unum;
} else {
sp++;
}
break;
case PYBC_JUMP_IF_FALSE_OR_POP:
DECODE_SLABEL;
if (rt_is_true(*sp)) {
sp++;
} else {
ip += unum;
}
break;
case PYBC_SETUP_EXCEPT:
DECODE_ULABEL; // except labels are always forward
*++exc_sp = (machine_uint_t)ip + unum;
*++exc_sp = (machine_uint_t)sp;
break;
case PYBC_END_FINALLY:
// not implemented
// if TOS is an exception, reraises the exception (3 values on TOS)
// if TOS is an integer, does something else
// if TOS is None, just pops it and continues
// else error
assert(0);
break;
case PYBC_GET_ITER:
*sp = rt_getiter(*sp);
break;
case PYBC_FOR_ITER:
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
obj1 = rt_iternext(*sp);
if (obj1 == py_const_stop_iteration) {
++sp; // pop the exhausted iterator
ip += unum; // jump to after for-block
} else {
PUSH(obj1); // push the next iteration value
}
break;
case PYBC_POP_BLOCK:
// pops block and restores the stack
assert(0);
break;
case PYBC_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[0]);
//sp = (py_obj_t*)(*exc_sp--);
//exc_sp--; // discard ip
exc_sp -= 2;
//sp += 3; // pop 3 exception values
break;
case PYBC_UNARY_OP:
unum = *ip++;
*sp = rt_unary_op(unum, *sp);
break;
*/
case PYBC_BINARY_OP:
unum = *ip++;
printf("BINARY_OP %lu", unum);
break;
case PYBC_COMPARE_OP:
unum = *ip++;
printf("COMPARE_OP %lu", unum);
break;
/*
case PYBC_BUILD_TUPLE:
DECODE_UINT;
obj1 = rt_build_tuple(unum, sp);
sp += unum - 1;
*sp = obj1;
break;
case PYBC_BUILD_LIST:
DECODE_UINT;
obj1 = rt_build_list(unum, sp);
sp += unum - 1;
*sp = obj1;
break;
case PYBC_LIST_APPEND:
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[unum] is a list
rt_list_append(sp[unum], sp[0]);
sp++;
break;
case PYBC_BUILD_MAP:
DECODE_UINT;
PUSH(rt_build_map(unum));
break;
case PYBC_STORE_MAP:
sp += 2;
rt_store_map(sp[0], sp[-2], sp[-1]);
break;
case PYBC_MAP_ADD:
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[unum + 1] is a map
rt_store_map(sp[unum + 1], sp[0], sp[1]);
sp += 2;
break;
case PYBC_BUILD_SET:
DECODE_UINT;
obj1 = rt_build_set(unum, sp);
sp += unum - 1;
*sp = obj1;
break;
case PYBC_SET_ADD:
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[unum] is a set
rt_store_set(sp[unum], sp[0]);
sp++;
break;
*/
case PYBC_MAKE_FUNCTION:
DECODE_UINT;
printf("MAKE_FUNCTION %lu", unum);
break;
case PYBC_CALL_FUNCTION:
DECODE_UINT;
assert((unum & 0xff00) == 0); // n_keyword
unum &= 0xff; // n_positional
printf("CALL_FUNCTION %lu", unum);
break;
case PYBC_CALL_METHOD:
DECODE_UINT;
assert((unum & 0xff00) == 0); // n_keyword
unum &= 0xff;
printf("CALL_METHOD %lu", unum);
break;
case PYBC_RETURN_VALUE:
printf("RETURN_VALUE");
break;
/*
case PYBC_YIELD_VALUE:
nlr_pop();
*ip_in_out = ip;
fastn[0] = fast0;
fastn[1] = fast1;
fastn[2] = fast2;
*sp_in_out = sp;
return true;
*/
default:
printf("code %p, byte code 0x%02x not implemented\n", ip, op);
assert(0);
return;
}
printf("\n");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment