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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 if (IS_FUNCTION(toJSON)) { | 146 if (IS_FUNCTION(toJSON)) { |
147 value = %_CallFunction(value, key, toJSON); | 147 value = %_CallFunction(value, key, toJSON); |
148 } | 148 } |
149 } | 149 } |
150 if (IS_FUNCTION(replacer)) { | 150 if (IS_FUNCTION(replacer)) { |
151 value = %_CallFunction(holder, key, value, replacer); | 151 value = %_CallFunction(holder, key, value, replacer); |
152 } | 152 } |
153 if (IS_STRING(value)) { | 153 if (IS_STRING(value)) { |
154 return %QuoteJSONString(value); | 154 return %QuoteJSONString(value); |
155 } else if (IS_NUMBER(value)) { | 155 } else if (IS_NUMBER(value)) { |
156 return NUMBER_IS_FINITE(value) ? $String(value) : "null"; | 156 return JSON_NUMBER_TO_STRING(value); |
157 } else if (IS_BOOLEAN(value)) { | 157 } else if (IS_BOOLEAN(value)) { |
158 return value ? "true" : "false"; | 158 return value ? "true" : "false"; |
159 } else if (IS_NULL(value)) { | 159 } else if (IS_NULL(value)) { |
160 return "null"; | 160 return "null"; |
161 } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) { | 161 } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) { |
162 // Non-callable object. If it's a primitive wrapper, it must be unwrapped. | 162 // Non-callable object. If it's a primitive wrapper, it must be unwrapped. |
163 if (IS_ARRAY(value)) { | 163 if (IS_ARRAY(value)) { |
164 return SerializeArray(value, replacer, stack, indent, gap); | 164 return SerializeArray(value, replacer, stack, indent, gap); |
165 } else if (IS_NUMBER_WRAPPER(value)) { | 165 } else if (IS_NUMBER_WRAPPER(value)) { |
166 value = ToNumber(value); | 166 value = ToNumber(value); |
167 return NUMBER_IS_FINITE(value) ? ToString(value) : "null"; | 167 return JSON_NUMBER_TO_STRING(value); |
168 } else if (IS_STRING_WRAPPER(value)) { | 168 } else if (IS_STRING_WRAPPER(value)) { |
169 return %QuoteJSONString(ToString(value)); | 169 return %QuoteJSONString(ToString(value)); |
170 } else if (IS_BOOLEAN_WRAPPER(value)) { | 170 } else if (IS_BOOLEAN_WRAPPER(value)) { |
171 return %_ValueOf(value) ? "true" : "false"; | 171 return %_ValueOf(value) ? "true" : "false"; |
172 } else { | 172 } else { |
173 return SerializeObject(value, replacer, stack, indent, gap); | 173 return SerializeObject(value, replacer, stack, indent, gap); |
174 } | 174 } |
175 } | 175 } |
176 // Undefined or a callable object. | 176 // Undefined or a callable object. |
177 return void 0; | 177 return void 0; |
(...skipping 18 matching lines...) Expand all Loading... |
196 builder[builder.length - 1] = array_string; | 196 builder[builder.length - 1] = array_string; |
197 } else { | 197 } else { |
198 builder.push(%QuoteJSONString(val)); | 198 builder.push(%QuoteJSONString(val)); |
199 for (var i = 1; i < len; i++) { | 199 for (var i = 1; i < len; i++) { |
200 val = value[i]; | 200 val = value[i]; |
201 if (IS_STRING(val)) { | 201 if (IS_STRING(val)) { |
202 builder.push(%QuoteJSONStringComma(val)); | 202 builder.push(%QuoteJSONStringComma(val)); |
203 } else { | 203 } else { |
204 builder.push(","); | 204 builder.push(","); |
205 var before = builder.length; | 205 var before = builder.length; |
206 BasicJSONSerialize(i, value[i], stack, builder); | 206 BasicJSONSerialize(i, val, stack, builder); |
207 if (before == builder.length) builder[before - 1] = ",null"; | 207 if (before == builder.length) builder[before - 1] = ",null"; |
208 } | 208 } |
209 } | 209 } |
210 } | 210 } |
211 } else if (IS_NUMBER(val)) { | 211 } else if (IS_NUMBER(val)) { |
212 // First entry is a number. Remaining entries are likely to be numbers too. | 212 // First entry is a number. Remaining entries are likely to be numbers too. |
213 builder.push(NUMBER_IS_FINITE(val) ? %_NumberToString(val) : "null"); | 213 builder.push(JSON_NUMBER_TO_STRING(val)); |
214 for (var i = 1; i < len; i++) { | 214 for (var i = 1; i < len; i++) { |
215 builder.push(","); | 215 builder.push(","); |
216 val = value[i]; | 216 val = value[i]; |
217 if (IS_NUMBER(val)) { | 217 if (IS_NUMBER(val)) { |
218 builder.push(NUMBER_IS_FINITE(val) | 218 builder.push(JSON_NUMBER_TO_STRING(val)); |
219 ? %_NumberToString(val) | |
220 : "null"); | |
221 } else { | 219 } else { |
222 var before = builder.length; | 220 var before = builder.length; |
223 BasicJSONSerialize(i, value[i], stack, builder); | 221 BasicJSONSerialize(i, val, stack, builder); |
224 if (before == builder.length) builder[before - 1] = ",null"; | 222 if (before == builder.length) builder[before - 1] = ",null"; |
225 } | 223 } |
226 } | 224 } |
227 } else { | 225 } else { |
228 var before = builder.length; | 226 var before = builder.length; |
229 BasicJSONSerialize(0, val, stack, builder); | 227 BasicJSONSerialize(0, val, stack, builder); |
230 if (before == builder.length) builder.push("null"); | 228 if (before == builder.length) builder.push("null"); |
231 for (var i = 1; i < len; i++) { | 229 for (var i = 1; i < len; i++) { |
232 builder.push(","); | 230 builder.push(","); |
233 before = builder.length; | 231 before = builder.length; |
234 val = value[i]; | 232 BasicJSONSerialize(i, value[i], stack, builder); |
235 BasicJSONSerialize(i, val, stack, builder); | |
236 if (before == builder.length) builder[before - 1] = ",null"; | 233 if (before == builder.length) builder[before - 1] = ",null"; |
237 } | 234 } |
238 } | 235 } |
239 stack.pop(); | 236 stack.pop(); |
240 builder.push("]"); | 237 builder.push("]"); |
241 } | 238 } |
242 | 239 |
243 | 240 |
244 function BasicSerializeObject(value, stack, builder) { | 241 function BasicSerializeObject(value, stack, builder) { |
245 if (!%PushIfAbsent(stack, value)) { | 242 if (!%PushIfAbsent(stack, value)) { |
(...skipping 27 matching lines...) Expand all Loading... |
273 function BasicJSONSerialize(key, value, stack, builder) { | 270 function BasicJSONSerialize(key, value, stack, builder) { |
274 if (IS_SPEC_OBJECT(value)) { | 271 if (IS_SPEC_OBJECT(value)) { |
275 var toJSON = value.toJSON; | 272 var toJSON = value.toJSON; |
276 if (IS_FUNCTION(toJSON)) { | 273 if (IS_FUNCTION(toJSON)) { |
277 value = %_CallFunction(value, ToString(key), toJSON); | 274 value = %_CallFunction(value, ToString(key), toJSON); |
278 } | 275 } |
279 } | 276 } |
280 if (IS_STRING(value)) { | 277 if (IS_STRING(value)) { |
281 builder.push(%QuoteJSONString(value)); | 278 builder.push(%QuoteJSONString(value)); |
282 } else if (IS_NUMBER(value)) { | 279 } else if (IS_NUMBER(value)) { |
283 builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null"); | 280 builder.push(JSON_NUMBER_TO_STRING(value)); |
284 } else if (IS_BOOLEAN(value)) { | 281 } else if (IS_BOOLEAN(value)) { |
285 builder.push(value ? "true" : "false"); | 282 builder.push(value ? "true" : "false"); |
286 } else if (IS_NULL(value)) { | 283 } else if (IS_NULL(value)) { |
287 builder.push("null"); | 284 builder.push("null"); |
288 } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) { | 285 } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) { |
289 // Value is a non-callable object. | 286 // Value is a non-callable object. |
290 // Unwrap value if necessary | 287 // Unwrap value if necessary |
291 if (IS_NUMBER_WRAPPER(value)) { | 288 if (IS_NUMBER_WRAPPER(value)) { |
292 value = ToNumber(value); | 289 value = ToNumber(value); |
293 builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null"); | 290 builder.push(JSON_NUMBER_TO_STRING(value)); |
294 } else if (IS_STRING_WRAPPER(value)) { | 291 } else if (IS_STRING_WRAPPER(value)) { |
295 builder.push(%QuoteJSONString(ToString(value))); | 292 builder.push(%QuoteJSONString(ToString(value))); |
296 } else if (IS_BOOLEAN_WRAPPER(value)) { | 293 } else if (IS_BOOLEAN_WRAPPER(value)) { |
297 builder.push(%_ValueOf(value) ? "true" : "false"); | 294 builder.push(%_ValueOf(value) ? "true" : "false"); |
298 } else if (IS_ARRAY(value)) { | 295 } else if (IS_ARRAY(value)) { |
299 BasicSerializeArray(value, stack, builder); | 296 BasicSerializeArray(value, stack, builder); |
300 } else { | 297 } else { |
301 BasicSerializeObject(value, stack, builder); | 298 BasicSerializeObject(value, stack, builder); |
302 } | 299 } |
303 } | 300 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 } | 335 } |
339 | 336 |
340 function SetupJSON() { | 337 function SetupJSON() { |
341 InstallFunctions($JSON, DONT_ENUM, $Array( | 338 InstallFunctions($JSON, DONT_ENUM, $Array( |
342 "parse", JSONParse, | 339 "parse", JSONParse, |
343 "stringify", JSONStringify | 340 "stringify", JSONStringify |
344 )); | 341 )); |
345 } | 342 } |
346 | 343 |
347 SetupJSON(); | 344 SetupJSON(); |
OLD | NEW |