Bug 483103 - TM: "Assertion failed: p->isQuad()" with str["-1"]; make str[-1] a non-special property rather than one that returns the length of str. r=brendan

This commit is contained in:
Jeff Walden 2009-03-17 15:27:31 -07:00
parent fd84f47200
commit 0d638ca87a
2 changed files with 44 additions and 18 deletions

View File

@ -547,28 +547,13 @@ static JSFunctionSpec string_functions[] = {
jschar js_empty_ucstr[] = {0}; jschar js_empty_ucstr[] = {0};
JSSubString js_EmptySubString = {0, js_empty_ucstr}; JSSubString js_EmptySubString = {0, js_empty_ucstr};
enum string_tinyid {
STRING_LENGTH = -1
};
static JSPropertySpec string_props[] = {
{js_length_str, STRING_LENGTH,
JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0},
{0,0,0,0,0}
};
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; jsval v;
JSString *str; JSString *str;
jsint slot;
if (!JSVAL_IS_INT(id)) if (id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
return JS_TRUE;
slot = JSVAL_TO_INT(id);
if (slot == STRING_LENGTH) {
if (OBJ_GET_CLASS(cx, obj) == &js_StringClass) { if (OBJ_GET_CLASS(cx, obj) == &js_StringClass) {
/* Follow ECMA-262 by fetching intrinsic length of our string. */ /* Follow ECMA-262 by fetching intrinsic length of our string. */
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
@ -583,6 +568,7 @@ str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
*vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str)); *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));
} }
return JS_TRUE; return JS_TRUE;
} }
@ -621,7 +607,21 @@ str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSString *str, *str1; JSString *str, *str1;
jsint slot; jsint slot;
if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING)) if (flags & JSRESOLVE_ASSIGNING)
return JS_TRUE;
if (id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
str = JSVAL_TO_STRING(v);
if (!OBJ_DEFINE_PROPERTY(cx, obj, id, INT_TO_JSVAL(17), NULL, NULL,
JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, NULL)) {
return JS_FALSE;
}
*objp = obj;
return JS_TRUE;
}
if (!JSVAL_IS_INT(id))
return JS_TRUE; return JS_TRUE;
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
@ -2855,7 +2855,7 @@ js_InitStringClass(JSContext *cx, JSObject *obj)
return NULL; return NULL;
proto = JS_InitClass(cx, obj, NULL, &js_StringClass, js_String, 1, proto = JS_InitClass(cx, obj, NULL, &js_StringClass, js_String, 1,
string_props, string_methods, NULL, string_methods,
NULL, string_static_methods); NULL, string_static_methods);
if (!proto) if (!proto)
return NULL; return NULL;

View File

@ -4538,6 +4538,32 @@ testAddNull.jitstats = {
}; };
test(testAddNull); test(testAddNull);
function testStringLengthNoTinyId()
{
var x = "unset";
var t = new String("");
for (var i = 0; i < 5; i++)
x = t["-1"];
var r = "t['-1'] is " + x;
t["-1"] = "foo";
r += " when unset, '" + t["-1"] + "' when set";
return r;
}
testStringLengthNoTinyId.expected = "t['-1'] is undefined when unset, 'foo' when set";
test(testStringLengthNoTinyId);
function testLengthInString()
{
var s = new String();
var res = "length" in s;
for (var i = 0; i < 5; i++)
res = res && ("length" in s);
return res;
}
testLengthInString.expected = true;
test(testLengthInString);
/***************************************************************************** /*****************************************************************************
* * * *