Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: src/js/json.js

Issue 1515133002: [proxies] Support proxies in JSON.parse and JSON.stringify. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/contexts.h ('k') | test/mjsunit/harmony/proxies-json.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 (function(global, utils) { 5 (function(global, utils) {
6 6
7 "use strict"; 7 "use strict";
8 8
9 %CheckIsBootstrapping(); 9 %CheckIsBootstrapping();
10 10
11 // ------------------------------------------------------------------- 11 // -------------------------------------------------------------------
12 // Imports 12 // Imports
13 13
14 var GlobalJSON = global.JSON; 14 var GlobalJSON = global.JSON;
15 var GlobalSet = global.Set;
15 var InternalArray = utils.InternalArray; 16 var InternalArray = utils.InternalArray;
16 var MakeTypeError; 17 var MakeTypeError;
17 var MaxSimple; 18 var MaxSimple;
18 var MinSimple; 19 var MinSimple;
19 var ObjectHasOwnProperty; 20 var ObjectHasOwnProperty;
20 var ObjectKeys; 21 var ObjectKeys;
21 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 22 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
22 23
23 utils.Import(function(from) { 24 utils.Import(function(from) {
24 MakeTypeError = from.MakeTypeError; 25 MakeTypeError = from.MakeTypeError;
25 MaxSimple = from.MaxSimple; 26 MaxSimple = from.MaxSimple;
26 MinSimple = from.MinSimple; 27 MinSimple = from.MinSimple;
27 ObjectHasOwnProperty = from.ObjectHasOwnProperty; 28 ObjectHasOwnProperty = from.ObjectHasOwnProperty;
28 ObjectKeys = from.ObjectKeys; 29 ObjectKeys = from.ObjectKeys;
29 }); 30 });
30 31
31 // ------------------------------------------------------------------- 32 // -------------------------------------------------------------------
32 33
34 function CreateDataProperty(o, p, v) {
35 var desc = {value: v, enumerable: true, writable: true, configurable: true};
36 return %reflect_define_property(o, p, desc);
37 }
38
39
33 function InternalizeJSONProperty(holder, name, reviver) { 40 function InternalizeJSONProperty(holder, name, reviver) {
34 var val = holder[name]; 41 var val = holder[name];
35 if (IS_OBJECT(val) && val !== null) { 42 if (IS_SPEC_OBJECT(val)) {
36 if (IS_ARRAY(val)) { 43 if (%is_arraylike(val)) {
37 var length = val.length; 44 var length = TO_LENGTH(val.length);
38 for (var i = 0; i < length; i++) { 45 for (var i = 0; i < length; i++) {
39 var newElement = 46 var newElement =
40 InternalizeJSONProperty(val, %_NumberToString(i), reviver); 47 InternalizeJSONProperty(val, %_NumberToString(i), reviver);
41 if (IS_UNDEFINED(newElement)) { 48 if (IS_UNDEFINED(newElement)) {
42 delete val[i]; 49 %reflect_delete_property(val, i);
43 } else { 50 } else {
44 val[i] = newElement; 51 CreateDataProperty(val, i, newElement);
45 } 52 }
46 } 53 }
47 } else { 54 } else {
48 for (var p of ObjectKeys(val)) { 55 for (var p of ObjectKeys(val)) {
49 var newElement = InternalizeJSONProperty(val, p, reviver); 56 var newElement = InternalizeJSONProperty(val, p, reviver);
50 if (IS_UNDEFINED(newElement)) { 57 if (IS_UNDEFINED(newElement)) {
51 delete val[p]; 58 %reflect_delete_property(val, p);
52 } else { 59 } else {
53 val[p] = newElement; 60 CreateDataProperty(val, p, newElement);
54 } 61 }
55 } 62 }
56 } 63 }
57 } 64 }
58 return %_Call(reviver, holder, name, val); 65 return %_Call(reviver, holder, name, val);
59 } 66 }
60 67
61 68
62 function JSONParse(text, reviver) { 69 function JSONParse(text, reviver) {
63 var unfiltered = %ParseJson(text); 70 var unfiltered = %ParseJson(text);
64 if (IS_CALLABLE(reviver)) { 71 if (IS_CALLABLE(reviver)) {
65 return InternalizeJSONProperty({'': unfiltered}, '', reviver); 72 return InternalizeJSONProperty({'': unfiltered}, '', reviver);
66 } else { 73 } else {
67 return unfiltered; 74 return unfiltered;
68 } 75 }
69 } 76 }
70 77
71 78
72 function SerializeArray(value, replacer, stack, indent, gap) { 79 function SerializeArray(value, replacer, stack, indent, gap) {
73 if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure); 80 if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure);
74 var stepback = indent; 81 var stepback = indent;
75 indent += gap; 82 indent += gap;
76 var partial = new InternalArray(); 83 var partial = new InternalArray();
77 var len = value.length; 84 var len = TO_LENGTH(value.length);
78 for (var i = 0; i < len; i++) { 85 for (var i = 0; i < len; i++) {
79 var strP = JSONSerialize(%_NumberToString(i), value, replacer, stack, 86 var strP = JSONSerialize(%_NumberToString(i), value, replacer, stack,
80 indent, gap); 87 indent, gap);
81 if (IS_UNDEFINED(strP)) { 88 if (IS_UNDEFINED(strP)) {
82 strP = "null"; 89 strP = "null";
83 } 90 }
84 partial.push(strP); 91 partial.push(strP);
85 } 92 }
86 var final; 93 var final;
87 if (gap == "") { 94 if (gap == "") {
(...skipping 11 matching lines...) Expand all
99 106
100 107
101 function SerializeObject(value, replacer, stack, indent, gap) { 108 function SerializeObject(value, replacer, stack, indent, gap) {
102 if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure); 109 if (!%PushIfAbsent(stack, value)) throw MakeTypeError(kCircularStructure);
103 var stepback = indent; 110 var stepback = indent;
104 indent += gap; 111 indent += gap;
105 var partial = new InternalArray(); 112 var partial = new InternalArray();
106 if (IS_ARRAY(replacer)) { 113 if (IS_ARRAY(replacer)) {
107 var length = replacer.length; 114 var length = replacer.length;
108 for (var i = 0; i < length; i++) { 115 for (var i = 0; i < length; i++) {
109 if (HAS_OWN_PROPERTY(replacer, i)) { 116 var p = replacer[i];
110 var p = replacer[i]; 117 var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
111 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); 118 if (!IS_UNDEFINED(strP)) {
112 if (!IS_UNDEFINED(strP)) { 119 var member = %QuoteJSONString(p) + ":";
113 var member = %QuoteJSONString(p) + ":"; 120 if (gap != "") member += " ";
114 if (gap != "") member += " "; 121 member += strP;
115 member += strP; 122 partial.push(member);
116 partial.push(member);
117 }
118 } 123 }
119 } 124 }
120 } else { 125 } else {
121 for (var p in value) { 126 for (var p of ObjectKeys(value)) {
122 if (HAS_OWN_PROPERTY(value, p)) { 127 var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
123 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); 128 if (!IS_UNDEFINED(strP)) {
124 if (!IS_UNDEFINED(strP)) { 129 var member = %QuoteJSONString(p) + ":";
125 var member = %QuoteJSONString(p) + ":"; 130 if (gap != "") member += " ";
126 if (gap != "") member += " "; 131 member += strP;
127 member += strP; 132 partial.push(member);
128 partial.push(member);
129 }
130 } 133 }
131 } 134 }
132 } 135 }
133 var final; 136 var final;
134 if (gap == "") { 137 if (gap == "") {
135 final = "{" + partial.join(",") + "}"; 138 final = "{" + partial.join(",") + "}";
136 } else if (partial.length > 0) { 139 } else if (partial.length > 0) {
137 var separator = ",\n" + indent; 140 var separator = ",\n" + indent;
138 final = "{\n" + indent + partial.join(separator) + "\n" + 141 final = "{\n" + indent + partial.join(separator) + "\n" +
139 stepback + "}"; 142 stepback + "}";
(...skipping 19 matching lines...) Expand all
159 if (IS_STRING(value)) { 162 if (IS_STRING(value)) {
160 return %QuoteJSONString(value); 163 return %QuoteJSONString(value);
161 } else if (IS_NUMBER(value)) { 164 } else if (IS_NUMBER(value)) {
162 return JSON_NUMBER_TO_STRING(value); 165 return JSON_NUMBER_TO_STRING(value);
163 } else if (IS_BOOLEAN(value)) { 166 } else if (IS_BOOLEAN(value)) {
164 return value ? "true" : "false"; 167 return value ? "true" : "false";
165 } else if (IS_NULL(value)) { 168 } else if (IS_NULL(value)) {
166 return "null"; 169 return "null";
167 } else if (IS_SPEC_OBJECT(value) && !IS_CALLABLE(value)) { 170 } else if (IS_SPEC_OBJECT(value) && !IS_CALLABLE(value)) {
168 // Non-callable object. If it's a primitive wrapper, it must be unwrapped. 171 // Non-callable object. If it's a primitive wrapper, it must be unwrapped.
169 if (IS_ARRAY(value)) { 172 if (%is_arraylike(value)) {
170 return SerializeArray(value, replacer, stack, indent, gap); 173 return SerializeArray(value, replacer, stack, indent, gap);
171 } else if (IS_NUMBER_WRAPPER(value)) { 174 } else if (IS_NUMBER_WRAPPER(value)) {
172 value = TO_NUMBER(value); 175 value = TO_NUMBER(value);
173 return JSON_NUMBER_TO_STRING(value); 176 return JSON_NUMBER_TO_STRING(value);
174 } else if (IS_STRING_WRAPPER(value)) { 177 } else if (IS_STRING_WRAPPER(value)) {
175 return %QuoteJSONString(TO_STRING(value)); 178 return %QuoteJSONString(TO_STRING(value));
176 } else if (IS_BOOLEAN_WRAPPER(value)) { 179 } else if (IS_BOOLEAN_WRAPPER(value)) {
177 return %_ValueOf(value) ? "true" : "false"; 180 return %_ValueOf(value) ? "true" : "false";
178 } else { 181 } else {
179 return SerializeObject(value, replacer, stack, indent, gap); 182 return SerializeObject(value, replacer, stack, indent, gap);
180 } 183 }
181 } 184 }
182 // Undefined or a callable object. 185 // Undefined or a callable object.
183 return UNDEFINED; 186 return UNDEFINED;
184 } 187 }
185 188
186 189
187 function JSONStringify(value, replacer, space) { 190 function JSONStringify(value, replacer, space) {
188 if (%_ArgumentsLength() == 1) { 191 if (%_ArgumentsLength() == 1 && !%_IsJSProxy(value)) {
189 return %BasicJSONStringify(value); 192 return %BasicJSONStringify(value);
190 } 193 }
191 if (IS_ARRAY(replacer)) { 194 if (!IS_CALLABLE(replacer) && %is_arraylike(replacer)) {
192 // Deduplicate replacer array items.
193 var property_list = new InternalArray(); 195 var property_list = new InternalArray();
194 var seen_properties = { __proto__: null }; 196 var seen_properties = new GlobalSet();
195 var length = replacer.length; 197 var length = TO_LENGTH(replacer.length);
196 for (var i = 0; i < length; i++) { 198 for (var i = 0; i < length; i++) {
197 var v = replacer[i]; 199 var v = replacer[i];
198 var item; 200 var item;
199 if (IS_STRING(v)) { 201 if (IS_STRING(v)) {
200 item = v; 202 item = v;
201 } else if (IS_NUMBER(v)) { 203 } else if (IS_NUMBER(v)) {
202 item = %_NumberToString(v); 204 item = %_NumberToString(v);
203 } else if (IS_STRING_WRAPPER(v) || IS_NUMBER_WRAPPER(v)) { 205 } else if (IS_STRING_WRAPPER(v) || IS_NUMBER_WRAPPER(v)) {
204 item = TO_STRING(v); 206 item = TO_STRING(v);
205 } else { 207 } else {
206 continue; 208 continue;
207 } 209 }
208 if (!seen_properties[item]) { 210 if (!seen_properties.has(item)) {
209 property_list.push(item); 211 property_list.push(item);
210 seen_properties[item] = true; 212 seen_properties.add(item);
211 } 213 }
212 } 214 }
213 replacer = property_list; 215 replacer = property_list;
214 } 216 }
215 if (IS_OBJECT(space)) { 217 if (IS_OBJECT(space)) {
216 // Unwrap 'space' if it is wrapped 218 // Unwrap 'space' if it is wrapped
217 if (IS_NUMBER_WRAPPER(space)) { 219 if (IS_NUMBER_WRAPPER(space)) {
218 space = TO_NUMBER(space); 220 space = TO_NUMBER(space);
219 } else if (IS_STRING_WRAPPER(space)) { 221 } else if (IS_STRING_WRAPPER(space)) {
220 space = TO_STRING(space); 222 space = TO_STRING(space);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 function JsonSerializeAdapter(key, object) { 254 function JsonSerializeAdapter(key, object) {
253 var holder = {}; 255 var holder = {};
254 holder[key] = object; 256 holder[key] = object;
255 // No need to pass the actual holder since there is no replacer function. 257 // No need to pass the actual holder since there is no replacer function.
256 return JSONSerialize(key, holder, UNDEFINED, new InternalArray(), "", ""); 258 return JSONSerialize(key, holder, UNDEFINED, new InternalArray(), "", "");
257 } 259 }
258 260
259 %InstallToContext(["json_serialize_adapter", JsonSerializeAdapter]); 261 %InstallToContext(["json_serialize_adapter", JsonSerializeAdapter]);
260 262
261 }) 263 })
OLDNEW
« no previous file with comments | « src/contexts.h ('k') | test/mjsunit/harmony/proxies-json.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698