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

Side by Side Diff: test/mjsunit/strong/literals.js

Issue 1158933002: [strong] fix strong array, object prototypes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months 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/objects.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 // Flags: --strong-mode --allow-natives-syntax 5 // Flags: --strong-mode --allow-natives-syntax
6 // Flags: --harmony-arrow-functions --harmony-rest-parameters 6 // Flags: --harmony-arrow-functions --harmony-rest-parameters
7 // Flags: --harmony-destructuring 7 // Flags: --harmony-destructuring
8 8
9 'use strict'; 9 'use strict';
10 10
11 let GeneratorFunctionPrototype = (function*(){}).__proto__;
12
13 function assertStrongObject(o) {
14 assertTrue(%IsStrong(o));
15 assertSame(Object.prototype, o.__proto__);
16 }
17
18 function assertStrongArray(a) {
19 assertTrue(%IsStrong(a));
20 assertSame(Array.prototype, a.__proto__);
21 }
22
23 function assertStrongFunction(f) {
24 assertTrue(%IsStrong(f));
25 assertSame(Function.prototype, f.__proto__);
26 }
27
28 function assertStrongGenerator(g) {
29 assertTrue(%IsStrong(g));
30 assertSame(GeneratorFunctionPrototype, g.__proto__);
31 }
32
11 (function WeakObjectLiterals() { 33 (function WeakObjectLiterals() {
12 assertTrue(!%IsStrong({})); 34 assertTrue(!%IsStrong({}));
13 assertTrue(!%IsStrong({a: 0, b: 0})); 35 assertTrue(!%IsStrong({a: 0, b: 0}));
14 assertTrue(!%IsStrong({a: [], b: {}})); 36 assertTrue(!%IsStrong({a: [], b: {}}));
15 assertTrue(!%IsStrong({a: [], b: {}}.a)); 37 assertTrue(!%IsStrong({a: [], b: {}}.a));
16 assertTrue(!%IsStrong({a: [], b: {}}.b)); 38 assertTrue(!%IsStrong({a: [], b: {}}.b));
17 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a)); 39 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a));
18 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b)); 40 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b));
19 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b.c)); 41 assertTrue(!%IsStrong({a: {b: {c: {}}}}.a.b.c));
20 assertTrue(!%IsStrong({f: function(){}})); 42 assertTrue(!%IsStrong({f: function(){}}));
21 assertTrue(!%IsStrong(Realm.eval(Realm.current(), 43 assertTrue(!%IsStrong(Realm.eval(Realm.current(),
22 "({f: function(){}})"))); 44 "({f: function(){}})")));
23 })(); 45 })();
24 46
25 (function StrongObjectLiterals() { 47 (function StrongObjectLiterals() {
26 'use strong'; 48 'use strong';
27 assertTrue(%IsStrong({})); 49 assertStrongObject({});
28 assertTrue(%IsStrong({a: 0, b: 0})); 50 assertStrongObject({a: 0, b: 0});
29 assertTrue(%IsStrong({a: [], b: {}})); 51 assertStrongObject({a: [], b: {}});
30 assertTrue(%IsStrong({a: [], b: {}}.a)); 52 assertStrongArray({a: [], b: {}}.a);
31 assertTrue(%IsStrong({a: [], b: {}}.b)); 53 assertStrongObject({a: [], b: {}}.b);
32 assertTrue(%IsStrong({a: {b: {c: {}}}}.a)); 54 assertStrongObject({a: {b: {c: {}}}}.a);
33 assertTrue(%IsStrong({a: {b: {c: {}}}}.a.b)); 55 assertStrongObject({a: {b: {c: {}}}}.a.b);
34 assertTrue(%IsStrong({a: {b: {c: {}}}}.a.b.c)); 56 assertStrongObject({a: {b: {c: {}}}}.a.b.c);
35 // Maps for literals with too many properties are not cached. 57 // Maps for literals with too many properties are not cached.
36 assertTrue(%IsStrong({ 58 assertStrongObject({
37 x001: 0, x002: 0, x003: 0, x004: 0, x005: 0, 59 x001: 0, x002: 0, x003: 0, x004: 0, x005: 0,
38 x006: 0, x007: 0, x008: 0, x009: 0, x010: 0, 60 x006: 0, x007: 0, x008: 0, x009: 0, x010: 0,
39 x011: 0, x012: 0, x013: 0, x014: 0, x015: 0, 61 x011: 0, x012: 0, x013: 0, x014: 0, x015: 0,
40 x016: 0, x017: 0, x018: 0, x019: 0, x020: 0, 62 x016: 0, x017: 0, x018: 0, x019: 0, x020: 0,
41 x021: 0, x022: 0, x023: 0, x024: 0, x025: 0, 63 x021: 0, x022: 0, x023: 0, x024: 0, x025: 0,
42 x026: 0, x027: 0, x028: 0, x029: 0, x030: 0, 64 x026: 0, x027: 0, x028: 0, x029: 0, x030: 0,
43 x031: 0, x032: 0, x033: 0, x034: 0, x035: 0, 65 x031: 0, x032: 0, x033: 0, x034: 0, x035: 0,
44 x036: 0, x037: 0, x038: 0, x039: 0, x040: 0, 66 x036: 0, x037: 0, x038: 0, x039: 0, x040: 0,
45 x041: 0, x042: 0, x043: 0, x044: 0, x045: 0, 67 x041: 0, x042: 0, x043: 0, x044: 0, x045: 0,
46 x046: 0, x047: 0, x048: 0, x049: 0, x050: 0, 68 x046: 0, x047: 0, x048: 0, x049: 0, x050: 0,
(...skipping 20 matching lines...) Expand all
67 x151: 0, x152: 0, x153: 0, x154: 0, x155: 0, 89 x151: 0, x152: 0, x153: 0, x154: 0, x155: 0,
68 x156: 0, x157: 0, x158: 0, x159: 0, x160: 0, 90 x156: 0, x157: 0, x158: 0, x159: 0, x160: 0,
69 x161: 0, x162: 0, x163: 0, x164: 0, x165: 0, 91 x161: 0, x162: 0, x163: 0, x164: 0, x165: 0,
70 x166: 0, x167: 0, x168: 0, x169: 0, x170: 0, 92 x166: 0, x167: 0, x168: 0, x169: 0, x170: 0,
71 x171: 0, x172: 0, x173: 0, x174: 0, x175: 0, 93 x171: 0, x172: 0, x173: 0, x174: 0, x175: 0,
72 x176: 0, x177: 0, x178: 0, x179: 0, x180: 0, 94 x176: 0, x177: 0, x178: 0, x179: 0, x180: 0,
73 x181: 0, x182: 0, x183: 0, x184: 0, x185: 0, 95 x181: 0, x182: 0, x183: 0, x184: 0, x185: 0,
74 x186: 0, x187: 0, x188: 0, x189: 0, x190: 0, 96 x186: 0, x187: 0, x188: 0, x189: 0, x190: 0,
75 x191: 0, x192: 0, x193: 0, x194: 0, x195: 0, 97 x191: 0, x192: 0, x193: 0, x194: 0, x195: 0,
76 x196: 0, x197: 0, x198: 0, x199: 0, x200: 0, 98 x196: 0, x197: 0, x198: 0, x199: 0, x200: 0,
77 })); 99 });
78 assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}})); 100 assertStrongObject({[Date() + ""]: 0, [Symbol()]: 0});
79 assertTrue(%IsStrong({[Date() + ""]: 0, [Symbol()]: 0})); 101 assertStrongObject({m() { super.m() }});
80 assertTrue(%IsStrong({m() { super.m() }}));
81 // Object literals with constant functions are treated specially, 102 // Object literals with constant functions are treated specially,
82 // but currently only on the toplevel (using Realm.eval to emulate that). 103 // but currently only on the toplevel (using Realm.eval to emulate that).
83 assertTrue(%IsStrong({f: function(){}})); 104 assertStrongObject({f: function(){}});
84 assertTrue(%IsStrong(Realm.eval(Realm.current(), 105 assertStrongObject(Realm.eval(Realm.current(),
85 "'use strong'; ({f: function(){}})"))); 106 "'use strong'; ({f: function(){}})"));
107 assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}}));
86 })(); 108 })();
87 109
88 (function WeakArrayLiterals(...args) { 110 (function WeakArrayLiterals(...args) {
89 let [...r] = []; 111 let [...r] = [];
90 assertTrue(!%IsStrong(args)); 112 assertTrue(!%IsStrong(args));
91 assertTrue(!%IsStrong(r)); 113 assertTrue(!%IsStrong(r));
92 assertTrue(!%IsStrong([])); 114 assertTrue(!%IsStrong([]));
93 assertTrue(!%IsStrong([1, 2, 3])); 115 assertTrue(!%IsStrong([1, 2, 3]));
94 assertTrue(!%IsStrong([[[]]])); 116 assertTrue(!%IsStrong([[[]]]));
95 assertTrue(!%IsStrong([[1], {}, [[3]]])); 117 assertTrue(!%IsStrong([[1], {}, [[3]]]));
96 assertTrue(!%IsStrong([[1], {}, [[3]]][0])); 118 assertTrue(!%IsStrong([[1], {}, [[3]]][0]));
97 assertTrue(!%IsStrong([[1], {}, [[3]]][1])); 119 assertTrue(!%IsStrong([[1], {}, [[3]]][1]));
98 assertTrue(!%IsStrong([[1], {}, [[3]]][2])); 120 assertTrue(!%IsStrong([[1], {}, [[3]]][2]));
99 assertTrue(!%IsStrong([[1], {}, [[3]]][2][0])); 121 assertTrue(!%IsStrong([[1], {}, [[3]]][2][0]));
100 })(); 122 })();
101 123
102 (function StrongArrayLiterals(...args) { 124 (function StrongArrayLiterals(...args) {
103 'use strong'; 125 'use strong';
104 let [...r] = []; 126 let [...r] = [];
105 // TODO(rossberg): teach strongness to FastCloneShallowArrayStub 127 // TODO(rossberg): teach strongness to FastCloneShallowArrayStub
106 // assertTrue(%IsStrong(args)); 128 // assertTrue(%IsStrong(args));
107 // assertTrue(%IsStrong(r)); 129 // assertTrue(%IsStrong(r));
108 // assertTrue(%IsStrong([])); 130 // assertTrue(%IsStrong([]));
109 // assertTrue(%IsStrong([1, 2, 3])); 131 // assertTrue(%IsStrong([1, 2, 3]));
110 // assertTrue(%IsStrong([1, 2, ...[3, 4], 5])); 132 // assertTrue(%IsStrong([1, 2, ...[3, 4], 5]));
111 assertTrue(%IsStrong([[[]]])); 133 assertStrongArray([[[]]]);
112 assertTrue(%IsStrong([[1], {}, [[3]]])); 134 assertStrongArray([[1], {}, [[3]]]);
113 assertTrue(%IsStrong([[1], {}, [[3]]][0])); 135 assertStrongArray([[1], {}, [[3]]][0]);
114 assertTrue(%IsStrong([[1], {}, [[3]]][1])); 136 assertStrongObject([[1], {}, [[3]]][1]);
115 assertTrue(%IsStrong([[1], {}, [[3]]][2])); 137 assertStrongArray([[1], {}, [[3]]][2]);
116 assertTrue(%IsStrong([[1], {}, [[3]]][2][0])); 138 assertStrongArray([[1], {}, [[3]]][2][0]);
117 })(); 139 })();
118 140
119 (function WeakFunctionLiterals() { 141 (function WeakFunctionLiterals() {
120 function f() {} 142 function f() {}
121 assertTrue(!%IsStrong(f)); 143 assertTrue(!%IsStrong(f));
122 assertTrue(!%IsStrong(function(){})); 144 assertTrue(!%IsStrong(function(){}));
123 assertTrue(!%IsStrong(function f(){})); 145 assertTrue(!%IsStrong(function f(){}));
124 assertTrue(!%IsStrong(() => {})); 146 assertTrue(!%IsStrong(() => {}));
125 assertTrue(!%IsStrong(x => x)); 147 assertTrue(!%IsStrong(x => x));
126 assertTrue(!%IsStrong({m(){}}.m)); 148 assertTrue(!%IsStrong({m(){}}.m));
127 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 149 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
128 {get a(){}}, 'a').get)); 150 {get a(){}}, 'a').get));
129 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 151 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
130 {set a(x){}}, 'a').set)); 152 {set a(x){}}, 'a').set));
131 assertTrue(!%IsStrong((class {static m(){}}).m)); 153 assertTrue(!%IsStrong((class {static m(){}}).m));
132 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 154 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
133 class {static get a(){}}, 'a').get)); 155 class {static get a(){}}, 'a').get));
134 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 156 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
135 class {static set a(x){}}, 'a').set)); 157 class {static set a(x){}}, 'a').set));
136 assertTrue(!%IsStrong((new class {m(){}}).m)); 158 assertTrue(!%IsStrong((new class {m(){}}).m));
137 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 159 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
138 (class {get a(){}}).prototype, 'a').get)); 160 (class {get a(){}}).prototype, 'a').get));
139 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor( 161 assertTrue(!%IsStrong(Object.getOwnPropertyDescriptor(
140 (class {set a(x){}}).prototype, 'a').set)); 162 (class {set a(x){}}).prototype, 'a').set));
141 })(); 163 })();
142 164
143 (function StrongFunctionLiterals() { 165 (function StrongFunctionLiterals() {
144 'use strong'; 166 'use strong';
145 function f() {} 167 function f() {}
146 assertTrue(%IsStrong(f)); 168 assertStrongFunction(f);
147 assertTrue(%IsStrong(function(){})); 169 assertStrongFunction(function(){});
148 assertTrue(%IsStrong(function f(){})); 170 assertStrongFunction(function f(){});
149 assertTrue(%IsStrong(() => {})); 171 assertStrongFunction(() => {});
150 assertTrue(%IsStrong(x => x)); 172 assertStrongFunction(x => x);
151 assertTrue(%IsStrong({m(){}}.m)); 173 assertStrongFunction({m(){}}.m);
152 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 174 assertStrongFunction(Object.getOwnPropertyDescriptor(
153 {get a(){}}, 'a').get)); 175 {get a(){}}, 'a').get);
154 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 176 assertStrongFunction(Object.getOwnPropertyDescriptor(
155 {set a(x){}}, 'a').set)); 177 {set a(x){}}, 'a').set);
156 assertTrue(%IsStrong((class {static m(){}}).m)); 178 assertStrongFunction((class {static m(){}}).m);
157 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 179 assertStrongFunction(Object.getOwnPropertyDescriptor(
158 class {static get a(){}}, 'a').get)); 180 class {static get a(){}}, 'a').get);
159 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 181 assertStrongFunction(Object.getOwnPropertyDescriptor(
160 class {static set a(x){}}, 'a').set)); 182 class {static set a(x){}}, 'a').set);
161 assertTrue(%IsStrong((new class {m(){}}).m)); 183 assertStrongFunction((new class {m(){}}).m);
162 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 184 assertStrongFunction(Object.getOwnPropertyDescriptor(
163 (class {get a(){}}).prototype, 'a').get)); 185 (class {get a(){}}).prototype, 'a').get);
164 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 186 assertStrongFunction(Object.getOwnPropertyDescriptor(
165 (class {set a(x){}}).prototype, 'a').set)); 187 (class {set a(x){}}).prototype, 'a').set);
166 })(); 188 })();
167 189
168 (function SelfStrongFunctionLiterals() { 190 (function SelfStrongFunctionLiterals() {
169 function f() {'use strong'} 191 function f() {'use strong'}
170 assertTrue(%IsStrong(f)); 192 assertStrongFunction(f);
171 assertTrue(%IsStrong(function(){'use strong'})); 193 assertStrongFunction(function(){'use strong'});
172 assertTrue(%IsStrong(function f(){'use strong'})); 194 assertStrongFunction(function f(){'use strong'});
173 assertTrue(%IsStrong(() => {'use strong'})); 195 assertStrongFunction(() => {'use strong'});
174 assertTrue(%IsStrong(x => {'use strong'})); 196 assertStrongFunction(x => {'use strong'});
175 assertTrue(%IsStrong({m(){'use strong'}}.m)); 197 assertStrongFunction({m(){'use strong'}}.m);
176 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 198 assertStrongFunction(Object.getOwnPropertyDescriptor(
177 {get a(){'use strong'}}, 'a').get)); 199 {get a(){'use strong'}}, 'a').get);
178 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 200 assertStrongFunction(Object.getOwnPropertyDescriptor(
179 {set a(x){'use strong'}}, 'a').set)); 201 {set a(x){'use strong'}}, 'a').set);
180 assertTrue(%IsStrong((class {static m(){'use strong'}}).m)); 202 assertStrongFunction((class {static m(){'use strong'}}).m);
181 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 203 assertStrongFunction(Object.getOwnPropertyDescriptor(
182 class {static get a(){'use strong'}}, 'a').get)); 204 class {static get a(){'use strong'}}, 'a').get);
183 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 205 assertStrongFunction(Object.getOwnPropertyDescriptor(
184 class {static set a(x){'use strong'}}, 'a').set)); 206 class {static set a(x){'use strong'}}, 'a').set);
185 assertTrue(%IsStrong((new class {m(){'use strong'}}).m)); 207 assertStrongFunction((new class {m(){'use strong'}}).m);
186 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 208 assertStrongFunction(Object.getOwnPropertyDescriptor(
187 (class {get a(){'use strong'}}).prototype, 'a').get)); 209 (class {get a(){'use strong'}}).prototype, 'a').get);
188 assertTrue(%IsStrong(Object.getOwnPropertyDescriptor( 210 assertStrongFunction(Object.getOwnPropertyDescriptor(
189 (class {set a(x){'use strong'}}).prototype, 'a').set)); 211 (class {set a(x){'use strong'}}).prototype, 'a').set);
190 })(); 212 })();
191 213
192 (function WeakGeneratorLiterals() { 214 (function WeakGeneratorLiterals() {
193 function* g() {} 215 function* g() {}
194 assertTrue(!%IsStrong(g)); 216 assertTrue(!%IsStrong(g));
195 assertTrue(!%IsStrong(function*(){})); 217 assertTrue(!%IsStrong(function*(){}));
196 assertTrue(!%IsStrong(function* g(){})); 218 assertTrue(!%IsStrong(function* g(){}));
197 assertTrue(!%IsStrong({*m(){}}.m)); 219 assertTrue(!%IsStrong({*m(){}}.m));
198 assertTrue(!%IsStrong((class {static *m(){}}).m)); 220 assertTrue(!%IsStrong((class {static *m(){}}).m));
199 assertTrue(!%IsStrong((new class {*m(){}}).m)); 221 assertTrue(!%IsStrong((new class {*m(){}}).m));
200 })(); 222 })();
201 223
202 (function StrongGeneratorLiterals() { 224 (function StrongGeneratorLiterals() {
203 'use strong'; 225 'use strong';
204 function* g() {} 226 function* g() {}
205 assertTrue(%IsStrong(g)); 227 assertStrongGenerator(g);
206 assertTrue(%IsStrong(function*(){})); 228 assertStrongGenerator(function*(){});
207 assertTrue(%IsStrong(function* g(){})); 229 assertStrongGenerator(function* g(){});
208 assertTrue(%IsStrong({*m(){}}.m)); 230 assertStrongGenerator({*m(){}}.m);
209 assertTrue(%IsStrong((class {static *m(){}}).m)); 231 assertStrongGenerator((class {static *m(){}}).m);
210 assertTrue(%IsStrong((new class {*m(){}}).m)); 232 assertStrongGenerator((new class {*m(){}}).m);
211 })(); 233 })();
212 234
213 (function SelfStrongGeneratorLiterals() { 235 (function SelfStrongGeneratorLiterals() {
214 function* g() {'use strong'} 236 function* g() {'use strong'}
215 assertTrue(%IsStrong(g)); 237 assertStrongGenerator(g);
216 assertTrue(%IsStrong(function*(){'use strong'})); 238 assertStrongGenerator(function*(){'use strong'});
217 assertTrue(%IsStrong(function* g(){'use strong'})); 239 assertStrongGenerator(function* g(){'use strong'});
218 assertTrue(%IsStrong({*m(){'use strong'}}.m)); 240 assertStrongGenerator({*m(){'use strong'}}.m);
219 assertTrue(%IsStrong((class {static *m(){'use strong'}}).m)); 241 assertStrongGenerator((class {static *m(){'use strong'}}).m);
220 assertTrue(%IsStrong((new class {*m(){'use strong'}}).m)); 242 assertStrongGenerator((new class {*m(){'use strong'}}).m);
221 })(); 243 })();
222 244
223 (function WeakClassLiterals() { 245 (function WeakClassLiterals() {
224 function assertWeakClass(C) { 246 function assertWeakClass(C) {
225 assertTrue(!%IsStrong(C)); 247 assertTrue(!%IsStrong(C));
226 assertTrue(!%IsStrong(C.prototype)); 248 assertTrue(!%IsStrong(C.prototype));
227 } 249 }
228 class C {}; 250 class C {};
229 class D extends C {}; 251 class D extends C {};
230 class E extends Object {}; 252 class E extends Object {};
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 306
285 (function WeakRegExpLiterals() { 307 (function WeakRegExpLiterals() {
286 assertTrue(!%IsStrong(/abc/)); 308 assertTrue(!%IsStrong(/abc/));
287 })(); 309 })();
288 310
289 (function StrongRegExpLiterals() { 311 (function StrongRegExpLiterals() {
290 'use strong'; 312 'use strong';
291 // TODO(rossberg): implement strong regexp literals 313 // TODO(rossberg): implement strong regexp literals
292 // assertTrue(%IsStrong(/abc/)); 314 // assertTrue(%IsStrong(/abc/));
293 })(); 315 })();
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698