4949#include <assert.h>
5050
5151#include "mpconfig.h"
52+ #include "nlr.h"
5253#include "misc.h"
5354#include "qstr.h"
5455#include "lexer.h"
@@ -723,7 +724,11 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
723724 assert (0 );
724725 emit_post_push_imm (emit , VTYPE_PTR , (machine_uint_t )qstr_str (qstr ));
725726 } else {
726- emit_call_with_imm_arg (emit , MP_F_LOAD_CONST_STR , mp_load_const_str , qstr , REG_ARG_1 );
727+ if (bytes ) {
728+ emit_call_with_imm_arg (emit , 0 , mp_load_const_bytes , qstr , REG_ARG_1 ); // TODO need to add function to runtime table
729+ } else {
730+ emit_call_with_imm_arg (emit , MP_F_LOAD_CONST_STR , mp_load_const_str , qstr , REG_ARG_1 );
731+ }
727732 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
728733 }
729734}
@@ -1057,17 +1062,33 @@ STATIC void emit_native_setup_with(emit_t *emit, uint label) {
10571062 // not supported, or could be with runtime call
10581063 assert (0 );
10591064}
1065+
10601066STATIC void emit_native_with_cleanup (emit_t * emit ) {
10611067 assert (0 );
10621068}
1069+
10631070STATIC void emit_native_setup_except (emit_t * emit , uint label ) {
1064- assert (0 );
1071+ emit_native_pre (emit );
1072+ // need to commit stack because we may jump elsewhere
1073+ need_stack_settled (emit );
1074+ emit_get_stack_pointer_to_reg_for_push (emit , REG_ARG_1 , sizeof (nlr_buf_t ) / sizeof (machine_uint_t )); // arg1 = pointer to nlr buf
1075+ emit_call (emit , 0 , nlr_push ); // TODO need to add function to runtime table
1076+ #if N_X64
1077+ asm_x64_test_r8_with_r8 (emit -> as , REG_RET , REG_RET );
1078+ asm_x64_jcc_label (emit -> as , JCC_JNZ , label );
1079+ #elif N_THUMB
1080+ asm_thumb_cmp_rlo_i8 (emit -> as , REG_RET , 0 );
1081+ asm_thumb_bcc_label (emit -> as , THUMB_CC_NE , label );
1082+ #endif
1083+ emit_post (emit );
10651084}
1085+
10661086STATIC void emit_native_setup_finally (emit_t * emit , uint label ) {
10671087 assert (0 );
10681088}
1089+
10691090STATIC void emit_native_end_finally (emit_t * emit ) {
1070- assert (0 );
1091+ // assert(0);
10711092}
10721093
10731094STATIC void emit_native_get_iter (emit_t * emit ) {
@@ -1107,19 +1128,31 @@ STATIC void emit_native_for_iter_end(emit_t *emit) {
11071128
11081129STATIC void emit_native_pop_block (emit_t * emit ) {
11091130 emit_native_pre (emit );
1131+ emit_call (emit , 0 , nlr_pop ); // TODO need to add function to runtime table
1132+ adjust_stack (emit , - (machine_int_t )(sizeof (nlr_buf_t ) / sizeof (machine_uint_t )));
11101133 emit_post (emit );
11111134}
11121135
11131136STATIC void emit_native_pop_except (emit_t * emit ) {
1114- assert (0 );
1137+ /*
1138+ emit_native_pre(emit);
1139+ emit_call(emit, 0, nlr_pop); // TODO need to add function to runtime table
1140+ adjust_stack(emit, -(machine_int_t)(sizeof(nlr_buf_t) / sizeof(machine_uint_t)));
1141+ emit_post(emit);
1142+ */
11151143}
11161144
11171145STATIC void emit_native_unary_op (emit_t * emit , mp_unary_op_t op ) {
1118- vtype_kind_t vtype ;
1119- emit_pre_pop_reg (emit , & vtype , REG_ARG_2 );
1120- assert (vtype == VTYPE_PYOBJ );
1121- emit_call_with_imm_arg (emit , MP_F_UNARY_OP , mp_unary_op , op , REG_ARG_1 );
1122- emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1146+ if (op == MP_UNARY_OP_NOT ) {
1147+ // we need to synthesise this operation
1148+ assert (0 );
1149+ } else {
1150+ vtype_kind_t vtype ;
1151+ emit_pre_pop_reg (emit , & vtype , REG_ARG_2 );
1152+ assert (vtype == VTYPE_PYOBJ );
1153+ emit_call_with_imm_arg (emit , MP_F_UNARY_OP , mp_unary_op , op , REG_ARG_1 );
1154+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1155+ }
11231156}
11241157
11251158STATIC void emit_native_binary_op (emit_t * emit , mp_binary_op_t op ) {
@@ -1233,17 +1266,26 @@ STATIC void emit_native_set_add(emit_t *emit, int set_index) {
12331266
12341267STATIC void emit_native_build_slice (emit_t * emit , int n_args ) {
12351268 DEBUG_printf ("build_slice %d\n" , n_args );
1236- assert (n_args == 2 );
1237- vtype_kind_t vtype_start , vtype_stop ;
1238- emit_pre_pop_reg_reg (emit , & vtype_stop , REG_ARG_2 , & vtype_start , REG_ARG_1 ); // arg1 = start, arg2 = stop
1239- assert (vtype_start == VTYPE_PYOBJ );
1240- assert (vtype_stop == VTYPE_PYOBJ );
1241- emit_call_with_imm_arg (emit , MP_F_NEW_SLICE , mp_obj_new_slice , (machine_uint_t )MP_OBJ_NULL , REG_ARG_3 ); // arg3 = step
1242- emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1269+ if (n_args == 2 ) {
1270+ vtype_kind_t vtype_start , vtype_stop ;
1271+ emit_pre_pop_reg_reg (emit , & vtype_stop , REG_ARG_2 , & vtype_start , REG_ARG_1 ); // arg1 = start, arg2 = stop
1272+ assert (vtype_start == VTYPE_PYOBJ );
1273+ assert (vtype_stop == VTYPE_PYOBJ );
1274+ emit_call_with_imm_arg (emit , MP_F_NEW_SLICE , mp_obj_new_slice , (machine_uint_t )mp_const_none , REG_ARG_3 ); // arg3 = step
1275+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1276+ } else {
1277+ assert (n_args == 3 );
1278+ vtype_kind_t vtype_start , vtype_stop , vtype_step ;
1279+ emit_pre_pop_reg_reg_reg (emit , & vtype_step , REG_ARG_3 , & vtype_stop , REG_ARG_2 , & vtype_start , REG_ARG_1 ); // arg1 = start, arg2 = stop, arg3 = step
1280+ assert (vtype_start == VTYPE_PYOBJ );
1281+ assert (vtype_stop == VTYPE_PYOBJ );
1282+ assert (vtype_step == VTYPE_PYOBJ );
1283+ emit_call (emit , MP_F_NEW_SLICE , mp_obj_new_slice );
1284+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1285+ }
12431286}
12441287
12451288STATIC void emit_native_unpack_sequence (emit_t * emit , int n_args ) {
1246- // TODO this is untested
12471289 DEBUG_printf ("unpack_sequence %d\n" , n_args );
12481290 vtype_kind_t vtype_base ;
12491291 emit_pre_pop_reg (emit , & vtype_base , REG_ARG_1 ); // arg1 = seq
@@ -1253,13 +1295,12 @@ STATIC void emit_native_unpack_sequence(emit_t *emit, int n_args) {
12531295}
12541296
12551297STATIC void emit_native_unpack_ex (emit_t * emit , int n_left , int n_right ) {
1256- // TODO this is untested
12571298 DEBUG_printf ("unpack_ex %d %d\n" , n_left , n_right );
12581299 vtype_kind_t vtype_base ;
12591300 emit_pre_pop_reg (emit , & vtype_base , REG_ARG_1 ); // arg1 = seq
12601301 assert (vtype_base == VTYPE_PYOBJ );
1261- emit_get_stack_pointer_to_reg_for_push (emit , REG_ARG_3 , n_left + n_right ); // arg3 = dest ptr
1262- emit_call_with_imm_arg (emit , MP_F_UNPACK_EX , mp_unpack_ex , n_left + n_right , REG_ARG_2 ); // arg2 = n_left + n_right
1302+ emit_get_stack_pointer_to_reg_for_push (emit , REG_ARG_3 , n_left + n_right + 1 ); // arg3 = dest ptr
1303+ emit_call_with_imm_arg (emit , MP_F_UNPACK_EX , mp_unpack_ex , n_left | ( n_right << 8 ) , REG_ARG_2 ); // arg2 = n_left + n_right
12631304}
12641305
12651306STATIC void emit_native_make_function (emit_t * emit , scope_t * scope , uint n_pos_defaults , uint n_kw_defaults ) {
@@ -1368,9 +1409,16 @@ STATIC void emit_native_return_value(emit_t *emit) {
13681409}
13691410
13701411STATIC void emit_native_raise_varargs (emit_t * emit , int n_args ) {
1371- // call runtime
1372- assert (0 );
1412+ assert (n_args == 1 );
1413+ vtype_kind_t vtype_err ;
1414+ emit_pre_pop_reg (emit , & vtype_err , REG_ARG_1 ); // arg1 = object to raise
1415+ assert (vtype_err == VTYPE_PYOBJ );
1416+ emit_call (emit , 0 , mp_make_raise_obj ); // TODO need to add function to runtime table
1417+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
1418+ emit_pre_pop_reg (emit , & vtype_err , REG_ARG_1 );
1419+ emit_call (emit , 0 , nlr_jump ); // TODO need to add function to runtime table
13731420}
1421+
13741422STATIC void emit_native_yield_value (emit_t * emit ) {
13751423 // not supported (for now)
13761424 assert (0 );
@@ -1380,6 +1428,21 @@ STATIC void emit_native_yield_from(emit_t *emit) {
13801428 assert (0 );
13811429}
13821430
1431+ STATIC void emit_native_start_except_handler (emit_t * emit ) {
1432+ // This instruction follows an nlr_pop, so the stack counter is back to zero, when really
1433+ // it should be up by a whole nlr_buf_t. We then want to pop the nlr_buf_t here, but save
1434+ // the first 2 elements, so we can get the thrown value.
1435+ adjust_stack (emit , 2 );
1436+ vtype_kind_t vtype_nlr ;
1437+ emit_pre_pop_reg (emit , & vtype_nlr , REG_ARG_1 ); // get the thrown value
1438+ emit_pre_pop_discard (emit , & vtype_nlr ); // discard the linked-list pointer in the nlr_buf
1439+ emit_post_push_reg_reg_reg (emit , VTYPE_PYOBJ , REG_ARG_1 , VTYPE_PYOBJ , REG_ARG_1 , VTYPE_PYOBJ , REG_ARG_1 ); // push the 3 exception items
1440+ }
1441+
1442+ STATIC void emit_native_end_except_handler (emit_t * emit ) {
1443+ adjust_stack (emit , -3 ); // stack adjust (not sure why it's this much...)
1444+ }
1445+
13831446const emit_method_table_t EXPORT_FUN (method_table ) = {
13841447 emit_native_set_viper_types ,
13851448 emit_native_start_pass ,
@@ -1465,6 +1528,9 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
14651528 emit_native_raise_varargs ,
14661529 emit_native_yield_value ,
14671530 emit_native_yield_from ,
1531+
1532+ emit_native_start_except_handler ,
1533+ emit_native_end_except_handler ,
14681534};
14691535
14701536#endif // (MICROPY_EMIT_X64 && N_X64) || (MICROPY_EMIT_THUMB && N_THUMB)
0 commit comments