Skip to content

Commit 5fa93b6

Browse files
committed
Second stage of qstr revamp: uPy str object can be qstr or not.
1 parent 8ae1c1b commit 5fa93b6

24 files changed

Lines changed: 376 additions & 274 deletions

py/builtin.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_callable_obj, mp_builtin_callable);
139139
static mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
140140
int ord = mp_obj_get_int(o_in);
141141
if (0 <= ord && ord <= 0x10ffff) {
142-
char str[1] = {ord};
143-
return mp_obj_new_str(qstr_from_strn(str, 1));
142+
byte str[1] = {ord};
143+
return mp_obj_new_str(str, 1, true);
144144
} else {
145145
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
146146
}
@@ -258,7 +258,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next);
258258

259259
static mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
260260
uint len;
261-
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &len);
261+
const byte *str = mp_obj_str_get_data(o_in, &len);
262262
if (len == 1) {
263263
return mp_obj_new_int(str[0]);
264264
} else {
@@ -305,8 +305,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_range_obj, 1, 3, mp_builtin_range
305305
static mp_obj_t mp_builtin_repr(mp_obj_t o_in) {
306306
vstr_t *vstr = vstr_new();
307307
mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR);
308-
// TODO don't intern this string
309-
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
308+
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
309+
vstr_free(vstr);
310+
return s;
310311
}
311312

312313
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
@@ -345,8 +346,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
345346
static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
346347
vstr_t *vstr = vstr_new();
347348
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
348-
// TODO don't intern this string
349-
return mp_obj_new_str(qstr_from_strn_take(vstr->buf, vstr->alloc, vstr->len));
349+
mp_obj_t s = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
350+
vstr_free(vstr);
351+
return s;
350352
}
351353

352354
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);

py/builtineval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
2323
uint str_len;
24-
const byte *str = qstr_data(mp_obj_get_qstr(o_in), &str_len);
24+
const byte *str = mp_obj_str_get_data(o_in, &str_len);
2525

2626
// create the lexer
2727
mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", (const char*)str, str_len, 0);

py/builtinimport.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
2929
}
3030
*/
3131

32-
qstr mod_name = mp_obj_get_qstr(args[0]);
32+
uint mod_name_l;
33+
const byte *mod_name_s = mp_obj_str_get_data(args[0], &mod_name_l);
34+
qstr mod_name = qstr_from_strn((const char*)mod_name_s, mod_name_l);
35+
3336
mp_obj_t loaded = mp_obj_module_get(mod_name);
3437
if (loaded != MP_OBJ_NULL) {
3538
return loaded;
@@ -43,7 +46,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
4346
}
4447

4548
// create a new module object
46-
mp_obj_t module_obj = mp_obj_new_module(mp_obj_get_qstr(args[0]));
49+
mp_obj_t module_obj = mp_obj_new_module(mod_name);
4750

4851
// save the old context
4952
mp_map_t *old_locals = rt_locals_get();

py/obj.c

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "runtime.h"
1515
#include "map.h"
1616

17-
mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
17+
mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in) {
1818
if (MP_OBJ_IS_SMALL_INT(o_in)) {
1919
return (mp_obj_t)&int_type;
2020
} else if (MP_OBJ_IS_QSTR(o_in)) {
@@ -26,14 +26,7 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
2626
}
2727

2828
const char *mp_obj_get_type_str(mp_obj_t o_in) {
29-
if (MP_OBJ_IS_SMALL_INT(o_in)) {
30-
return "int";
31-
} else if (MP_OBJ_IS_QSTR(o_in)) {
32-
return "str";
33-
} else {
34-
mp_obj_base_t *o = o_in;
35-
return o->type->name;
36-
}
29+
return mp_obj_get_type(o_in)->name;
3730
}
3831

3932
void printf_wrapper(void *env, const char *fmt, ...) {
@@ -44,17 +37,11 @@ void printf_wrapper(void *env, const char *fmt, ...) {
4437
}
4538

4639
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
47-
if (MP_OBJ_IS_SMALL_INT(o_in)) {
48-
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(o_in));
49-
} else if (MP_OBJ_IS_QSTR(o_in)) {
50-
mp_obj_str_print_qstr(print, env, MP_OBJ_QSTR_VALUE(o_in), kind);
40+
mp_obj_type_t *type = mp_obj_get_type(o_in);
41+
if (type->print != NULL) {
42+
type->print(print, env, o_in, kind);
5143
} else {
52-
mp_obj_base_t *o = o_in;
53-
if (o->type->print != NULL) {
54-
o->type->print(print, env, o_in, kind);
55-
} else {
56-
print(env, "<%s>", o->type->name);
57-
}
44+
print(env, "<%s>", type->name);
5845
}
5946
}
6047

@@ -94,12 +81,10 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) {
9481
return 1; // needs to hash to same as the integer 1, since True==1
9582
} else if (MP_OBJ_IS_SMALL_INT(o_in)) {
9683
return MP_OBJ_SMALL_INT_VALUE(o_in);
97-
} else if (MP_OBJ_IS_QSTR(o_in)) {
98-
return MP_OBJ_QSTR_VALUE(o_in);
84+
} else if (MP_OBJ_IS_STR(o_in)) {
85+
return mp_obj_str_get_hash(o_in);
9986
} else if (MP_OBJ_IS_TYPE(o_in, &none_type)) {
10087
return (machine_int_t)o_in;
101-
} else if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
102-
return mp_obj_str_get(o_in);
10388
} else {
10489
assert(0);
10590
return 0;
@@ -138,10 +123,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
138123
}
139124
return false;
140125
}
141-
} else if (MP_OBJ_IS_QSTR(o1) || MP_OBJ_IS_QSTR(o2)) {
142-
return false;
143-
} else if (MP_OBJ_IS_TYPE(o1, &str_type) && MP_OBJ_IS_TYPE(o2, &str_type)) {
144-
return mp_obj_str_get(o1) == mp_obj_str_get(o2);
126+
} else if (MP_OBJ_IS_STR(o1) && MP_OBJ_IS_STR(o2)) {
127+
return mp_obj_str_equal(o1, o2);
145128
} else {
146129
mp_obj_base_t *o = o1;
147130
if (o->type->binary_op != NULL) {
@@ -218,17 +201,6 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
218201
}
219202
#endif
220203

221-
qstr mp_obj_get_qstr(mp_obj_t arg) {
222-
if (MP_OBJ_IS_QSTR(arg)) {
223-
return MP_OBJ_QSTR_VALUE(arg);
224-
} else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
225-
return mp_obj_str_get(arg);
226-
} else {
227-
assert(0);
228-
return 0;
229-
}
230-
}
231-
232204
mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) {
233205
if (MP_OBJ_IS_TYPE(o_in, &tuple_type) || MP_OBJ_IS_TYPE(o_in, &list_type)) {
234206
uint seq_len;
@@ -266,8 +238,8 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index)
266238
// may return MP_OBJ_NULL
267239
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
268240
mp_small_int_t len = 0;
269-
if (MP_OBJ_IS_TYPE(o_in, &str_type)) {
270-
len = qstr_len(mp_obj_str_get(o_in));
241+
if (MP_OBJ_IS_STR(o_in)) {
242+
len = mp_obj_str_get_len(o_in);
271243
} else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) {
272244
uint seq_len;
273245
mp_obj_t *seq_items;

py/obj.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
4040
#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2)
4141
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0)
4242
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t)))
43+
#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &str_type))
4344

4445
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1)
4546
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1))
@@ -199,14 +200,14 @@ extern const mp_obj_t mp_const_stop_iteration; // special object indicating end
199200

200201
// General API for objects
201202

202-
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
203+
mp_obj_t mp_obj_new_type(const char *name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
203204
mp_obj_t mp_obj_new_none(void);
204205
mp_obj_t mp_obj_new_bool(bool value);
205206
mp_obj_t mp_obj_new_cell(mp_obj_t obj);
206207
mp_obj_t mp_obj_new_int(machine_int_t value);
207208
mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value);
208209
mp_obj_t mp_obj_new_int_from_long_str(const char *s);
209-
mp_obj_t mp_obj_new_str(qstr qstr);
210+
mp_obj_t mp_obj_new_str(const byte* data, uint len, bool make_qstr_if_not_already);
210211
#if MICROPY_ENABLE_FLOAT
211212
mp_obj_t mp_obj_new_float(mp_float_t val);
212213
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
@@ -231,7 +232,7 @@ mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
231232
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self);
232233
mp_obj_t mp_obj_new_module(qstr module_name);
233234

234-
mp_obj_t mp_obj_get_type(mp_obj_t o_in);
235+
mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in);
235236
const char *mp_obj_get_type_str(mp_obj_t o_in);
236237

237238
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
@@ -248,7 +249,7 @@ machine_int_t mp_obj_get_int(mp_obj_t arg);
248249
mp_float_t mp_obj_get_float(mp_obj_t self_in);
249250
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
250251
#endif
251-
qstr mp_obj_get_qstr(mp_obj_t arg);
252+
//qstr mp_obj_get_qstr(mp_obj_t arg);
252253
mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n);
253254
uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index);
254255
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); /* may return NULL */
@@ -279,8 +280,13 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine
279280

280281
// str
281282
extern const mp_obj_type_t str_type;
282-
qstr mp_obj_str_get(mp_obj_t self_in);
283-
void mp_obj_str_print_qstr(void (*print)(void *env, const char *fmt, ...), void *env, qstr q, mp_print_kind_t kind);
283+
mp_obj_t mp_obj_str_builder_start(uint len, byte **data);
284+
mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in);
285+
bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2);
286+
uint mp_obj_str_get_hash(mp_obj_t self_in);
287+
uint mp_obj_str_get_len(mp_obj_t self_in);
288+
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
289+
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
284290

285291
#if MICROPY_ENABLE_FLOAT
286292
// float

py/objarray.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,11 @@ static mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
167167
switch (n_args) {
168168
case 2:
169169
{
170-
const char *code = qstr_str(mp_obj_str_get(args[0]));
170+
// TODO check args
171+
uint l;
172+
const byte *s = mp_obj_str_get_data(args[0], &l);
171173
mp_obj_t initializer = args[1];
172-
return array_construct(*code, initializer);
174+
return array_construct(*s, initializer);
173175
}
174176

175177
default:

py/objfun.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ mp_obj_t fun_native_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_
5656
// TODO if n_kw==0 then don't allocate any memory for map (either pass NULL or allocate it on the heap)
5757
mp_map_t *kw_args = mp_map_new(n_kw);
5858
for (int i = 0; i < 2 * n_kw; i += 2) {
59-
qstr name = mp_obj_str_get(args[n_args + i]);
60-
mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = args[n_args + i + 1];
59+
mp_map_lookup(kw_args, args[n_args + i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = args[n_args + i + 1];
6160
}
6261
mp_obj_t res = ((mp_fun_kw_t)self->fun)(n_args, args, kw_args);
6362
// TODO clean up kw_args
@@ -214,9 +213,10 @@ machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
214213
return 0;
215214
} else if (obj == mp_const_true) {
216215
return 1;
217-
} else if (MP_OBJ_IS_TYPE(obj, &str_type)) {
216+
} else if (MP_OBJ_IS_STR(obj)) {
218217
// pointer to the string (it's probably constant though!)
219-
return (machine_uint_t)qstr_str(mp_obj_str_get(obj));
218+
uint l;
219+
return (machine_uint_t)mp_obj_str_get_data(obj, &l);
220220
#if MICROPY_ENABLE_FLOAT
221221
} else if (MP_OBJ_IS_TYPE(obj, &float_type)) {
222222
// convert float to int (could also pass in float registers)

py/objint.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,35 @@ static mp_obj_t int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
2020
return MP_OBJ_NEW_SMALL_INT(0);
2121

2222
case 1:
23-
if (MP_OBJ_IS_TYPE(args[0], &str_type)) {
23+
if (MP_OBJ_IS_STR(args[0])) {
2424
// a string, parse it
25-
return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[0])), 0));
25+
uint l;
26+
const byte *s = mp_obj_str_get_data(args[0], &l);
27+
return MP_OBJ_NEW_SMALL_INT(strtonum((const char*)s, 0));
2628
} else {
2729
return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
2830
}
2931

3032
case 2:
33+
{
3134
// should be a string, parse it
3235
// TODO proper error checking of argument types
33-
return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[0])), mp_obj_get_int(args[1])));
36+
uint l;
37+
const byte *s = mp_obj_str_get_data(args[0], &l);
38+
return MP_OBJ_NEW_SMALL_INT(strtonum((const char*)s, mp_obj_get_int(args[1])));
39+
}
3440

3541
default:
3642
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
3743
}
3844
}
3945

40-
const mp_obj_type_t int_type = {
41-
{ &mp_const_type },
42-
"int",
43-
.print = int_print,
44-
.make_new = int_make_new,
45-
.binary_op = int_binary_op,
46-
};
47-
4846
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
49-
// This is called only for non-SMALL_INT
47+
5048
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
49+
if (MP_OBJ_IS_SMALL_INT(self_in)) {
50+
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(self_in));
51+
}
5152
}
5253

5354
// This is called only for non-SMALL_INT
@@ -88,4 +89,12 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) {
8889
return MP_OBJ_SMALL_INT_VALUE(self_in);
8990
}
9091

91-
#endif
92+
#endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
93+
94+
const mp_obj_type_t int_type = {
95+
{ &mp_const_type },
96+
"int",
97+
.print = int_print,
98+
.make_new = int_make_new,
99+
.binary_op = int_binary_op,
100+
};

py/objint_longlong.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ static mp_obj_t mp_obj_new_int_from_ll(long long val);
2424
#endif
2525

2626
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
27-
mp_obj_int_t *self = self_in;
28-
print(env, "%lld" SUFFIX, self->val);
27+
if (MP_OBJ_IS_SMALL_INT(self_in)) {
28+
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(self_in));
29+
} else {
30+
mp_obj_int_t *self = self_in;
31+
print(env, "%lld" SUFFIX, self->val);
32+
}
2933
}
3034

3135
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {

py/objmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ mp_obj_t mp_obj_new_module(qstr module_name) {
6464
o->name = module_name;
6565
o->globals = mp_map_new(1);
6666
el->value = o;
67-
mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = mp_obj_new_str(module_name);
67+
mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = MP_OBJ_NEW_QSTR(module_name);
6868
return o;
6969
}
7070

0 commit comments

Comments
 (0)