summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/asmthumb.c86
-rw-r--r--py/asmthumb.h8
-rw-r--r--py/binary.c20
-rw-r--r--py/binary.h1
-rw-r--r--py/emitinlinethumb.c12
-rw-r--r--py/modstruct.c4
-rw-r--r--py/obj.c12
-rw-r--r--py/obj.h24
-rw-r--r--py/objarray.c43
-rw-r--r--py/objfun.c19
-rw-r--r--py/objint.c4
-rw-r--r--py/objstr.c6
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++) {
diff --git a/py/obj.c b/py/obj.c
index 514a6941b..4b7251447 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -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"));
}
}
diff --git a/py/obj.h b/py/obj.h
index 0330857d0..dd25ec4f2 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -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;
}
}