py/objstr: Remove "make_qstr_if_not_already" arg from mp_obj_new_str.

This patch simplifies the str creation API to favour the common case of
creating a str object that is not forced to be interned.  To force
interning of a new str the new mp_obj_new_str_via_qstr function is added,
and should only be used if warranted.

Apart from simplifying the mp_obj_new_str function (and making it have the
same signature as mp_obj_new_bytes), this patch also reduces code size by a
bit (-16 bytes for bare-arm and roughly -40 bytes on the bare-metal archs).
This commit is contained in:
Damien George 2017-11-16 13:17:51 +11:00
parent 6bc55b657b
commit 4601759bf5
24 changed files with 55 additions and 54 deletions

View File

@ -166,7 +166,7 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
goto fail;
}
S_NEXT(s);
next = mp_obj_new_str(vstr.buf, vstr.len, false);
next = mp_obj_new_str(vstr.buf, vstr.len);
break;
case '-':
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {

View File

@ -141,7 +141,7 @@ STATIC void handle_op(mp_obj_webrepl_t *self) {
// Handle operations requiring opened file
mp_obj_t open_args[2] = {
mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname), false),
mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname)),
MP_OBJ_NEW_QSTR(MP_QSTR_rb)
};

View File

@ -197,7 +197,7 @@ STATIC mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) {
if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]);
}
return mp_obj_new_str(buf, strlen(buf), false);
return mp_obj_new_str(buf, strlen(buf));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd);

View File

@ -57,7 +57,7 @@ STATIC mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) {
// make 3-tuple with info about this entry
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
if (self->is_str) {
t->items[0] = mp_obj_new_str(fn, strlen(fn), false);
t->items[0] = mp_obj_new_str(fn, strlen(fn));
} else {
t->items[0] = mp_obj_new_bytes((const byte*)fn, strlen(fn));
}

View File

@ -71,7 +71,7 @@ STATIC void mp_reader_vfs_close(void *data) {
void mp_reader_new_file(mp_reader_t *reader, const char *filename) {
mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t);
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename));
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
int errcode;
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);

View File

@ -41,7 +41,7 @@ mp_obj_t netutils_format_ipv4_addr(uint8_t *ip, netutils_endian_t endian) {
} else {
ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
}
return mp_obj_new_str(ip_str, ip_len, false);
return mp_obj_new_str(ip_str, ip_len);
}
// Takes an array with a raw IP address, and a port, and returns a net-address

View File

@ -885,7 +885,7 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
}
mp_obj_t tuple[5];
tuple[0] = mp_obj_new_str((const char *)wlanEntry.ssid, wlanEntry.ssid_len, false);
tuple[0] = mp_obj_new_str((const char *)wlanEntry.ssid, wlanEntry.ssid_len);
tuple[1] = mp_obj_new_bytes((const byte *)wlanEntry.bssid, SL_BSSID_LENGTH);
// 'normalize' the security type
if (wlanEntry.sec_type > 2) {
@ -1075,7 +1075,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_mode_obj, 1, 2, wlan_mode);
STATIC mp_obj_t wlan_ssid(size_t n_args, const mp_obj_t *args) {
wlan_obj_t *self = args[0];
if (n_args == 1) {
return mp_obj_new_str((const char *)self->ssid, strlen((const char *)self->ssid), false);
return mp_obj_new_str((const char *)self->ssid, strlen((const char *)self->ssid));
} else {
size_t len;
const char *ssid = mp_obj_str_get_data(args[1], &len);
@ -1095,7 +1095,7 @@ STATIC mp_obj_t wlan_auth(size_t n_args, const mp_obj_t *args) {
} else {
mp_obj_t security[2];
security[0] = mp_obj_new_int(self->auth);
security[1] = mp_obj_new_str((const char *)self->key, strlen((const char *)self->key), false);
security[1] = mp_obj_new_str((const char *)self->key, strlen((const char *)self->key));
return mp_obj_new_tuple(2, security);
}
} else {
@ -1199,7 +1199,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
// mp_obj_t connections = mp_obj_new_list(0, NULL);
//
// if (wlan_is_connected()) {
// device[0] = mp_obj_new_str((const char *)wlan_obj.ssid_o, strlen((const char *)wlan_obj.ssid_o), false);
// device[0] = mp_obj_new_str((const char *)wlan_obj.ssid_o, strlen((const char *)wlan_obj.ssid_o));
// device[1] = mp_obj_new_bytes((const byte *)wlan_obj.bssid, SL_BSSID_LENGTH);
// // add the device to the list
// mp_obj_list_append(connections, mp_obj_new_tuple(MP_ARRAY_SIZE(device), device));
@ -1232,7 +1232,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
// if (sl_NetAppGet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, &len, (uint8_t *)urn) < 0) {
// mp_raise_OSError(MP_EIO);
// }
// return mp_obj_new_str(urn, (len - 1), false);
// return mp_obj_new_str(urn, (len - 1));
// }
//
// return mp_const_none;

View File

@ -411,7 +411,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
}
case QS(MP_QSTR_essid):
req_if = SOFTAP_IF;
val = mp_obj_new_str((char*)cfg.ap.ssid, cfg.ap.ssid_len, false);
val = mp_obj_new_str((char*)cfg.ap.ssid, cfg.ap.ssid_len);
break;
case QS(MP_QSTR_hidden):
req_if = SOFTAP_IF;
@ -428,7 +428,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
case QS(MP_QSTR_dhcp_hostname): {
req_if = STATION_IF;
char* s = wifi_station_get_hostname();
val = mp_obj_new_str(s, strlen(s), false);
val = mp_obj_new_str(s, strlen(s));
break;
}
default:

View File

@ -60,7 +60,7 @@ STATIC mp_obj_tuple_t os_uname_info_obj = {
STATIC mp_obj_t os_uname(void) {
// We must populate the "release" field each time in case it was GC'd since the last call.
const char *ver = system_get_sdk_version();
os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver), false);
os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver));
return (mp_obj_t)&os_uname_info_obj;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);

View File

@ -531,8 +531,8 @@ STATIC mp_obj_t cc3k_ifconfig(mp_obj_t self_in) {
netutils_format_ipv4_addr(ipconfig.aucDefaultGateway, NETUTILS_LITTLE),
netutils_format_ipv4_addr(ipconfig.aucDNSServer, NETUTILS_LITTLE),
netutils_format_ipv4_addr(ipconfig.aucDHCPServer, NETUTILS_LITTLE),
mp_obj_new_str(mac_vstr.buf, mac_vstr.len, false),
mp_obj_new_str((const char*)ipconfig.uaSSID, strlen((const char*)ipconfig.uaSSID), false),
mp_obj_new_str(mac_vstr.buf, mac_vstr.len),
mp_obj_new_str((const char*)ipconfig.uaSSID, strlen((const char*)ipconfig.uaSSID)),
};
return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple);
}

View File

@ -227,7 +227,7 @@ STATIC mp_obj_t extra_coverage(void) {
mp_printf(&mp_plat_print, "# str\n");
// intern string
mp_printf(&mp_plat_print, "%d\n", MP_OBJ_IS_QSTR(mp_obj_str_intern(mp_obj_new_str("intern me", 9, false))));
mp_printf(&mp_plat_print, "%d\n", MP_OBJ_IS_QSTR(mp_obj_str_intern(mp_obj_new_str("intern me", 9))));
}
// mpz
@ -260,12 +260,12 @@ STATIC mp_obj_t extra_coverage(void) {
// call mp_call_function_1_protected
mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), MP_OBJ_NEW_SMALL_INT(1));
// call mp_call_function_1_protected with invalid args
mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), mp_obj_new_str("abc", 3, false));
mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), mp_obj_new_str("abc", 3));
// call mp_call_function_2_protected
mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), MP_OBJ_NEW_SMALL_INT(1), MP_OBJ_NEW_SMALL_INT(1));
// call mp_call_function_2_protected with invalid args
mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), mp_obj_new_str("abc", 3, false), mp_obj_new_str("abc", 3, false));
mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), mp_obj_new_str("abc", 3), mp_obj_new_str("abc", 3));
}
// warning

View File

@ -481,7 +481,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
vstr_add_strn(&vstr, p + 1, p1 - p - 1);
path_items[i] = mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
} else {
path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p));
path_items[i] = mp_obj_new_str_via_qstr(p, p1 - p);
}
p = p1 + 1;
}
@ -537,7 +537,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
return usage(argv);
}
mp_obj_t import_args[4];
import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]), false);
import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]));
import_args[1] = import_args[2] = mp_const_none;
// Ask __import__ to handle imported module specially - set its __name__
// to __main__, and also return this leaf module, not top-level package
@ -603,7 +603,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
// Set base dir of the script as first entry in sys.path
char *p = strrchr(basedir, '/');
path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir));
path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir);
free(pathbuf);
set_sys_argv(argv, argc, a);

View File

@ -144,7 +144,7 @@ STATIC mp_obj_t return_ffi_value(ffi_arg val, char type)
if (!s) {
return mp_const_none;
}
return mp_obj_new_str(s, strlen(s), false);
return mp_obj_new_str(s, strlen(s));
}
case 'v':
return mp_const_none;

View File

@ -337,7 +337,7 @@ STATIC mp_obj_t new_jobject(jobject jo) {
return mp_const_none;
} else if (JJ(IsInstanceOf, jo, String_class)) {
const char *s = JJ(GetStringUTFChars, jo, NULL);
mp_obj_t ret = mp_obj_new_str(s, strlen(s), false);
mp_obj_t ret = mp_obj_new_str(s, strlen(s));
JJ(ReleaseStringUTFChars, jo, s);
return ret;
} else if (JJ(IsInstanceOf, jo, Class_class)) {

View File

@ -133,7 +133,7 @@ STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) {
if (s == NULL) {
return mp_const_none;
}
return mp_obj_new_str(s, strlen(s), false);
return mp_obj_new_str(s, strlen(s));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_obj, mod_os_getenv);
@ -171,7 +171,7 @@ STATIC mp_obj_t listdir_next(mp_obj_t self_in) {
}
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
t->items[0] = mp_obj_new_str(dirent->d_name, strlen(dirent->d_name), false);
t->items[0] = mp_obj_new_str(dirent->d_name, strlen(dirent->d_name));
#ifdef _DIRENT_HAVE_D_TYPE
t->items[1] = MP_OBJ_NEW_SMALL_INT(dirent->d_type);
#else

View File

@ -91,7 +91,7 @@ STATIC mp_obj_t format_inet_addr(struct sockaddr *addr, mp_obj_t port) {
net_addr_ntop(addr->sa_family, &sockaddr_in6->sin6_addr, buf, sizeof(buf));
mp_obj_tuple_t *tuple = mp_obj_new_tuple(addr->sa_family == AF_INET ? 2 : 4, NULL);
tuple->items[0] = mp_obj_new_str(buf, strlen(buf), false);
tuple->items[0] = mp_obj_new_str(buf, strlen(buf));
// We employ the fact that port offset is the same for IPv4 & IPv6
// not filled in
//tuple->items[1] = mp_obj_new_int(ntohs(((struct sockaddr_in*)addr)->sin_port));

View File

@ -206,7 +206,7 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
return (mp_obj_t)(mp_uint_t)val;
} else if (val_type == 'S') {
const char *s_val = (const char*)(uintptr_t)(mp_uint_t)val;
return mp_obj_new_str(s_val, strlen(s_val), false);
return mp_obj_new_str(s_val, strlen(s_val));
#if MICROPY_PY_BUILTINS_FLOAT
} else if (val_type == 'f') {
union { uint32_t i; float f; } fpu = {val};

View File

@ -69,7 +69,7 @@ STATIC void mp_help_add_from_names(mp_obj_t list, const char *name) {
while (*name) {
size_t l = strlen(name);
// name should end in '.py' and we strip it off
mp_obj_list_append(list, mp_obj_new_str(name, l - 3, false));
mp_obj_list_append(list, mp_obj_new_str(name, l - 3));
name += l + 1;
}
}

View File

@ -434,7 +434,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
DEBUG_printf("%.*s is dir\n", vstr_len(&path), vstr_str(&path));
// https://docs.python.org/3/reference/import.html
// "Specifically, any module that contains a __path__ attribute is considered a package."
mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path), false));
mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path)));
size_t orig_path_len = path.len;
vstr_add_char(&path, PATH_SEP_CHAR);
vstr_add_str(&path, "__init__.py");

View File

@ -159,12 +159,12 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
} else {
mp_raise_ValueError("chr() arg not in range(0x110000)");
}
return mp_obj_new_str(str, len, true);
return mp_obj_new_str_via_qstr(str, len);
#else
mp_int_t ord = mp_obj_get_int(o_in);
if (0 <= ord && ord <= 0xff) {
char str[1] = {ord};
return mp_obj_new_str(str, 1, true);
return mp_obj_new_str_via_qstr(str, 1);
} else {
mp_raise_ValueError("chr() arg not in range(256)");
}

View File

@ -176,7 +176,7 @@ STATIC mp_obj_t resource_stream(mp_obj_t package_in, mp_obj_t path_in) {
return MP_OBJ_FROM_PTR(o);
}
mp_obj_t path_out = mp_obj_new_str(path_buf.buf, path_buf.len, false);
mp_obj_t path_out = mp_obj_new_str(path_buf.buf, path_buf.len);
return mp_builtin_open(1, &path_out, (mp_map_t*)&mp_const_empty_map);
}
MP_DEFINE_CONST_FUN_OBJ_2(resource_stream_obj, resource_stream);

View File

@ -637,7 +637,8 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value);
mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base);
mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already);
mp_obj_t mp_obj_new_str(const char* data, size_t len);
mp_obj_t mp_obj_new_str_via_qstr(const char* data, size_t len);
mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr);
mp_obj_t mp_obj_new_bytes(const byte* data, size_t len);
mp_obj_t mp_obj_new_bytearray(size_t n, void *items);

View File

@ -176,7 +176,7 @@ mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
mp_raise_msg(&mp_type_UnicodeError, NULL);
}
#endif
return mp_obj_new_str(bufinfo.buf, bufinfo.len, false);
return mp_obj_new_str(bufinfo.buf, bufinfo.len);
}
}
}
@ -423,7 +423,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
if (MICROPY_PY_BUILTINS_STR_UNICODE || type == &mp_type_bytes) {
return MP_OBJ_NEW_SMALL_INT(self_data[index_val]);
} else {
return mp_obj_new_str((char*)&self_data[index_val], 1, true);
return mp_obj_new_str_via_qstr((char*)&self_data[index_val], 1);
}
} else {
return MP_OBJ_NULL; // op not supported
@ -1046,7 +1046,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
} else {
const char *lookup;
for (lookup = field_name; lookup < field_name_top && *lookup != '.' && *lookup != '['; lookup++);
mp_obj_t field_q = mp_obj_new_str(field_name, lookup - field_name, true/*?*/);
mp_obj_t field_q = mp_obj_new_str_via_qstr(field_name, lookup - field_name); // should it be via qstr?
field_name = lookup;
mp_map_elem_t *key_elem = mp_map_lookup(kwargs, field_q, MP_MAP_LOOKUP);
if (key_elem == NULL) {
@ -1413,7 +1413,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
}
++str;
}
mp_obj_t k_obj = mp_obj_new_str((const char*)key, str - key, true);
mp_obj_t k_obj = mp_obj_new_str_via_qstr((const char*)key, str - key);
arg = mp_obj_dict_get(dict, k_obj);
str++;
}
@ -1992,6 +1992,11 @@ mp_obj_t mp_obj_new_str_of_type(const mp_obj_type_t *type, const byte* data, siz
return MP_OBJ_FROM_PTR(o);
}
// Create a str using a qstr to store the data; may use existing or new qstr.
mp_obj_t mp_obj_new_str_via_qstr(const char* data, size_t len) {
return MP_OBJ_NEW_QSTR(qstr_from_strn(data, len));
}
// Create a str/bytes object from the given vstr. The vstr buffer is resized to
// the exact length required and then reused for the str/bytes object. The vstr
// is cleared and can safely be passed to vstr_free if it was heap allocated.
@ -2022,25 +2027,20 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) {
return MP_OBJ_FROM_PTR(o);
}
mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already) {
if (make_qstr_if_not_already) {
// use existing, or make a new qstr
return MP_OBJ_NEW_QSTR(qstr_from_strn(data, len));
mp_obj_t mp_obj_new_str(const char* data, size_t len) {
qstr q = qstr_find_strn(data, len);
if (q != MP_QSTR_NULL) {
// qstr with this data already exists
return MP_OBJ_NEW_QSTR(q);
} else {
qstr q = qstr_find_strn(data, len);
if (q != MP_QSTR_NULL) {
// qstr with this data already exists
return MP_OBJ_NEW_QSTR(q);
} else {
// no existing qstr, don't make one
return mp_obj_new_str_of_type(&mp_type_str, (const byte*)data, len);
}
// no existing qstr, don't make one
return mp_obj_new_str_of_type(&mp_type_str, (const byte*)data, len);
}
}
mp_obj_t mp_obj_str_intern(mp_obj_t str) {
GET_STR_DATA_LEN(str, data, len);
return MP_OBJ_NEW_QSTR(qstr_from_strn((const char*)data, len));
return mp_obj_new_str_via_qstr((const char*)data, len);
}
mp_obj_t mp_obj_new_bytes(const byte* data, size_t len) {
@ -2138,7 +2138,7 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
mp_obj_str8_it_t *self = MP_OBJ_TO_PTR(self_in);
GET_STR_DATA_LEN(self->str, str, len);
if (self->cur < len) {
mp_obj_t o_out = mp_obj_new_str((const char*)str + self->cur, 1, true);
mp_obj_t o_out = mp_obj_new_str_via_qstr((const char*)str + self->cur, 1);
self->cur += 1;
return o_out;
} else {

View File

@ -216,7 +216,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
++len;
}
}
return mp_obj_new_str((const char*)s, len, true); // This will create a one-character string
return mp_obj_new_str_via_qstr((const char*)s, len); // This will create a one-character string
} else {
return MP_OBJ_NULL; // op not supported
}
@ -291,7 +291,7 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
if (self->cur < len) {
const byte *cur = str + self->cur;
const byte *end = utf8_next_char(str + self->cur);
mp_obj_t o_out = mp_obj_new_str((const char*)cur, end - cur, true);
mp_obj_t o_out = mp_obj_new_str_via_qstr((const char*)cur, end - cur);
self->cur += end - cur;
return o_out;
} else {