From dab1385177558f1d27c03b59e443b6fa25a2cdc0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 13 Jan 2015 15:55:54 +0000 Subject: [PATCH] py: Add load_const_obj to emitter, add LOAD_CONST_OBJ to bytecode. This allows to directly load a Python object to the Python stack. See issue #722 for background. --- py/bc0.h | 1 + py/emit.h | 1 + py/emitbc.c | 6 ++++++ py/emitcpy.c | 10 ++++++++++ py/emitnative.c | 7 +++++++ py/emitpass1.c | 1 + py/vm.c | 6 ++++++ py/vmentrytable.h | 1 + 8 files changed, 33 insertions(+) diff --git a/py/bc0.h b/py/bc0.h index 42b8b62800..f1c7baac4d 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -38,6 +38,7 @@ #define MP_BC_LOAD_CONST_DEC (0x16) // qstr #define MP_BC_LOAD_CONST_BYTES (0x17) // qstr #define MP_BC_LOAD_CONST_STRING (0x18) // qstr +#define MP_BC_LOAD_CONST_OBJ (0x09) // ptr; TODO renumber to be in order #define MP_BC_LOAD_NULL (0x19) #define MP_BC_LOAD_FAST_N (0x1a) // uint diff --git a/py/emit.h b/py/emit.h index 49bb76eadb..06a4201e7f 100644 --- a/py/emit.h +++ b/py/emit.h @@ -80,6 +80,7 @@ typedef struct _emit_method_table_t { void (*load_const_int)(emit_t *emit, qstr qst); void (*load_const_dec)(emit_t *emit, qstr qst); void (*load_const_str)(emit_t *emit, qstr qst, bool bytes); + void (*load_const_obj)(emit_t *emit, void *obj); void (*load_null)(emit_t *emit); void (*load_fast)(emit_t *emit, qstr qst, mp_uint_t id_flags, mp_uint_t local_num); void (*load_deref)(emit_t *emit, qstr qst, mp_uint_t local_num); diff --git a/py/emitbc.c b/py/emitbc.c index 4560d1ec6a..d63739125f 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -487,6 +487,11 @@ STATIC void emit_bc_load_const_str(emit_t *emit, qstr qst, bool bytes) { } } +STATIC void emit_bc_load_const_obj(emit_t *emit, void *obj) { + emit_bc_pre(emit, 1); + emit_write_bytecode_byte_ptr(emit, MP_BC_LOAD_CONST_OBJ, obj); +} + STATIC void emit_bc_load_null(emit_t *emit) { emit_bc_pre(emit, 1); emit_write_bytecode_byte(emit, MP_BC_LOAD_NULL); @@ -917,6 +922,7 @@ const emit_method_table_t emit_bc_method_table = { emit_bc_load_const_int, emit_bc_load_const_dec, emit_bc_load_const_str, + emit_bc_load_const_obj, emit_bc_load_null, emit_bc_load_fast, emit_bc_load_deref, diff --git a/py/emitcpy.c b/py/emitcpy.c index a1e8e95c8c..c54345c907 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -231,6 +231,15 @@ STATIC void emit_cpy_load_const_str(emit_t *emit, qstr qst, bool bytes) { } } +STATIC void emit_cpy_load_const_obj(emit_t *emit, void *obj) { + emit_pre(emit, 1, 3); + if (emit->pass == MP_PASS_EMIT) { + printf("LOAD_CONST "); + mp_obj_print(obj, PRINT_REPR); + printf("\n"); + } +} + STATIC void emit_cpy_load_null(emit_t *emit) { // unused for cpy assert(0); @@ -833,6 +842,7 @@ const emit_method_table_t emit_cpython_method_table = { emit_cpy_load_const_int, emit_cpy_load_const_dec, emit_cpy_load_const_str, + emit_cpy_load_const_obj, emit_cpy_load_null, emit_cpy_load_fast, emit_cpy_load_deref, diff --git a/py/emitnative.c b/py/emitnative.c index 494f89093d..211d2895a3 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1172,6 +1172,12 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qst, bool bytes) { } } +STATIC void emit_native_load_const_obj(emit_t *emit, void *obj) { + emit_native_pre(emit); + ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, (mp_uint_t)obj, REG_RET); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); +} + STATIC void emit_native_load_null(emit_t *emit) { emit_native_pre(emit); emit_post_push_imm(emit, VTYPE_PYOBJ, 0); @@ -2274,6 +2280,7 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_load_const_int, emit_native_load_const_dec, emit_native_load_const_str, + emit_native_load_const_obj, emit_native_load_null, emit_native_load_fast, emit_native_load_deref, diff --git a/py/emitpass1.c b/py/emitpass1.c index 8878b562e3..941f34dafb 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -190,6 +190,7 @@ const emit_method_table_t emit_pass1_method_table = { (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, + (void*)emit_pass1_dummy, #if MICROPY_PY_BUILTINS_SET (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, diff --git a/py/vm.c b/py/vm.c index 24280ee714..2dcc5378be 100644 --- a/py/vm.c +++ b/py/vm.c @@ -224,6 +224,12 @@ dispatch_loop: DISPATCH(); } + ENTRY(MP_BC_LOAD_CONST_OBJ): { + DECODE_PTR; + PUSH(ptr); + DISPATCH(); + } + ENTRY(MP_BC_LOAD_NULL): PUSH(MP_OBJ_NULL); DISPATCH(); diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 2926c0d7cd..7173c2df00 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -40,6 +40,7 @@ static void* entry_table[256] = { [MP_BC_LOAD_CONST_DEC] = &&entry_MP_BC_LOAD_CONST_DEC, [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_CONST_OBJ] = &&entry_MP_BC_LOAD_CONST_OBJ, [MP_BC_LOAD_NULL] = &&entry_MP_BC_LOAD_NULL, [MP_BC_LOAD_FAST_N] = &&entry_MP_BC_LOAD_FAST_N, [MP_BC_LOAD_DEREF] = &&entry_MP_BC_LOAD_DEREF,