mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Several optimizations and speed improvements.
cstubs: Use Matrix type instead of float[4][4].
This commit is contained in:
		
							parent
							
								
									a75d306e2b
								
							
						
					
					
						commit
						3bb8a05947
					
				
					 10 changed files with 216 additions and 63 deletions
				
			
		|  | @ -51,6 +51,9 @@ functions should be applied to nil objects. | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| 	OB_VARHEAD | 	OB_VARHEAD | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	long ob_shash; | ||||||
|  | #endif | ||||||
| 	char ob_sval[1]; | 	char ob_sval[1]; | ||||||
| } stringobject; | } stringobject; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -529,21 +529,21 @@ gl_getmatrix(self, args) | ||||||
| 	object *self; | 	object *self; | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	float arg1 [ 16 ] ; | 	Matrix arg1; | ||||||
| 	object *v, *w; | 	object *v, *w; | ||||||
| 	int i; | 	int i, j; | ||||||
| 	getmatrix( arg1 ); | 	getmatrix( arg1 ); | ||||||
| 	v = newlistobject(16); | 	v = newlistobject(16); | ||||||
| 	if (v == NULL) { | 	if (v == NULL) { | ||||||
| 		return err_nomem(); | 		return err_nomem(); | ||||||
| 	} | 	} | ||||||
| 	for (i = 0; i < 16; i++) { | 	for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) { | ||||||
| 		w = mknewfloatobject(arg1[i]); | 		w = mknewfloatobject(arg1[i][j]); | ||||||
| 		if (w == NULL) { | 		if (w == NULL) { | ||||||
| 			DECREF(v); | 			DECREF(v); | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		} | 		} | ||||||
| 		setlistitem(v, i, w); | 		setlistitem(v, i*4+j, w); | ||||||
| 	} | 	} | ||||||
| 	return v; | 	return v; | ||||||
| } | } | ||||||
|  | @ -559,7 +559,7 @@ gl_altgetmatrix(self, args) | ||||||
| 	object *self; | 	object *self; | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	float arg1 [ 4 ] [ 4 ] ; | 	Matrix arg1; | ||||||
| 	object *v, *w; | 	object *v, *w; | ||||||
| 	int i, j; | 	int i, j; | ||||||
| 	getmatrix( arg1 ); | 	getmatrix( arg1 ); | ||||||
|  | @ -742,7 +742,7 @@ gl_packrect(self, args) | ||||||
| 	if (packed == NULL) | 	if (packed == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	parray = (unsigned long *) getstringvalue(unpacked); | 	parray = (unsigned long *) getstringvalue(unpacked); | ||||||
| 	p = getstringvalue(packed); | 	p = (unsigned char *) getstringvalue(packed); | ||||||
| 	for (y = 0; y < height; y += packfactor, parray += packfactor*width) { | 	for (y = 0; y < height; y += packfactor, parray += packfactor*width) { | ||||||
| 		for (x = 0; x < width; x += packfactor) { | 		for (x = 0; x < width; x += packfactor) { | ||||||
| 			pixel = parray[x]; | 			pixel = parray[x]; | ||||||
|  |  | ||||||
|  | @ -254,24 +254,26 @@ strop_lower(self, args) | ||||||
| 	object *self; /* Not used */ | 	object *self; /* Not used */ | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	char *s; | 	char *s, *s_new; | ||||||
| 	int i, n; | 	int i, n; | ||||||
| 	object *new; | 	object *new; | ||||||
| 	int changed; | 	int changed; | ||||||
| 
 | 
 | ||||||
| 	if (!getargs(args, "s#", &s, &n)) | 	if (!getargs(args, "s#", &s, &n)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	new = newsizedstringobject(s, n); | 	new = newsizedstringobject(NULL, n); | ||||||
| 	if (new == NULL) | 	if (new == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	s = getstringvalue(new); | 	s_new = getstringvalue(new); | ||||||
| 	changed = 0; | 	changed = 0; | ||||||
| 	for (i = 0; i < n; i++) { | 	for (i = 0; i < n; i++) { | ||||||
| 		char c = s[i]; | 		char c = *s++; | ||||||
| 		if (isupper(c)) { | 		if (isupper(c)) { | ||||||
| 			changed = 1; | 			changed = 1; | ||||||
| 			s[i] = tolower(c); | 			*s_new = tolower(c); | ||||||
| 		} | 		} else | ||||||
|  | 			*s_new = c; | ||||||
|  | 		s_new++; | ||||||
| 	} | 	} | ||||||
| 	if (!changed) { | 	if (!changed) { | ||||||
| 		DECREF(new); | 		DECREF(new); | ||||||
|  | @ -287,24 +289,26 @@ strop_upper(self, args) | ||||||
| 	object *self; /* Not used */ | 	object *self; /* Not used */ | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	char *s; | 	char *s, *s_new; | ||||||
| 	int i, n; | 	int i, n; | ||||||
| 	object *new; | 	object *new; | ||||||
| 	int changed; | 	int changed; | ||||||
| 
 | 
 | ||||||
| 	if (!getargs(args, "s#", &s, &n)) | 	if (!getargs(args, "s#", &s, &n)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	new = newsizedstringobject(s, n); | 	new = newsizedstringobject(NULL, n); | ||||||
| 	if (new == NULL) | 	if (new == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	s = getstringvalue(new); | 	s_new = getstringvalue(new); | ||||||
| 	changed = 0; | 	changed = 0; | ||||||
| 	for (i = 0; i < n; i++) { | 	for (i = 0; i < n; i++) { | ||||||
| 		char c = s[i]; | 		char c = *s++; | ||||||
| 		if (islower(c)) { | 		if (islower(c)) { | ||||||
| 			changed = 1; | 			changed = 1; | ||||||
| 			s[i] = toupper(c); | 			*s_new = toupper(c); | ||||||
| 		} | 		} else | ||||||
|  | 			*s_new = c; | ||||||
|  | 		s_new++; | ||||||
| 	} | 	} | ||||||
| 	if (!changed) { | 	if (!changed) { | ||||||
| 		DECREF(new); | 		DECREF(new); | ||||||
|  | @ -320,28 +324,31 @@ strop_swapcase(self, args) | ||||||
| 	object *self; /* Not used */ | 	object *self; /* Not used */ | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	char *s; | 	char *s, *s_new; | ||||||
| 	int i, n; | 	int i, n; | ||||||
| 	object *new; | 	object *new; | ||||||
| 	int changed; | 	int changed; | ||||||
| 
 | 
 | ||||||
| 	if (!getargs(args, "s#", &s, &n)) | 	if (!getargs(args, "s#", &s, &n)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	new = newsizedstringobject(s, n); | 	new = newsizedstringobject(NULL, n); | ||||||
| 	if (new == NULL) | 	if (new == NULL) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	s = getstringvalue(new); | 	s_new = getstringvalue(new); | ||||||
| 	changed = 0; | 	changed = 0; | ||||||
| 	for (i = 0; i < n; i++) { | 	for (i = 0; i < n; i++) { | ||||||
| 		char c = s[i]; | 		char c = *s++; | ||||||
| 		if (islower(c)) { | 		if (islower(c)) { | ||||||
| 			changed = 1; | 			changed = 1; | ||||||
| 			s[i] = toupper(c); | 			*s_new = toupper(c); | ||||||
| 		} | 		} | ||||||
| 		else if (isupper(c)) { | 		else if (isupper(c)) { | ||||||
| 			changed = 1; | 			changed = 1; | ||||||
| 			s[i] = tolower(c); | 			*s_new = tolower(c); | ||||||
| 		} | 		} | ||||||
|  | 		else | ||||||
|  | 			*s_new = c; | ||||||
|  | 		s_new++; | ||||||
| 	} | 	} | ||||||
| 	if (!changed) { | 	if (!changed) { | ||||||
| 		DECREF(new); | 		DECREF(new); | ||||||
|  |  | ||||||
|  | @ -232,10 +232,11 @@ isprivileged(caller) | ||||||
| 	object *caller; | 	object *caller; | ||||||
| { | { | ||||||
| 	object *g; | 	object *g; | ||||||
| 	if (caller != NULL && hasattr(caller, "__privileged__")) | 	static char privileged[] = "__privileged__"; | ||||||
|  | 	if (caller != NULL && hasattr(caller, privileged)) | ||||||
| 		return 1; | 		return 1; | ||||||
| 	g = getglobals(); | 	g = getglobals(); | ||||||
| 	if (g != NULL && dictlookup(g, "__privileged__")) | 	if (g != NULL && dictlookup(g, privileged)) | ||||||
| 		return 1; | 		return 1; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -355,13 +355,15 @@ instance_getattr(inst, name) | ||||||
| { | { | ||||||
| 	register object *v; | 	register object *v; | ||||||
| 	classobject *class; | 	classobject *class; | ||||||
| 	if (strcmp(name, "__dict__") == 0) { | 	if (name[0] == '_' && name[1] == '_') { | ||||||
| 		INCREF(inst->in_dict); | 		if (strcmp(name, "__dict__") == 0) { | ||||||
| 		return inst->in_dict; | 			INCREF(inst->in_dict); | ||||||
| 	} | 			return inst->in_dict; | ||||||
| 	if (strcmp(name, "__class__") == 0) { | 		} | ||||||
| 		INCREF(inst->in_class); | 		if (strcmp(name, "__class__") == 0) { | ||||||
| 		return (object *)inst->in_class; | 			INCREF(inst->in_class); | ||||||
|  | 			return (object *)inst->in_class; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	class = NULL; | 	class = NULL; | ||||||
| 	v = dictlookup(inst->in_dict, name); | 	v = dictlookup(inst->in_dict, name); | ||||||
|  |  | ||||||
|  | @ -242,6 +242,9 @@ mappinglookup(op, key) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | @ -260,6 +263,9 @@ mappinginsert(op, key, value) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
|  | @ -289,6 +295,9 @@ mappingremove(op, key) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
|  | @ -447,7 +456,11 @@ mapping_subscript(mp, key) | ||||||
| 	register object *key; | 	register object *key; | ||||||
| { | { | ||||||
| 	object *v; | 	object *v; | ||||||
| 	long hash = hashobject(key); | 	long hash; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
|  | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	v = lookmapping(mp, key, hash) -> me_value; | 	v = lookmapping(mp, key, hash) -> me_value; | ||||||
|  | @ -628,9 +641,15 @@ mapping_compare(a, b) | ||||||
| 		res = cmpobject(akey, bkey); | 		res = cmpobject(akey, bkey); | ||||||
| 		if (res != 0) | 		if (res != 0) | ||||||
| 			break; | 			break; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 		if (!is_stringobject(akey) || (ahash = ((stringobject *) akey)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 		ahash = hashobject(akey); | 		ahash = hashobject(akey); | ||||||
| 		if (ahash == -1) | 		if (ahash == -1) | ||||||
| 			err_clear(); /* Don't want errors here */ | 			err_clear(); /* Don't want errors here */ | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 		if (!is_stringobject(bkey) || (bhash = ((stringobject *) bkey)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 		bhash = hashobject(bkey); | 		bhash = hashobject(bkey); | ||||||
| 		if (bhash == -1) | 		if (bhash == -1) | ||||||
| 			err_clear(); /* Don't want errors here */ | 			err_clear(); /* Don't want errors here */ | ||||||
|  | @ -661,6 +680,9 @@ mapping_has_key(mp, args) | ||||||
| 	register long ok; | 	register long ok; | ||||||
| 	if (!getargs(args, "O", &key)) | 	if (!getargs(args, "O", &key)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
|  | @ -242,6 +242,9 @@ mappinglookup(op, key) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | @ -260,6 +263,9 @@ mappinginsert(op, key, value) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
|  | @ -289,6 +295,9 @@ mappingremove(op, key) | ||||||
| 		err_badcall(); | 		err_badcall(); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
|  | @ -447,7 +456,11 @@ mapping_subscript(mp, key) | ||||||
| 	register object *key; | 	register object *key; | ||||||
| { | { | ||||||
| 	object *v; | 	object *v; | ||||||
| 	long hash = hashobject(key); | 	long hash; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
|  | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	v = lookmapping(mp, key, hash) -> me_value; | 	v = lookmapping(mp, key, hash) -> me_value; | ||||||
|  | @ -628,9 +641,15 @@ mapping_compare(a, b) | ||||||
| 		res = cmpobject(akey, bkey); | 		res = cmpobject(akey, bkey); | ||||||
| 		if (res != 0) | 		if (res != 0) | ||||||
| 			break; | 			break; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 		if (!is_stringobject(akey) || (ahash = ((stringobject *) akey)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 		ahash = hashobject(akey); | 		ahash = hashobject(akey); | ||||||
| 		if (ahash == -1) | 		if (ahash == -1) | ||||||
| 			err_clear(); /* Don't want errors here */ | 			err_clear(); /* Don't want errors here */ | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 		if (!is_stringobject(bkey) || (bhash = ((stringobject *) bkey)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 		bhash = hashobject(bkey); | 		bhash = hashobject(bkey); | ||||||
| 		if (bhash == -1) | 		if (bhash == -1) | ||||||
| 			err_clear(); /* Don't want errors here */ | 			err_clear(); /* Don't want errors here */ | ||||||
|  | @ -661,6 +680,9 @@ mapping_has_key(mp, args) | ||||||
| 	register long ok; | 	register long ok; | ||||||
| 	if (!getargs(args, "O", &key)) | 	if (!getargs(args, "O", &key)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1) | ||||||
|  | #endif | ||||||
| 	hash = hashobject(key); | 	hash = hashobject(key); | ||||||
| 	if (hash == -1) | 	if (hash == -1) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ long ref_total; | ||||||
| static typeobject *type_list; | static typeobject *type_list; | ||||||
| extern int tuple_zero_allocs, fast_tuple_allocs; | extern int tuple_zero_allocs, fast_tuple_allocs; | ||||||
| extern int quick_int_allocs, quick_neg_int_allocs; | extern int quick_int_allocs, quick_neg_int_allocs; | ||||||
|  | extern int null_strings, one_strings; | ||||||
| void | void | ||||||
| dump_counts() | dump_counts() | ||||||
| { | { | ||||||
|  | @ -51,6 +52,7 @@ dump_counts() | ||||||
| 	       tuple_zero_allocs); | 	       tuple_zero_allocs); | ||||||
| 	printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs, | 	printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs, | ||||||
| 	       quick_neg_int_allocs); | 	       quick_neg_int_allocs); | ||||||
|  | 	printf("null strings: %d, 1-strings: %d\n", null_strings, one_strings); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  |  | ||||||
|  | @ -26,21 +26,76 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
| 
 | 
 | ||||||
| #include "allobjects.h" | #include "allobjects.h" | ||||||
| 
 | 
 | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | int null_strings, one_strings; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef __STDC__ | ||||||
|  | #include <limits.h> | ||||||
|  | #else | ||||||
|  | #ifndef UCHAR_MAX | ||||||
|  | #define UCHAR_MAX 255 | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static stringobject *characters[UCHAR_MAX + 1]; | ||||||
|  | static stringobject *nullstring; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |    Newsizedstringobject() and newstringobject() try in certain cases | ||||||
|  |    to share string objects.  When the size of the string is zero, | ||||||
|  |    these routines always return a pointer to the same string object; | ||||||
|  |    when the size is one, they return a pointer to an already existing | ||||||
|  |    object if the contents of the string is known.  For | ||||||
|  |    newstringobject() this is always the case, for | ||||||
|  |    newsizedstringobject() this is the case when the first argument in | ||||||
|  |    not NULL. | ||||||
|  |    A common practice to allocate a string and then fill it in or | ||||||
|  |    change it must be done carefully.  It is only allowed to change the | ||||||
|  |    contents of the string if the obect was gotten from | ||||||
|  |    newsizedstringobject() with a NULL first argument, because in the | ||||||
|  |    future these routines may try to do even more sharing of objects. | ||||||
|  | */ | ||||||
| object * | object * | ||||||
| newsizedstringobject(str, size) | newsizedstringobject(str, size) | ||||||
| 	char *str; | 	char *str; | ||||||
| 	int size; | 	int size; | ||||||
| { | { | ||||||
| 	register stringobject *op = (stringobject *) | 	register stringobject *op; | ||||||
|  | 	if (size == 0 && (op = nullstring) != NULL) { | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | 		null_strings++; | ||||||
|  | #endif | ||||||
|  | 		INCREF(op); | ||||||
|  | 		return op; | ||||||
|  | 	} | ||||||
|  | 	if (size == 1 && str != NULL && (op = characters[*str & UCHAR_MAX]) != NULL) { | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | 		one_strings++; | ||||||
|  | #endif | ||||||
|  | 		INCREF(op); | ||||||
|  | 		return op; | ||||||
|  | 	} | ||||||
|  | 	op = (stringobject *) | ||||||
| 		malloc(sizeof(stringobject) + size * sizeof(char)); | 		malloc(sizeof(stringobject) + size * sizeof(char)); | ||||||
| 	if (op == NULL) | 	if (op == NULL) | ||||||
| 		return err_nomem(); | 		return err_nomem(); | ||||||
| 	op->ob_type = &Stringtype; | 	op->ob_type = &Stringtype; | ||||||
| 	op->ob_size = size; | 	op->ob_size = size; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	op->ob_shash = -1; | ||||||
|  | #endif | ||||||
| 	NEWREF(op); | 	NEWREF(op); | ||||||
| 	if (str != NULL) | 	if (str != NULL) | ||||||
| 		memcpy(op->ob_sval, str, size); | 		memcpy(op->ob_sval, str, size); | ||||||
| 	op->ob_sval[size] = '\0'; | 	op->ob_sval[size] = '\0'; | ||||||
|  | 	if (size == 0) { | ||||||
|  | 		nullstring = op; | ||||||
|  | 		INCREF(op); | ||||||
|  | 	} else if (size == 1 && str != NULL) { | ||||||
|  | 		characters[*str & UCHAR_MAX] = op; | ||||||
|  | 		INCREF(op); | ||||||
|  | 	} | ||||||
| 	return (object *) op; | 	return (object *) op; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -49,14 +104,39 @@ newstringobject(str) | ||||||
| 	char *str; | 	char *str; | ||||||
| { | { | ||||||
| 	register unsigned int size = strlen(str); | 	register unsigned int size = strlen(str); | ||||||
| 	register stringobject *op = (stringobject *) | 	register stringobject *op; | ||||||
|  | 	if (size == 0 && (op = nullstring) != NULL) { | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | 		null_strings++; | ||||||
|  | #endif | ||||||
|  | 		INCREF(op); | ||||||
|  | 		return op; | ||||||
|  | 	} | ||||||
|  | 	if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) { | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | 		one_strings++; | ||||||
|  | #endif | ||||||
|  | 		INCREF(op); | ||||||
|  | 		return op; | ||||||
|  | 	} | ||||||
|  | 	op = (stringobject *) | ||||||
| 		malloc(sizeof(stringobject) + size * sizeof(char)); | 		malloc(sizeof(stringobject) + size * sizeof(char)); | ||||||
| 	if (op == NULL) | 	if (op == NULL) | ||||||
| 		return err_nomem(); | 		return err_nomem(); | ||||||
| 	op->ob_type = &Stringtype; | 	op->ob_type = &Stringtype; | ||||||
| 	op->ob_size = size; | 	op->ob_size = size; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	op->ob_shash = -1; | ||||||
|  | #endif | ||||||
| 	NEWREF(op); | 	NEWREF(op); | ||||||
| 	strcpy(op->ob_sval, str); | 	strcpy(op->ob_sval, str); | ||||||
|  | 	if (size == 0) { | ||||||
|  | 		nullstring = op; | ||||||
|  | 		INCREF(op); | ||||||
|  | 	} else if (size == 1) { | ||||||
|  | 		characters[*str & UCHAR_MAX] = op; | ||||||
|  | 		INCREF(op); | ||||||
|  | 	} | ||||||
| 	return (object *) op; | 	return (object *) op; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -189,6 +269,9 @@ string_concat(a, bb) | ||||||
| 		return err_nomem(); | 		return err_nomem(); | ||||||
| 	op->ob_type = &Stringtype; | 	op->ob_type = &Stringtype; | ||||||
| 	op->ob_size = size; | 	op->ob_size = size; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	op->ob_shash = -1; | ||||||
|  | #endif | ||||||
| 	NEWREF(op); | 	NEWREF(op); | ||||||
| 	memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); | 	memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); | ||||||
| 	memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); | 	memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); | ||||||
|  | @ -218,6 +301,9 @@ string_repeat(a, n) | ||||||
| 		return err_nomem(); | 		return err_nomem(); | ||||||
| 	op->ob_type = &Stringtype; | 	op->ob_type = &Stringtype; | ||||||
| 	op->ob_size = size; | 	op->ob_size = size; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	op->ob_shash = -1; | ||||||
|  | #endif | ||||||
| 	NEWREF(op); | 	NEWREF(op); | ||||||
| 	for (i = 0; i < size; i += a->ob_size) | 	for (i = 0; i < size; i += a->ob_size) | ||||||
| 		memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); | 		memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); | ||||||
|  | @ -247,16 +333,6 @@ string_slice(a, i, j) | ||||||
| 	return newsizedstringobject(a->ob_sval + i, (int) (j-i)); | 	return newsizedstringobject(a->ob_sval + i, (int) (j-i)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef __STDC__ |  | ||||||
| #include <limits.h> |  | ||||||
| #else |  | ||||||
| #ifndef UCHAR_MAX |  | ||||||
| #define UCHAR_MAX 255 |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| static object *characters[UCHAR_MAX + 1]; |  | ||||||
| 
 |  | ||||||
| static object * | static object * | ||||||
| string_item(a, i) | string_item(a, i) | ||||||
| 	stringobject *a; | 	stringobject *a; | ||||||
|  | @ -269,12 +345,16 @@ string_item(a, i) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 	c = a->ob_sval[i] & UCHAR_MAX; | 	c = a->ob_sval[i] & UCHAR_MAX; | ||||||
| 	v = characters[c]; | 	v = (object *) characters[c]; | ||||||
|  | #ifdef COUNT_ALLOCS | ||||||
|  | 	if (v != NULL) | ||||||
|  | 		one_strings++; | ||||||
|  | #endif | ||||||
| 	if (v == NULL) { | 	if (v == NULL) { | ||||||
| 		v = newsizedstringobject((char *)NULL, 1); | 		v = newsizedstringobject((char *)NULL, 1); | ||||||
| 		if (v == NULL) | 		if (v == NULL) | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		characters[c] = v; | 		characters[c] = (stringobject *) v; | ||||||
| 		((stringobject *)v)->ob_sval[0] = c; | 		((stringobject *)v)->ob_sval[0] = c; | ||||||
| 	} | 	} | ||||||
| 	INCREF(v); | 	INCREF(v); | ||||||
|  | @ -287,9 +367,14 @@ string_compare(a, b) | ||||||
| { | { | ||||||
| 	int len_a = a->ob_size, len_b = b->ob_size; | 	int len_a = a->ob_size, len_b = b->ob_size; | ||||||
| 	int min_len = (len_a < len_b) ? len_a : len_b; | 	int min_len = (len_a < len_b) ? len_a : len_b; | ||||||
| 	int cmp = memcmp(a->ob_sval, b->ob_sval, min_len); | 	int cmp; | ||||||
| 	if (cmp != 0) | 	if (min_len > 0) { | ||||||
| 		return cmp; | 		cmp = *a->ob_sval - *b->ob_sval; | ||||||
|  | 		if (cmp == 0) | ||||||
|  | 			cmp = memcmp(a->ob_sval, b->ob_sval, min_len); | ||||||
|  | 		if (cmp != 0) | ||||||
|  | 			return cmp; | ||||||
|  | 	} | ||||||
| 	return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; | 	return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -297,14 +382,25 @@ static long | ||||||
| string_hash(a) | string_hash(a) | ||||||
| 	stringobject *a; | 	stringobject *a; | ||||||
| { | { | ||||||
| 	register int len = a->ob_size; | 	register int len; | ||||||
| 	register unsigned char *p = (unsigned char *) a->ob_sval; | 	register unsigned char *p; | ||||||
| 	register long x = *p << 7; | 	register long x; | ||||||
|  | 
 | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	if (a->ob_shash != -1) | ||||||
|  | 		return a->ob_shash; | ||||||
|  | #endif | ||||||
|  | 	len = a->ob_size; | ||||||
|  | 	p = (unsigned char *) a->ob_sval; | ||||||
|  | 	x = *p << 7; | ||||||
| 	while (--len >= 0) | 	while (--len >= 0) | ||||||
| 		x = (x + x + x) ^ *p++; | 		x = (x + x + x) ^ *p++; | ||||||
| 	x ^= a->ob_size; | 	x ^= a->ob_size; | ||||||
| 	if (x == -1) | 	if (x == -1) | ||||||
| 		x = -2; | 		x = -2; | ||||||
|  | #ifdef CACHE_HASH | ||||||
|  | 	a->ob_shash = x; | ||||||
|  | #endif | ||||||
| 	return x; | 	return x; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -821,7 +821,7 @@ eval_code(co, globals, locals, owner, arg) | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if ((err = dict2remove(f->f_locals, w)) != 0) | 			if ((err = dict2remove(f->f_locals, w)) != 0) | ||||||
| 				err_setstr(NameError, getstringvalue(w)); | 				err_setval(NameError, w); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| #ifdef CASE_TOO_BIG | #ifdef CASE_TOO_BIG | ||||||
|  | @ -1031,7 +1031,7 @@ eval_code(co, globals, locals, owner, arg) | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if ((err = dict2remove(f->f_globals, w)) != 0) | 			if ((err = dict2remove(f->f_globals, w)) != 0) | ||||||
| 				err_setstr(NameError, getstringvalue(w)); | 				err_setval(NameError, w); | ||||||
| 			break; | 			break; | ||||||
| 		 | 		 | ||||||
| 		case LOAD_CONST: | 		case LOAD_CONST: | ||||||
|  | @ -1050,8 +1050,7 @@ eval_code(co, globals, locals, owner, arg) | ||||||
| 					err_clear(); | 					err_clear(); | ||||||
| 					x = getbuiltin(w); | 					x = getbuiltin(w); | ||||||
| 					if (x == NULL) { | 					if (x == NULL) { | ||||||
| 						err_setstr(NameError, | 						err_setval(NameError, w); | ||||||
| 							getstringvalue(w)); |  | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | @ -1073,8 +1072,7 @@ eval_code(co, globals, locals, owner, arg) | ||||||
| 				err_clear(); | 				err_clear(); | ||||||
| 				x = getbuiltin(w); | 				x = getbuiltin(w); | ||||||
| 				if (x == NULL) { | 				if (x == NULL) { | ||||||
| 					err_setstr(NameError, | 					err_setval(NameError, w); | ||||||
| 						getstringvalue(w)); |  | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -1092,7 +1090,7 @@ eval_code(co, globals, locals, owner, arg) | ||||||
| 			w = GETNAMEV(oparg); | 			w = GETNAMEV(oparg); | ||||||
| 			x = dict2lookup(f->f_locals, w); | 			x = dict2lookup(f->f_locals, w); | ||||||
| 			if (x == NULL) { | 			if (x == NULL) { | ||||||
| 				err_setstr(NameError, getstringvalue(w)); | 				err_setval(NameError, w); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if (is_accessobject(x)) { | 			if (is_accessobject(x)) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sjoerd Mullender
						Sjoerd Mullender