Fix string.length to be specific for String objects, generic for others for backward compat; and simplify resolve/enumerate accordingly (313567, r/sr=igor/shaver).

This commit is contained in:
brendan%mozilla.org 2005-10-25 15:58:33 +00:00
Родитель 0407076411
Коммит 170ed8da7e
1 изменённых файлов: 23 добавлений и 18 удалений

Просмотреть файл

@ -522,24 +522,29 @@ static JSPropertySpec string_props[] = {
static JSBool static JSBool
str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{ {
jsval v;
JSString *str; JSString *str;
jsint slot; jsint slot;
if (!JSVAL_IS_INT(id)) if (!JSVAL_IS_INT(id))
return JS_TRUE; return JS_TRUE;
/*
* Call js_ValueToString because getters and setters can be invoked on
* objects of different class, unlike enumerate, resolve, and the other
* class hooks.
*/
str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
if (!str)
return JS_FALSE;
slot = JSVAL_TO_INT(id); slot = JSVAL_TO_INT(id);
if (slot == STRING_LENGTH) if (slot == STRING_LENGTH) {
if (OBJ_GET_CLASS(cx, obj) == &js_StringClass) {
/* Follow ECMA-262 by fetching intrinsic length of our string. */
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
JS_ASSERT(JSVAL_IS_STRING(v));
str = JSVAL_TO_STRING(v);
} else {
/* Preserve compatibility: convert obj to a string primitive. */
str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
if (!str)
return JS_FALSE;
}
*vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str)); *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));
}
return JS_TRUE; return JS_TRUE;
} }
@ -548,6 +553,7 @@ str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
static JSBool static JSBool
str_enumerate(JSContext *cx, JSObject *obj) str_enumerate(JSContext *cx, JSObject *obj)
{ {
jsval v;
JSString *str, *str1; JSString *str, *str1;
size_t i, length; size_t i, length;
@ -555,10 +561,9 @@ str_enumerate(JSContext *cx, JSObject *obj)
if (JS_VERSION_IS_1_2(cx)) if (JS_VERSION_IS_1_2(cx))
return JS_TRUE; return JS_TRUE;
str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!str) JS_ASSERT(JSVAL_IS_STRING(v));
return JS_TRUE; str = JSVAL_TO_STRING(v);
cx->newborn[GCX_STRING] = (JSGCThing *) str;
length = JSSTRING_LENGTH(str); length = JSSTRING_LENGTH(str);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
@ -578,16 +583,16 @@ static JSBool
str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp) JSObject **objp)
{ {
jsval v;
JSString *str, *str1; JSString *str, *str1;
jsint slot; jsint slot;
if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING)) if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING))
return JS_TRUE; return JS_TRUE;
str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
if (!str) JS_ASSERT(JSVAL_IS_STRING(v));
return JS_TRUE; str = JSVAL_TO_STRING(v);
cx->newborn[GCX_STRING] = (JSGCThing *) str;
slot = JSVAL_TO_INT(id); slot = JSVAL_TO_INT(id);
if ((size_t)slot < JSSTRING_LENGTH(str)) { if ((size_t)slot < JSSTRING_LENGTH(str)) {