Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 } else { | 188 } else { |
| 189 return SerializeObject(value, replacer, stack, indent, gap); | 189 return SerializeObject(value, replacer, stack, indent, gap); |
| 190 } | 190 } |
| 191 case "number": | 191 case "number": |
| 192 return $isFinite(value) ? $String(value) : "null"; | 192 return $isFinite(value) ? $String(value) : "null"; |
| 193 case "boolean": | 193 case "boolean": |
| 194 return value ? "true" : "false"; | 194 return value ? "true" : "false"; |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 | 197 |
| 198 function BasicSerializeArray(value, stack) { | 198 |
| 199 function BasicSerializeArray(value, stack, builder) { | |
| 199 if (StackContains(stack, value)) { | 200 if (StackContains(stack, value)) { |
| 200 throw MakeTypeError('circular_structure', []); | 201 throw MakeTypeError('circular_structure', []); |
| 201 } | 202 } |
| 202 stack.push(value); | 203 stack.push(value); |
| 203 var partial = []; | 204 builder.push("["); |
| 204 var len = value.length; | 205 var len = value.length; |
| 205 for (var i = 0; i < len; i++) { | 206 for (var i = 0; i < len; i++) { |
| 206 var strP = BasicJSONSerialize($String(i), value, stack); | 207 var before = builder.length; |
| 207 if (IS_UNDEFINED(strP)) strP = "null"; | 208 BasicJSONSerialize($String(i), value, stack, builder); |
| 208 partial.push(strP); | 209 if (before == builder.length) builder.push("null"); |
| 210 builder.push(","); | |
|
Lasse Reichstein
2010/12/06 08:48:45
An idiom often used in "picket fence loops" like t
| |
| 209 } | 211 } |
| 210 stack.pop(); | 212 stack.pop(); |
| 211 return "[" + partial.join() + "]"; | 213 if (builder.pop() != ",") { |
|
Erik Corry
2010/12/05 15:09:06
This seems a bit indirect. I think it would be cl
sandholm
2010/12/06 11:42:31
I added a comment.
On 2010/12/05 15:09:06, Erik Co
| |
| 214 builder.push("[]"); | |
| 215 } else { | |
| 216 builder.push("]"); | |
| 217 } | |
| 212 } | 218 } |
| 213 | 219 |
| 214 function BasicSerializeObject(value, stack) { | 220 |
| 221 function BasicSerializeObject(value, stack, builder) { | |
| 215 if (StackContains(stack, value)) { | 222 if (StackContains(stack, value)) { |
| 216 throw MakeTypeError('circular_structure', []); | 223 throw MakeTypeError('circular_structure', []); |
| 217 } | 224 } |
| 218 stack.push(value); | 225 stack.push(value); |
| 219 var partial = []; | 226 builder.push("{"); |
| 220 for (var p in value) { | 227 for (var p in value) { |
| 221 if (ObjectHasOwnProperty.call(value, p)) { | 228 if (ObjectHasOwnProperty.call(value, p)) { |
| 222 var strP = BasicJSONSerialize(p, value, stack); | 229 builder.push(%QuoteJSONString(p), ":"); |
|
Erik Corry
2010/12/05 15:09:06
If you didn't already try it I think it would be i
sandholm
2010/12/06 11:42:31
I experimented a bit. Will submit another change.
| |
| 223 if (!IS_UNDEFINED(strP)) partial.push(%QuoteJSONString(p) + ":" + strP); | 230 var before = builder.length; |
| 231 BasicJSONSerialize(p, value, stack, builder); | |
| 232 if (before == builder.length) { | |
| 233 builder.pop(); | |
| 234 builder.pop(); | |
| 235 } else { | |
| 236 builder.push(","); | |
| 237 } | |
| 224 } | 238 } |
| 225 } | 239 } |
| 226 stack.pop(); | 240 stack.pop(); |
| 227 return "{" + partial.join() + "}"; | 241 if (builder.pop() != ",") { |
|
Erik Corry
2010/12/05 15:09:06
Again, I find this convoluted. A boolean variable
sandholm
2010/12/06 11:42:31
I added a comment
On 2010/12/05 15:09:06, Erik Cor
| |
| 242 builder.push("{}"); | |
| 243 } else { | |
| 244 builder.push("}"); | |
| 245 } | |
| 228 } | 246 } |
| 229 | 247 |
| 230 function BasicJSONSerialize(key, holder, stack) { | 248 |
| 249 function BasicJSONSerialize(key, holder, stack, builder) { | |
| 231 var value = holder[key]; | 250 var value = holder[key]; |
| 232 if (IS_OBJECT(value) && value) { | 251 if (IS_OBJECT(value) && value) { |
| 233 var toJSON = value.toJSON; | 252 var toJSON = value.toJSON; |
| 234 if (IS_FUNCTION(toJSON)) value = toJSON.call(value, key); | 253 if (IS_FUNCTION(toJSON)) value = toJSON.call(value, key); |
| 235 } | 254 } |
| 236 // Unwrap value if necessary | 255 if (IS_STRING(value)) { |
| 237 if (IS_OBJECT(value)) { | 256 builder.push(%QuoteJSONString(value)); |
| 257 } else if (IS_NUMBER(value)) { | |
| 258 builder.push(($isFinite(value) ? $String(value) : "null")); | |
|
Erik Corry
2010/12/05 15:09:06
I wonder how $String compares speedwise to ("" + v
Lasse Reichstein
2010/12/06 08:48:45
Use %_NumberToString instead of the generic $Strin
sandholm
2010/12/06 11:42:31
Done.
sandholm
2010/12/06 11:42:31
Done.
| |
| 259 } else if (IS_BOOLEAN(value)) { | |
| 260 builder.push((value ? "true" : "false")); | |
| 261 } else if (IS_OBJECT(value)) { | |
| 262 // Unwrap value if necessary | |
| 238 if (IS_NUMBER_WRAPPER(value)) { | 263 if (IS_NUMBER_WRAPPER(value)) { |
| 239 value = $Number(value); | 264 value = $Number(value); |
|
Lasse Reichstein
2010/12/06 08:48:45
use %_ValueOf to extract the number.
sandholm
2010/12/06 11:42:31
Done.
| |
| 265 builder.push(($isFinite(value) ? $String(value) : "null")); | |
|
Lasse Reichstein
2010/12/06 08:48:45
%_NumberToString here too.
sandholm
2010/12/06 11:42:31
Done.
| |
| 240 } else if (IS_STRING_WRAPPER(value)) { | 266 } else if (IS_STRING_WRAPPER(value)) { |
| 241 value = $String(value); | 267 builder.push(%QuoteJSONString($String(value))); |
| 242 } else if (IS_BOOLEAN_WRAPPER(value)) { | 268 } else if (IS_BOOLEAN_WRAPPER(value)) { |
| 243 value = %_ValueOf(value); | 269 builder.push((%_ValueOf(value) ? "true" : "false")); |
| 270 } else { // Regular non-wrapped object | |
|
Erik Corry
2010/12/05 15:09:06
There should be 2 spaces before //
Lasse Reichstein
2010/12/06 08:48:45
I would put the comment on the next line instead.
sandholm
2010/12/06 11:42:31
Done.
sandholm
2010/12/06 11:42:31
Done.
| |
| 271 if (!value) { | |
| 272 builder.push("null"); | |
| 273 } else if (IS_ARRAY(value)) { | |
| 274 BasicSerializeArray(value, stack, builder); | |
| 275 } else { | |
| 276 BasicSerializeObject(value, stack, builder); | |
| 277 } | |
| 244 } | 278 } |
| 245 } | 279 } |
| 246 switch (typeof value) { | |
| 247 case "string": | |
| 248 return %QuoteJSONString(value); | |
| 249 case "object": | |
| 250 if (!value) { | |
| 251 return "null"; | |
| 252 } else if (IS_ARRAY(value)) { | |
| 253 return BasicSerializeArray(value, stack); | |
| 254 } else { | |
| 255 return BasicSerializeObject(value, stack); | |
| 256 } | |
| 257 case "number": | |
| 258 return $isFinite(value) ? $String(value) : "null"; | |
| 259 case "boolean": | |
| 260 return value ? "true" : "false"; | |
| 261 } | |
| 262 } | 280 } |
| 263 | 281 |
| 264 function JSONStringify(value, replacer, space) { | 282 function JSONStringify(value, replacer, space) { |
| 265 if (IS_UNDEFINED(replacer) && IS_UNDEFINED(space)) { | 283 if (IS_UNDEFINED(replacer) && IS_UNDEFINED(space)) { |
| 266 return BasicJSONSerialize('', {'': value}, []); | 284 var builder = []; |
| 285 BasicJSONSerialize('', {'': value}, [], builder); | |
| 286 if (builder.length == 0) return; | |
| 287 else return %StringBuilderConcat(builder, builder.length, ""); | |
| 267 } | 288 } |
| 268 if (IS_OBJECT(space)) { | 289 if (IS_OBJECT(space)) { |
| 269 // Unwrap 'space' if it is wrapped | 290 // Unwrap 'space' if it is wrapped |
| 270 if (IS_NUMBER_WRAPPER(space)) { | 291 if (IS_NUMBER_WRAPPER(space)) { |
| 271 space = $Number(space); | 292 space = $Number(space); |
| 272 } else if (IS_STRING_WRAPPER(space)) { | 293 } else if (IS_STRING_WRAPPER(space)) { |
| 273 space = $String(space); | 294 space = $String(space); |
| 274 } | 295 } |
| 275 } | 296 } |
| 276 var gap; | 297 var gap; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 293 } | 314 } |
| 294 | 315 |
| 295 function SetupJSON() { | 316 function SetupJSON() { |
| 296 InstallFunctions($JSON, DONT_ENUM, $Array( | 317 InstallFunctions($JSON, DONT_ENUM, $Array( |
| 297 "parse", JSONParse, | 318 "parse", JSONParse, |
| 298 "stringify", JSONStringify | 319 "stringify", JSONStringify |
| 299 )); | 320 )); |
| 300 } | 321 } |
| 301 | 322 |
| 302 SetupJSON(); | 323 SetupJSON(); |
| OLD | NEW |