py: Add constant table to bytecode.
Contains just argument names at the moment but makes it easy to add arbitrary constants.
This commit is contained in:
parent
3a3db4dcf0
commit
713ea1800d
9
py/bc.c
9
py/bc.c
@ -97,6 +97,9 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
|
||||
// ip comes in as an offset into bytecode, so turn it into a true pointer
|
||||
code_state->ip = self->bytecode + (mp_uint_t)code_state->ip;
|
||||
|
||||
// store pointer to constant table
|
||||
code_state->const_table = self->const_table;
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
code_state->prev = NULL;
|
||||
#endif
|
||||
@ -107,9 +110,6 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
|
||||
mp_uint_t n_kwonly_args = *code_state->ip++;
|
||||
mp_uint_t n_def_pos_args = *code_state->ip++;
|
||||
|
||||
// align ip
|
||||
code_state->ip = MP_ALIGN(code_state->ip, sizeof(mp_uint_t));
|
||||
|
||||
code_state->sp = &code_state->state[0] - 1;
|
||||
code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
|
||||
|
||||
@ -168,7 +168,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
|
||||
}
|
||||
|
||||
// get pointer to arg_names array
|
||||
const mp_obj_t *arg_names = (const mp_obj_t*)code_state->ip;
|
||||
const mp_obj_t *arg_names = (const mp_obj_t*)code_state->const_table;
|
||||
|
||||
for (mp_uint_t i = 0; i < n_kw; i++) {
|
||||
mp_obj_t wanted_arg_name = kwargs[2 * i];
|
||||
@ -243,7 +243,6 @@ continue2:;
|
||||
|
||||
// get the ip and skip argument names
|
||||
const byte *ip = code_state->ip;
|
||||
ip += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t);
|
||||
|
||||
// store pointer to code_info and jump over it
|
||||
{
|
||||
|
29
py/bc.h
29
py/bc.h
@ -38,24 +38,26 @@
|
||||
// n_kwonly_args : byte number of keyword-only arguments this function takes
|
||||
// n_def_pos_args : byte number of default positional arguments
|
||||
//
|
||||
// <word alignment padding>
|
||||
//
|
||||
// argname0 : obj (qstr)
|
||||
// ... : obj (qstr)
|
||||
// argnameN : obj (qstr) N = num_pos_args + num_kwonly_args
|
||||
//
|
||||
// code_info_size : var uint | code_info_size counts bytes in this chunk
|
||||
// simple_name : var qstr |
|
||||
// source_file : var qstr |
|
||||
// <line number info> |
|
||||
// <word alignment padding> |
|
||||
// <word alignment padding> | only needed if bytecode contains pointers
|
||||
//
|
||||
// num_cells : byte number of locals that are cells
|
||||
// local_num0 : byte
|
||||
// ... : byte
|
||||
// local_numN : byte N = num_cells
|
||||
// local_num0 : byte |
|
||||
// ... : byte |
|
||||
// local_numN : byte | N = num_cells
|
||||
// 255 : byte | end of list sentinel
|
||||
// <bytecode> |
|
||||
//
|
||||
// <bytecode>
|
||||
//
|
||||
// constant table layout:
|
||||
//
|
||||
// argname0 : obj (qstr)
|
||||
// ... : obj (qstr)
|
||||
// argnameN : obj (qstr) N = num_pos_args + num_kwonly_args
|
||||
// const0 : obj
|
||||
// constN : obj
|
||||
|
||||
// Exception stack entry
|
||||
typedef struct _mp_exc_stack {
|
||||
@ -70,6 +72,7 @@ typedef struct _mp_exc_stack {
|
||||
typedef struct _mp_code_state {
|
||||
const byte *code_info;
|
||||
const byte *ip;
|
||||
const mp_uint_t *const_table;
|
||||
mp_obj_t *sp;
|
||||
// bit 0 is saved currently_in_except_block value
|
||||
mp_exc_stack_t *exc_sp;
|
||||
@ -89,7 +92,7 @@ mp_uint_t mp_decode_uint(const byte **ptr);
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_obj_t inject_exc);
|
||||
mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
void mp_bytecode_print(const void *descr, const byte *code, mp_uint_t len);
|
||||
void mp_bytecode_print(const void *descr, const byte *code, mp_uint_t len, const mp_uint_t *const_table);
|
||||
void mp_bytecode_print2(const byte *code, mp_uint_t len);
|
||||
const byte *mp_bytecode_print_str(const byte *ip);
|
||||
#define mp_bytecode_print_inst(code) mp_bytecode_print2(code, 1)
|
||||
|
73
py/emitbc.c
73
py/emitbc.c
@ -56,6 +56,7 @@ struct _emit_t {
|
||||
mp_uint_t bytecode_offset;
|
||||
mp_uint_t bytecode_size;
|
||||
byte *code_base; // stores both byte code and code info
|
||||
mp_uint_t *const_table;
|
||||
// Accessed as mp_uint_t, so must be aligned as such
|
||||
byte dummy_data[DUMMY_DATA_SIZE];
|
||||
};
|
||||
@ -123,13 +124,6 @@ STATIC void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
|
||||
emit_write_uint(emit, emit_get_cur_to_write_code_info, qst);
|
||||
}
|
||||
|
||||
STATIC void emit_write_code_info_prealigned_ptr(emit_t* emit, void *ptr) {
|
||||
mp_uint_t *c = (mp_uint_t*)emit_get_cur_to_write_code_info(emit, sizeof(mp_uint_t));
|
||||
// Verify thar c is already uint-aligned
|
||||
assert(c == MP_ALIGN(c, sizeof(mp_uint_t)));
|
||||
*c = (mp_uint_t)ptr;
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_SOURCE_LINE
|
||||
STATIC void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
|
||||
assert(bytes_to_skip > 0 || lines_to_skip > 0);
|
||||
@ -301,37 +295,6 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||
emit_write_code_info_byte(emit, emit->scope->num_kwonly_args);
|
||||
emit_write_code_info_byte(emit, emit->scope->num_def_pos_args);
|
||||
|
||||
// Align code-info so that following pointers are aligned on a machine word.
|
||||
emit_align_code_info_to_machine_word(emit);
|
||||
|
||||
// Write argument names (needed to resolve positional args passed as
|
||||
// keywords). We store them as full word-sized objects for efficient access
|
||||
// in mp_setup_code_state this is the start of the prelude and is guaranteed
|
||||
// to be aligned on a word boundary.
|
||||
{
|
||||
// For a given argument position (indexed by i) we need to find the
|
||||
// corresponding id_info which is a parameter, as it has the correct
|
||||
// qstr name to use as the argument name. Note that it's not a simple
|
||||
// 1-1 mapping (ie i!=j in general) because of possible closed-over
|
||||
// variables. In the case that the argument i has no corresponding
|
||||
// parameter we use "*" as its name (since no argument can ever be named
|
||||
// "*"). We could use a blank qstr but "*" is better for debugging.
|
||||
// Note: there is some wasted RAM here for the case of storing a qstr
|
||||
// for each closed-over variable, and maybe there is a better way to do
|
||||
// it, but that would require changes to mp_setup_code_state.
|
||||
for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
|
||||
qstr qst = MP_QSTR__star_;
|
||||
for (int j = 0; j < scope->id_info_len; ++j) {
|
||||
id_info_t *id = &scope->id_info[j];
|
||||
if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
|
||||
qst = id->qst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit_write_code_info_prealigned_ptr(emit, MP_OBJ_NEW_QSTR(qst));
|
||||
}
|
||||
}
|
||||
|
||||
// Write size of the rest of the code info. We don't know how big this
|
||||
// variable uint will be on the MP_PASS_CODE_SIZE pass so we reserve 2 bytes
|
||||
// for it and hope that is enough! TODO assert this or something.
|
||||
@ -354,6 +317,35 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||
}
|
||||
}
|
||||
emit_write_bytecode_byte(emit, 255); // end of list sentinel
|
||||
|
||||
if (pass == MP_PASS_EMIT) {
|
||||
// Write argument names (needed to resolve positional args passed as
|
||||
// keywords). We store them as full word-sized objects for efficient access
|
||||
// in mp_setup_code_state this is the start of the prelude and is guaranteed
|
||||
// to be aligned on a word boundary.
|
||||
|
||||
// For a given argument position (indexed by i) we need to find the
|
||||
// corresponding id_info which is a parameter, as it has the correct
|
||||
// qstr name to use as the argument name. Note that it's not a simple
|
||||
// 1-1 mapping (ie i!=j in general) because of possible closed-over
|
||||
// variables. In the case that the argument i has no corresponding
|
||||
// parameter we use "*" as its name (since no argument can ever be named
|
||||
// "*"). We could use a blank qstr but "*" is better for debugging.
|
||||
// Note: there is some wasted RAM here for the case of storing a qstr
|
||||
// for each closed-over variable, and maybe there is a better way to do
|
||||
// it, but that would require changes to mp_setup_code_state.
|
||||
for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
|
||||
qstr qst = MP_QSTR__star_;
|
||||
for (int j = 0; j < scope->id_info_len; ++j) {
|
||||
id_info_t *id = &scope->id_info[j];
|
||||
if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
|
||||
qst = id->qst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit->const_table[i] = (mp_uint_t)MP_OBJ_NEW_QSTR(qst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_emit_bc_end_pass(emit_t *emit) {
|
||||
@ -377,9 +369,12 @@ void mp_emit_bc_end_pass(emit_t *emit) {
|
||||
emit->bytecode_size = emit->bytecode_offset;
|
||||
emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
|
||||
|
||||
emit->const_table = m_new0(mp_uint_t, emit->scope->num_pos_args + emit->scope->num_kwonly_args);
|
||||
|
||||
} else if (emit->pass == MP_PASS_EMIT) {
|
||||
mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
|
||||
emit->code_info_size + emit->bytecode_size, emit->scope->scope_flags);
|
||||
emit->code_info_size + emit->bytecode_size,
|
||||
emit->const_table, emit->scope->scope_flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,11 @@ struct _mp_raw_code_t {
|
||||
union {
|
||||
struct {
|
||||
const byte *code;
|
||||
const mp_uint_t *const_table;
|
||||
} u_byte;
|
||||
struct {
|
||||
void *fun_data;
|
||||
const mp_uint_t *const_table;
|
||||
mp_uint_t type_sig; // for viper, compressed as 2-bit types; ret is MSB, then arg0, arg1, etc
|
||||
} u_native;
|
||||
} data;
|
||||
@ -65,28 +67,30 @@ mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t scope_flags) {
|
||||
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, mp_uint_t len, const mp_uint_t *const_table, mp_uint_t scope_flags) {
|
||||
rc->kind = MP_CODE_BYTECODE;
|
||||
rc->scope_flags = scope_flags;
|
||||
rc->data.u_byte.code = code;
|
||||
rc->data.u_byte.const_table = const_table;
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " flags=%x\n", code, len, (uint)scope_flags);
|
||||
#endif
|
||||
#if MICROPY_DEBUG_PRINTERS
|
||||
if (mp_verbose_flag >= 2) {
|
||||
mp_bytecode_print(rc, code, len);
|
||||
mp_bytecode_print(rc, code, len, const_table);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB
|
||||
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) {
|
||||
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) {
|
||||
assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM);
|
||||
rc->kind = kind;
|
||||
rc->scope_flags = scope_flags;
|
||||
rc->n_pos_args = n_pos_args;
|
||||
rc->data.u_native.fun_data = fun_data;
|
||||
rc->data.u_native.const_table = const_table;
|
||||
rc->data.u_native.type_sig = type_sig;
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
@ -125,11 +129,11 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp
|
||||
switch (rc->kind) {
|
||||
case MP_CODE_BYTECODE:
|
||||
no_other_choice:
|
||||
fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.code);
|
||||
fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.code, rc->data.u_byte.const_table);
|
||||
break;
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
case MP_CODE_NATIVE_PY:
|
||||
fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->data.u_native.fun_data);
|
||||
fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->data.u_native.fun_data, rc->data.u_native.const_table);
|
||||
break;
|
||||
case MP_CODE_NATIVE_VIPER:
|
||||
fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
|
||||
|
@ -43,8 +43,8 @@ typedef struct _mp_raw_code_t mp_raw_code_t;
|
||||
|
||||
mp_raw_code_t *mp_emit_glue_new_raw_code(void);
|
||||
|
||||
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t scope_flags);
|
||||
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig);
|
||||
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, mp_uint_t len, const mp_uint_t *const_table, mp_uint_t scope_flags);
|
||||
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig);
|
||||
|
||||
mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args);
|
||||
mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args);
|
||||
|
@ -90,7 +90,7 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
|
||||
|
||||
if (emit->pass == MP_PASS_EMIT) {
|
||||
void *f = asm_thumb_get_code(emit->as);
|
||||
mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args, 0, 0);
|
||||
mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), NULL, emit->scope->num_pos_args, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,6 +567,7 @@ struct _emit_t {
|
||||
vtype_kind_t saved_stack_vtype;
|
||||
|
||||
int prelude_offset;
|
||||
int const_table_offset;
|
||||
int n_state;
|
||||
int stack_start;
|
||||
int stack_size;
|
||||
@ -828,7 +829,24 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
||||
ASM_DATA(emit->as, 1, emit->scope->num_pos_args);
|
||||
ASM_DATA(emit->as, 1, emit->scope->num_kwonly_args);
|
||||
ASM_DATA(emit->as, 1, emit->scope->num_def_pos_args);
|
||||
|
||||
// write code info (just contains block name and source file)
|
||||
ASM_DATA(emit->as, 1, 5);
|
||||
ASM_DATA(emit->as, 2, emit->scope->simple_name);
|
||||
ASM_DATA(emit->as, 2, emit->scope->source_file);
|
||||
|
||||
// bytecode prelude: initialise closed over variables
|
||||
for (int i = 0; i < emit->scope->id_info_len; i++) {
|
||||
id_info_t *id = &emit->scope->id_info[i];
|
||||
if (id->kind == ID_INFO_KIND_CELL) {
|
||||
assert(id->local_num < 255);
|
||||
ASM_DATA(emit->as, 1, id->local_num); // write the local which should be converted to a cell
|
||||
}
|
||||
}
|
||||
ASM_DATA(emit->as, 1, 255); // end of list sentinel
|
||||
|
||||
ASM_ALIGN(emit->as, ASM_WORD_SIZE);
|
||||
emit->const_table_offset = ASM_GET_CODE_POS(emit->as);
|
||||
|
||||
// write argument names as qstr objects
|
||||
// see comment in corresponding part of emitbc.c about the logic here
|
||||
@ -844,18 +862,6 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
||||
ASM_DATA(emit->as, ASM_WORD_SIZE, (mp_uint_t)MP_OBJ_NEW_QSTR(qst));
|
||||
}
|
||||
|
||||
// write dummy code info (for mp_setup_code_state to parse)
|
||||
ASM_DATA(emit->as, 1, 1);
|
||||
|
||||
// bytecode prelude: initialise closed over variables
|
||||
for (int i = 0; i < emit->scope->id_info_len; i++) {
|
||||
id_info_t *id = &emit->scope->id_info[i];
|
||||
if (id->kind == ID_INFO_KIND_CELL) {
|
||||
assert(id->local_num < 255);
|
||||
ASM_DATA(emit->as, 1, id->local_num); // write the local which should be converted to a cell
|
||||
}
|
||||
}
|
||||
ASM_DATA(emit->as, 1, 255); // end of list sentinel
|
||||
}
|
||||
|
||||
ASM_END_PASS(emit->as);
|
||||
@ -878,7 +884,8 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
||||
|
||||
mp_emit_glue_assign_native(emit->scope->raw_code,
|
||||
emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY,
|
||||
f, f_len, emit->scope->num_pos_args, emit->scope->scope_flags, type_sig);
|
||||
f, f_len, (mp_uint_t*)((byte*)f + emit->const_table_offset),
|
||||
emit->scope->num_pos_args, emit->scope->scope_flags, type_sig);
|
||||
}
|
||||
}
|
||||
|
||||
|
4
py/obj.h
4
py/obj.h
@ -537,8 +537,8 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg);
|
||||
mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg);
|
||||
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
|
||||
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code);
|
||||
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data);
|
||||
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table);
|
||||
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table);
|
||||
mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig);
|
||||
mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data);
|
||||
mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
|
||||
|
13
py/objfun.c
13
py/objfun.c
@ -126,11 +126,9 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {
|
||||
mp_decode_uint(&bc); // skip n_state
|
||||
mp_decode_uint(&bc); // skip n_exc_stack
|
||||
bc++; // skip scope_params
|
||||
mp_uint_t n_pos_args = *bc++;
|
||||
mp_uint_t n_kwonly_args = *bc++;
|
||||
bc++; // skip n_pos_args
|
||||
bc++; // skip n_kwonly_args
|
||||
bc++; // skip n_def_pos_args
|
||||
bc = MP_ALIGN(bc, sizeof(mp_uint_t)); // align
|
||||
bc += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t); // skip arg names
|
||||
return mp_obj_code_get_name(bc);
|
||||
}
|
||||
|
||||
@ -320,7 +318,7 @@ const mp_obj_type_t mp_type_fun_bc = {
|
||||
#endif
|
||||
};
|
||||
|
||||
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code) {
|
||||
mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table) {
|
||||
mp_uint_t n_def_args = 0;
|
||||
mp_uint_t n_extra_args = 0;
|
||||
mp_obj_tuple_t *def_args = def_args_in;
|
||||
@ -336,6 +334,7 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byt
|
||||
o->base.type = &mp_type_fun_bc;
|
||||
o->globals = mp_globals_get();
|
||||
o->bytecode = code;
|
||||
o->const_table = const_table;
|
||||
if (def_args != MP_OBJ_NULL) {
|
||||
memcpy(o->extra_args, def_args->items, n_def_args * sizeof(mp_obj_t));
|
||||
}
|
||||
@ -364,8 +363,8 @@ STATIC const mp_obj_type_t mp_type_fun_native = {
|
||||
.unary_op = mp_generic_unary_op,
|
||||
};
|
||||
|
||||
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data) {
|
||||
mp_obj_fun_bc_t *o = mp_obj_new_fun_bc(def_args_in, def_kw_args, (const byte*)fun_data);
|
||||
mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table) {
|
||||
mp_obj_fun_bc_t *o = mp_obj_new_fun_bc(def_args_in, def_kw_args, (const byte*)fun_data, const_table);
|
||||
o->base.type = &mp_type_fun_native;
|
||||
return o;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ typedef struct _mp_obj_fun_bc_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_dict_t *globals; // the context within which this function was defined
|
||||
const byte *bytecode; // bytecode for the function
|
||||
const mp_uint_t *const_table; // constant table
|
||||
// the following extra_args array is allocated space to take (in order):
|
||||
// - values of positional default args (if any)
|
||||
// - a single slot for default kw args dict (if it has them)
|
||||
|
@ -68,7 +68,6 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw
|
||||
|
||||
o->globals = self_fun->globals;
|
||||
o->code_state.n_state = n_state;
|
||||
o->code_state.code_info = 0; // offset to code-info
|
||||
o->code_state.ip = (byte*)(ip - self_fun->bytecode); // offset to prelude
|
||||
mp_setup_code_state(&o->code_state, self_fun, n_args, n_kw, args);
|
||||
return o;
|
||||
|
10
py/showbc.c
10
py/showbc.c
@ -54,7 +54,7 @@
|
||||
|
||||
const byte *mp_showbc_code_start;
|
||||
|
||||
void mp_bytecode_print(const void *descr, const byte *ip, mp_uint_t len) {
|
||||
void mp_bytecode_print(const void *descr, const byte *ip, mp_uint_t len, const mp_uint_t *const_table) {
|
||||
mp_showbc_code_start = ip;
|
||||
|
||||
// get bytecode parameters
|
||||
@ -65,12 +65,6 @@ void mp_bytecode_print(const void *descr, const byte *ip, mp_uint_t len) {
|
||||
mp_uint_t n_kwonly_args = *ip++;
|
||||
/*mp_uint_t n_def_pos_args =*/ ip++;
|
||||
|
||||
ip = MP_ALIGN(ip, sizeof(mp_uint_t));
|
||||
|
||||
// get and skip arg names
|
||||
const mp_obj_t *arg_names = (const mp_obj_t*)ip;
|
||||
ip += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t);
|
||||
|
||||
const byte *code_info = ip;
|
||||
mp_uint_t code_info_size = mp_decode_uint(&code_info);
|
||||
ip += code_info_size;
|
||||
@ -93,7 +87,7 @@ void mp_bytecode_print(const void *descr, const byte *ip, mp_uint_t len) {
|
||||
// bytecode prelude: arg names (as qstr objects)
|
||||
printf("arg names:");
|
||||
for (mp_uint_t i = 0; i < n_pos_args + n_kwonly_args; i++) {
|
||||
printf(" %s", qstr_str(MP_OBJ_QSTR_VALUE(arg_names[i])));
|
||||
printf(" %s", qstr_str(MP_OBJ_QSTR_VALUE(const_table[i])));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user