Bug 686582 - Make the JSON Walk function do its walking over array elements using getElement instead of getProperty, a first step toward actually using element-based methods now being specialized. r=dvander

--HG--
extra : rebase_source : 9816241003454d8b23c8903c97656993cb834ea1
This commit is contained in:
Jeff Walden 2011-08-10 14:54:52 -07:00
Родитель bb472a9954
Коммит 5640581cbe
1 изменённых файлов: 27 добавлений и 8 удалений

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

@ -281,12 +281,33 @@ class CycleDetector
JSObject *const obj;
};
template<typename KeyType>
class KeyStringifier {
};
template<>
class KeyStringifier<uint32> {
public:
static JSString *toString(JSContext *cx, uint32 index) {
return IndexToString(cx, index);
}
};
template<>
class KeyStringifier<jsid> {
public:
static JSString *toString(JSContext *cx, jsid id) {
return IdToString(cx, id);
}
};
/*
* ES5 15.12.3 Str, steps 2-4, extracted to enable preprocessing of property
* values when stringifying objects in JO.
*/
template<typename KeyType>
static bool
PreprocessValue(JSContext *cx, JSObject *holder, jsid key, Value *vp, StringifyContext *scx)
PreprocessValue(JSContext *cx, JSObject *holder, KeyType key, Value *vp, StringifyContext *scx)
{
JSString *keyStr = NULL;
@ -298,7 +319,7 @@ PreprocessValue(JSContext *cx, JSObject *holder, jsid key, Value *vp, StringifyC
return false;
if (js_IsCallable(toJSON)) {
keyStr = IdToString(cx, key);
keyStr = KeyStringifier<KeyType>::toString(cx, key);
if (!keyStr)
return false;
@ -319,7 +340,7 @@ PreprocessValue(JSContext *cx, JSObject *holder, jsid key, Value *vp, StringifyC
/* Step 3. */
if (scx->replacer && scx->replacer->isCallable()) {
if (!keyStr) {
keyStr = IdToString(cx, key);
keyStr = KeyStringifier<KeyType>::toString(cx, key);
if (!keyStr)
return false;
}
@ -495,18 +516,16 @@ JA(JSContext *cx, JSObject *obj, StringifyContext *scx)
/* Steps 7-10. */
Value outputValue;
for (jsuint i = 0; i < length; i++) {
jsid id = INT_TO_JSID(i);
for (uint32 i = 0; i < length; i++) {
/*
* Steps 8a-8c. Again note how the call to the spec's Str method
* is broken up into getting the property, running it past toJSON
* and the replacer and maybe unboxing, and interpreting some
* values as |null| in separate steps.
*/
if (!obj->getProperty(cx, id, &outputValue))
if (!obj->getElement(cx, i, &outputValue))
return JS_FALSE;
if (!PreprocessValue(cx, obj, id, &outputValue, scx))
if (!PreprocessValue(cx, obj, i, &outputValue, scx))
return JS_FALSE;
if (IsFilteredValue(outputValue)) {
if (!scx->sb.append("null"))