diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/asmthumb.c | 86 | ||||
-rw-r--r-- | py/asmthumb.h | 8 | ||||
-rw-r--r-- | py/binary.c | 20 | ||||
-rw-r--r-- | py/binary.h | 1 | ||||
-rw-r--r-- | py/emitinlinethumb.c | 12 | ||||
-rw-r--r-- | py/modstruct.c | 4 | ||||
-rw-r--r-- | py/obj.c | 12 | ||||
-rw-r--r-- | py/obj.h | 24 | ||||
-rw-r--r-- | py/objarray.c | 43 | ||||
-rw-r--r-- | py/objfun.c | 19 | ||||
-rw-r--r-- | py/objint.c | 4 | ||||
-rw-r--r-- | py/objstr.c | 6 |
12 files changed, 139 insertions, 100 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c index 6bf6d6658..7037ac518 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -121,22 +121,6 @@ STATIC void asm_thumb_write_byte_1(asm_thumb_t *as, byte b1) { } */ -STATIC void asm_thumb_write_op16(asm_thumb_t *as, uint op) { - byte *c = asm_thumb_get_cur_to_write_bytes(as, 2); - // little endian - c[0] = op; - c[1] = op >> 8; -} - -STATIC void asm_thumb_write_op32(asm_thumb_t *as, uint op1, uint op2) { - byte *c = asm_thumb_get_cur_to_write_bytes(as, 4); - // little endian, op1 then op2 - c[0] = op1; - c[1] = op1 >> 8; - c[2] = op2; - c[3] = op2 >> 8; -} - /* #define IMM32_L0(x) ((x) & 0xff) #define IMM32_L1(x) (((x) >> 8) & 0xff) @@ -196,9 +180,9 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { stack_adjust = ((num_locals - 3) + 1) & (~1); break; } - asm_thumb_write_op16(as, OP_PUSH_RLIST_LR(reglist)); + asm_thumb_op16(as, OP_PUSH_RLIST_LR(reglist)); if (stack_adjust > 0) { - asm_thumb_write_op16(as, OP_SUB_SP(stack_adjust)); + asm_thumb_op16(as, OP_SUB_SP(stack_adjust)); } as->push_reglist = reglist; as->stack_adjust = stack_adjust; @@ -207,9 +191,9 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { void asm_thumb_exit(asm_thumb_t *as) { if (as->stack_adjust > 0) { - asm_thumb_write_op16(as, OP_ADD_SP(as->stack_adjust)); + asm_thumb_op16(as, OP_ADD_SP(as->stack_adjust)); } - asm_thumb_write_op16(as, OP_POP_RLIST_PC(as->push_reglist)); + asm_thumb_op16(as, OP_POP_RLIST_PC(as->push_reglist)); } void asm_thumb_label_assign(asm_thumb_t *as, uint label) { @@ -230,19 +214,35 @@ STATIC int get_label_dest(asm_thumb_t *as, uint label) { return as->label_offsets[label]; } +void asm_thumb_op16(asm_thumb_t *as, uint op) { + byte *c = asm_thumb_get_cur_to_write_bytes(as, 2); + // little endian + c[0] = op; + c[1] = op >> 8; +} + +void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) { + byte *c = asm_thumb_get_cur_to_write_bytes(as, 4); + // little endian, op1 then op2 + c[0] = op1; + c[1] = op1 >> 8; + c[2] = op2; + c[3] = op2 >> 8; +} + #define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) { assert(rlo_dest < REG_R8); assert(rlo_src < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); + asm_thumb_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); } #define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { assert(rlo < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_3(op, rlo, i8)); + asm_thumb_op16(as, OP_FORMAT_3(op, rlo, i8)); } #define OP_FORMAT_4(op, rlo_dest, rlo_src) ((op) | ((rlo_src) << 3) | (rlo_dest)) @@ -250,13 +250,13 @@ void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) { assert(rlo_dest < REG_R8); assert(rlo_src < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); + asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); } #define OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset) ((op) | (((offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset) { - asm_thumb_write_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset)); + asm_thumb_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset)); } void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { @@ -272,7 +272,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { op_lo |= 0x80 | (reg_dest - 8); } // mov reg_dest, reg_src - asm_thumb_write_op16(as, 0x4600 | op_lo); + asm_thumb_op16(as, 0x4600 | op_lo); } #define OP_MOVW (0xf240) @@ -282,7 +282,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { assert(reg_dest < REG_R15); // mov[wt] reg_dest, #i16_src - asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); + asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); } // the i16_src value will be zero extended into the r32 register! @@ -296,7 +296,7 @@ void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) { } void asm_thumb_ite_ge(asm_thumb_t *as) { - asm_thumb_write_op16(as, 0xbfac); + asm_thumb_op16(as, 0xbfac); } #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff)) @@ -306,7 +306,7 @@ void asm_thumb_b_n(asm_thumb_t *as, uint label) { int rel = dest - as->code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction if (SIGNED_FIT12(rel)) { - asm_thumb_write_op16(as, OP_B_N(rel)); + asm_thumb_op16(as, OP_B_N(rel)); } else { printf("asm_thumb_b_n: branch does not fit in 12 bits\n"); } @@ -319,7 +319,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label) { int rel = dest - as->code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction if (SIGNED_FIT9(rel)) { - asm_thumb_write_op16(as, OP_BCC_N(cond, rel)); + asm_thumb_op16(as, OP_BCC_N(cond, rel)); } else { printf("asm_thumb_bcc_n: branch does not fit in 9 bits\n"); } @@ -350,14 +350,14 @@ void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) { assert(rlo_src < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); + asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); } void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { assert(rlo_dest < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); + asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); } #define OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset) (0xa800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) @@ -366,7 +366,7 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) assert(rlo_dest < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); + asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); } // this could be wrong, because it should have a range of +/- 16MiB... @@ -381,14 +381,14 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 12 bit relative jump if (SIGNED_FIT12(rel)) { - asm_thumb_write_op16(as, OP_B_N(rel)); + asm_thumb_op16(as, OP_B_N(rel)); } else { goto large_jump; } } else { // is a forwards jump, so need to assume it's large large_jump: - asm_thumb_write_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); + asm_thumb_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); } } @@ -404,14 +404,14 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 9 bit relative jump if (SIGNED_FIT9(rel)) { - asm_thumb_write_op16(as, OP_BCC_N(cond, rel)); + asm_thumb_op16(as, OP_BCC_N(cond, rel)); } else { goto large_jump; } } else { // is a forwards jump, so need to assume it's large large_jump: - asm_thumb_write_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); + asm_thumb_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); } } @@ -423,22 +423,22 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp uint rlo_base = REG_R3; uint rlo_dest = REG_R7; uint word_offset = 4; - asm_thumb_write_op16(as, 0x0000); - asm_thumb_write_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset] - asm_thumb_write_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg + asm_thumb_op16(as, 0x0000); + asm_thumb_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset] + asm_thumb_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg */ if (0) { // load ptr to function into register using immediate, then branch // not relocatable asm_thumb_mov_reg_i32(as, reg_temp, (machine_uint_t)fun_ptr); - asm_thumb_write_op16(as, OP_BLX(reg_temp)); + asm_thumb_op16(as, OP_BLX(reg_temp)); } else if (1) { - asm_thumb_write_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id)); - asm_thumb_write_op16(as, OP_BLX(reg_temp)); + asm_thumb_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id)); + asm_thumb_op16(as, OP_BLX(reg_temp)); } else { // use SVC - asm_thumb_write_op16(as, OP_SVC(fun_id)); + asm_thumb_op16(as, OP_SVC(fun_id)); } } diff --git a/py/asmthumb.h b/py/asmthumb.h index 6b4f5506b..ca81b847f 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -58,6 +58,14 @@ void asm_thumb_label_assign(asm_thumb_t *as, uint label); // argument order follows ARM, in general dest is first // note there is a difference between movw and mov.w, and many others! +#define ASM_THUMB_OP_NOP (0xbf00) +#define ASM_THUMB_OP_WFI (0xbf30) +#define ASM_THUMB_OP_CPSID_I (0xb672) // cpsid i, disable irq +#define ASM_THUMB_OP_CPSIE_I (0xb662) // cpsie i, enable irq + +void asm_thumb_op16(asm_thumb_t *as, uint op); +void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2); + // FORMAT 2: add/subtract #define ASM_THUMB_FORMAT_2_ADD (0x1800) diff --git a/py/binary.c b/py/binary.c index 1ddf4569b..d3dd00954 100644 --- a/py/binary.c +++ b/py/binary.c @@ -151,11 +151,21 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) { } void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) { - machine_int_t val = 0; - if (MP_OBJ_IS_INT(val_in)) { - val = mp_obj_int_get(val_in); + switch (typecode) { +#if MICROPY_ENABLE_FLOAT + case 'f': + ((float*)p)[index] = mp_obj_float_get(val_in); + break; + case 'd': + ((double*)p)[index] = mp_obj_float_get(val_in); + break; +#endif + default: + mp_binary_set_val_array_from_int(typecode, p, index, mp_obj_get_int(val_in)); } +} +void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine_int_t val) { switch (typecode) { case 'b': ((int8_t*)p)[index] = val; @@ -187,10 +197,10 @@ void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) #endif #if MICROPY_ENABLE_FLOAT case 'f': - ((float*)p)[index] = mp_obj_float_get(val_in); + ((float*)p)[index] = val; break; case 'd': - ((double*)p)[index] = mp_obj_float_get(val_in); + ((double*)p)[index] = val; break; #endif } diff --git a/py/binary.h b/py/binary.h index e9fb38f13..538d6e7f2 100644 --- a/py/binary.h +++ b/py/binary.h @@ -6,3 +6,4 @@ int mp_binary_get_size(char typecode); mp_obj_t mp_binary_get_val_array(char typecode, void *p, int index); mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr); void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in); +void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine_int_t val); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 812e702af..dabd5a883 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -235,7 +235,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, m uint op_len = strlen(op_str); if (n_args == 0) { - if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op? + if (strcmp(op_str, "nop") == 0) { + asm_thumb_op16(emit->as, ASM_THUMB_OP_NOP); + } else if (strcmp(op_str, "wfi") == 0) { + asm_thumb_op16(emit->as, ASM_THUMB_OP_WFI); + } else if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op? asm_thumb_ite_ge(emit->as); } else { goto unknown_op; @@ -259,6 +263,12 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, m int label_num = get_arg_label(emit, op_str, pn_args[0]); // TODO check that this succeeded, ie branch was within range asm_thumb_bcc_n(emit->as, cc, label_num); + } else if (strcmp(op_str, "cpsid")) { + // TODO check pn_args[0] == i + asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSID_I); + } else if (strcmp(op_str, "cpsie")) { + // TODO check pn_args[0] == i + asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSIE_I); } else { goto unknown_op; } diff --git a/py/modstruct.c b/py/modstruct.c index 3b9679a4c..cd2516b24 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -55,8 +55,8 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { char fmt_type = get_fmt_type(&fmt); uint size = calcsize_items(fmt); mp_obj_tuple_t *res = mp_obj_new_tuple(size, NULL); - buffer_info_t bufinfo; - mp_get_buffer_raise(data_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); byte *p = bufinfo.buf; for (uint i = 0; i < size; i++) { @@ -357,20 +357,20 @@ mp_obj_t mp_identity(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); -bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) { +bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags) { mp_obj_type_t *type = mp_obj_get_type(obj); if (type->buffer_p.get_buffer == NULL) { return false; } - type->buffer_p.get_buffer(obj, bufinfo, BUFFER_READ); - if (bufinfo->buf == NULL) { + int ret = type->buffer_p.get_buffer(obj, bufinfo, flags); + if (ret != 0 || bufinfo->buf == NULL) { return false; } return true; } -void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo) { - if (!mp_get_buffer(obj, bufinfo)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Object with buffer protocol required")); +void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags) { + if (!mp_get_buffer(obj, bufinfo, flags)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "object with buffer protocol required")); } } @@ -189,32 +189,28 @@ typedef struct _mp_method_t { } mp_method_t; // Buffer protocol -typedef struct _buffer_info_t { +typedef struct _mp_buffer_info_t { // if we'd bother to support various versions of structure // (with different number of fields), we can distinguish // them with ver = sizeof(struct). Cons: overkill for *micro*? //int ver; // ? void *buf; - machine_int_t len; - - // Rationale: have array.array and have SIMD operations on them - // Cons: users can pass item size to processing functions themselves, - // though that's not "plug&play" - // int itemsize; + machine_int_t len; // in bytes + int typecode; // as per binary.h // Rationale: to load arbitrary-sized sprites directly to LCD // Cons: a bit adhoc usecase // int stride; -} buffer_info_t; -#define BUFFER_READ (1) -#define BUFFER_WRITE (2) -#define BUFFER_RW (BUFFER_READ | BUFFER_WRITE) +} mp_buffer_info_t; +#define MP_BUFFER_READ (1) +#define MP_BUFFER_WRITE (2) +#define MP_BUFFER_RW (MP_BUFFER_READ | MP_BUFFER_WRITE) typedef struct _mp_buffer_p_t { - machine_int_t (*get_buffer)(mp_obj_t obj, buffer_info_t *bufinfo, int flags); + machine_int_t (*get_buffer)(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); } mp_buffer_p_t; -bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo); -void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo); +bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); +void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); // Stream protocol typedef struct _mp_stream_p_t { diff --git a/py/objarray.c b/py/objarray.c index 5c160bfab..c6da45728 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -35,7 +35,7 @@ STATIC void array_print(void (*print)(void *env, const char *fmt, ...), void *en } else { print(env, "array('%c'", o->typecode); if (o->len > 0) { - print(env, ", [", o->typecode); + print(env, ", ["); for (int i = 0; i < o->len; i++) { if (i > 0) { print(env, ", "); @@ -75,32 +75,37 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { } STATIC mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - if (n_args < 1 || n_args > 2) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected # of arguments, %d given", n_args)); - } - // TODO check args + mp_check_nargs(n_args, 1, 2, n_kw, false); + + // get typecode uint l; const char *typecode = mp_obj_str_get_data(args[0], &l); + if (n_args == 1) { + // 1 arg: make an empty array return array_new(*typecode, 0); + } else { + // 2 args: construct the array from the given iterator + return array_construct(*typecode, args[1]); } - - return array_construct(*typecode, args[1]); } STATIC mp_obj_t bytearray_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - if (n_args > 1) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected # of arguments, %d given", n_args)); - } + mp_check_nargs(n_args, 0, 1, n_kw, false); - if (MP_OBJ_IS_SMALL_INT(args[0])) { + if (n_args == 0) { + // no args: construct an empty bytearray + return array_new(BYTEARRAY_TYPECODE, 0); + } else if (MP_OBJ_IS_SMALL_INT(args[0])) { + // 1 arg, an integer: construct a blank bytearray of that length uint len = MP_OBJ_SMALL_INT_VALUE(args[0]); mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, len); memset(o->items, 0, len); return o; + } else { + // 1 arg, an iterator: construct the bytearray from that + return array_construct(BYTEARRAY_TYPECODE, args[0]); } - - return array_construct(BYTEARRAY_TYPECODE, args[0]); } STATIC mp_obj_t array_unary_op(int op, mp_obj_t o_in) { @@ -129,7 +134,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_append_obj, array_append); STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { - // delete item; does this need to be implemented? + // delete item + // TODO implement return MP_OBJ_NOT_SUPPORTED; } else { mp_obj_array_t *o = self_in; @@ -145,10 +151,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value } } -STATIC machine_int_t array_get_buffer(mp_obj_t o_in, buffer_info_t *bufinfo, int flags) { +STATIC machine_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, int flags) { mp_obj_array_t *o = o_in; bufinfo->buf = o->items; bufinfo->len = o->len * mp_binary_get_size(o->typecode); + bufinfo->typecode = o->typecode; return 0; } @@ -183,12 +190,16 @@ const mp_obj_type_t mp_type_bytearray = { }; STATIC mp_obj_array_t *array_new(char typecode, uint n) { + int typecode_size = mp_binary_get_size(typecode); + if (typecode_size <= 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad typecode")); + } mp_obj_array_t *o = m_new_obj(mp_obj_array_t); o->base.type = (typecode == BYTEARRAY_TYPECODE) ? &mp_type_bytearray : &mp_type_array; o->typecode = typecode; o->free = 0; o->len = n; - o->items = m_malloc(mp_binary_get_size(typecode) * o->len); + o->items = m_malloc(typecode_size * o->len); return o; } diff --git a/py/objfun.c b/py/objfun.c index 07d6606c5..ab6326057 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -30,26 +30,27 @@ STATIC void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) { } void mp_check_nargs(int n_args, machine_uint_t n_args_min, machine_uint_t n_args_max, int n_kw, bool is_kw) { + // TODO maybe take the function name as an argument so we can print nicer error messages + if (n_kw && !is_kw) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "function does not take keyword arguments")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); } if (n_args_min == n_args_max) { if (n_args != n_args_min) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function takes %d positional arguments but %d were given", - n_args_min, n_args)); + "function takes %d positional arguments but %d were given", + n_args_min, n_args)); } } else { if (n_args < n_args_min) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "<fun name>() missing %d required positional arguments: <list of names of params>", + "function missing %d required positional arguments", n_args_min - n_args)); } else if (n_args > n_args_max) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "<fun name> expected at most %d arguments, got %d", - n_args_max, n_args)); + "function expected at most %d arguments, got %d", + n_args_max, n_args)); } } } @@ -425,8 +426,8 @@ STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { - buffer_info_t bufinfo; - if (mp_get_buffer(obj, &bufinfo)) { + mp_buffer_info_t bufinfo; + if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_WRITE)) { // supports the buffer protocol, return a pointer to the data return (machine_uint_t)bufinfo.buf; } else { diff --git a/py/objint.c b/py/objint.c index 2c71f51cd..110876e00 100644 --- a/py/objint.c +++ b/py/objint.c @@ -272,8 +272,8 @@ STATIC mp_obj_t int_from_bytes(uint n_args, const mp_obj_t *args) { // TODO: Support signed param (assumes signed=False at the moment) // get the buffer info - buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); // convert the bytes to an integer machine_uint_t value = 0; diff --git a/py/objstr.c b/py/objstr.c index e444ec7d4..a682144b8 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1326,16 +1326,18 @@ STATIC mp_obj_t str_encode(uint n_args, const mp_obj_t *args) { } #endif -STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { - if (flags == BUFFER_READ) { +STATIC machine_int_t str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, int flags) { + if (flags == MP_BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); bufinfo->buf = (void*)str_data; bufinfo->len = str_len; + bufinfo->typecode = 'b'; return 0; } else { // can't write to a string bufinfo->buf = NULL; bufinfo->len = 0; + bufinfo->typecode = -1; return 1; } } |