Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/api-inl.h"
6 : #include "src/ast/ast.h"
7 : #include "src/compiler.h"
8 : #include "src/objects-inl.h"
9 : #include "src/parsing/parse-info.h"
10 : #include "src/parsing/parsing.h"
11 : #include "src/parsing/preparse-data-impl.h"
12 : #include "src/parsing/preparse-data.h"
13 :
14 : #include "test/cctest/cctest.h"
15 : #include "test/cctest/scope-test-helper.h"
16 : #include "test/cctest/unicode-helpers.h"
17 :
18 : namespace {
19 :
20 : enum SkipTests {
21 : DONT_SKIP = 0,
22 : // Skip if the test function declares itself strict, otherwise don't skip.
23 : SKIP_STRICT_FUNCTION = 1,
24 : // Skip if there's a "use strict" directive above the test.
25 : SKIP_STRICT_OUTER = 1 << 1,
26 : SKIP_ARROW = 1 << 2,
27 : SKIP_STRICT = SKIP_STRICT_FUNCTION | SKIP_STRICT_OUTER
28 : };
29 :
30 : enum class PreciseMaybeAssigned { YES, NO };
31 :
32 : enum class Bailout { BAILOUT_IF_OUTER_SLOPPY, NO };
33 :
34 : } // namespace
35 :
36 26644 : TEST(PreParserScopeAnalysis) {
37 : i::Isolate* isolate = CcTest::i_isolate();
38 : i::Factory* factory = isolate->factory();
39 5 : LocalContext env;
40 :
41 : struct Outer {
42 : const char* code;
43 : bool strict_outer;
44 : bool strict_test_function;
45 : bool arrow;
46 : } outers[] = {
47 : // Normal case (test function at the laziness boundary):
48 : {"function test(%s) { %s function skippable() { } } test;", false, false,
49 : false},
50 :
51 : {"var test2 = function test(%s) { %s function skippable() { } }; test2",
52 : false, false, false},
53 :
54 : // Arrow functions (they can never be at the laziness boundary):
55 : {"function test() { (%s) => { %s }; function skippable() { } } test;",
56 : false, false, true},
57 :
58 : // Repeat the above mentioned cases with global 'use strict'
59 : {"'use strict'; function test(%s) { %s function skippable() { } } test;",
60 : true, false, false},
61 :
62 : {"'use strict'; var test2 = function test(%s) { %s \n"
63 : "function skippable() { } }; test2",
64 : true, false, false},
65 :
66 : {"'use strict'; function test() { (%s) => { %s };\n"
67 : "function skippable() { } } test;",
68 : true, false, true},
69 :
70 : // ... and with the test function declaring itself strict:
71 : {"function test(%s) { 'use strict'; %s function skippable() { } } test;",
72 : false, true, false},
73 :
74 : {"var test2 = function test(%s) { 'use strict'; %s \n"
75 : "function skippable() { } }; test2",
76 : false, true, false},
77 :
78 : {"function test() { 'use strict'; (%s) => { %s };\n"
79 : "function skippable() { } } test;",
80 : false, true, true},
81 :
82 : // Methods containing skippable functions.
83 : {"function get_method() {\n"
84 : " class MyClass { test_method(%s) { %s function skippable() { } } }\n"
85 : " var o = new MyClass(); return o.test_method;\n"
86 : "}\n"
87 : "get_method();",
88 : true, true, false},
89 :
90 : // Corner case: function expression with name "arguments".
91 : {"var test = function arguments(%s) { %s function skippable() { } };\n"
92 : "test;\n",
93 : false, false, false}
94 :
95 : // FIXME(marja): Generators and async functions
96 5 : };
97 :
98 83030 : struct Inner {
99 1210 : Inner(const char* s) : source(s) {} // NOLINT
100 135 : Inner(const char* s, SkipTests skip) : source(s), skip(skip) {}
101 : Inner(const char* s, SkipTests skip, PreciseMaybeAssigned precise)
102 10 : : source(s), skip(skip), precise_maybe_assigned(precise) {}
103 :
104 85 : Inner(const char* p, const char* s) : params(p), source(s) {}
105 : Inner(const char* p, const char* s, SkipTests skip)
106 270 : : params(p), source(s), skip(skip) {}
107 : Inner(const char* p, const char* s, SkipTests skip,
108 : PreciseMaybeAssigned precise)
109 55 : : params(p), source(s), skip(skip), precise_maybe_assigned(precise) {}
110 : Inner(const char* p, const char* s, SkipTests skip, Bailout bailout)
111 15 : : params(p), source(s), skip(skip), bailout(bailout) {}
112 :
113 25 : Inner(const char* s, std::function<void()> p, std::function<void()> e)
114 50 : : source(s), prologue(p), epilogue(e) {}
115 :
116 : const char* params = "";
117 : const char* source;
118 : SkipTests skip = DONT_SKIP;
119 : PreciseMaybeAssigned precise_maybe_assigned = PreciseMaybeAssigned::YES;
120 : Bailout bailout = Bailout::NO;
121 : std::function<void()> prologue = nullptr;
122 : std::function<void()> epilogue = nullptr;
123 : } inners[] = {
124 : // Simple cases
125 : {"var1;"},
126 : {"var1 = 5;"},
127 : {"if (true) {}"},
128 : {"function f1() {}"},
129 : {"test;"},
130 : {"test2;"},
131 :
132 : // Var declarations and assignments.
133 : {"var var1;"},
134 : {"var var1; var1 = 5;"},
135 : {"if (true) { var var1; }", DONT_SKIP, PreciseMaybeAssigned::NO},
136 : {"if (true) { var var1; var1 = 5; }"},
137 : {"var var1; function f() { var1; }"},
138 : {"var var1; var1 = 5; function f() { var1; }"},
139 : {"var var1; function f() { var1 = 5; }"},
140 : {"function f1() { f2(); } function f2() {}"},
141 :
142 : // Let declarations and assignments.
143 : {"let var1;"},
144 : {"let var1; var1 = 5;"},
145 : {"if (true) { let var1; }"},
146 : {"if (true) { let var1; var1 = 5; }"},
147 : {"let var1; function f() { var1; }"},
148 : {"let var1; var1 = 5; function f() { var1; }"},
149 : {"let var1; function f() { var1 = 5; }"},
150 :
151 : // Const declarations.
152 : {"const var1 = 5;"},
153 : {"if (true) { const var1 = 5; }"},
154 : {"const var1 = 5; function f() { var1; }"},
155 :
156 : // Functions.
157 : {"function f1() { let var2; }"},
158 : {"var var1 = function f1() { let var2; };"},
159 : {"let var1 = function f1() { let var2; };"},
160 : {"const var1 = function f1() { let var2; };"},
161 : {"var var1 = function() { let var2; };"},
162 : {"let var1 = function() { let var2; };"},
163 : {"const var1 = function() { let var2; };"},
164 :
165 : {"function *f1() { let var2; }"},
166 : {"let var1 = function *f1() { let var2; };"},
167 : {"let var1 = function*() { let var2; };"},
168 :
169 : {"async function f1() { let var2; }"},
170 : {"let var1 = async function f1() { let var2; };"},
171 : {"let var1 = async function() { let var2; };"},
172 :
173 : // Redeclarations.
174 : {"var var1; var var1;"},
175 : {"var var1; var var1; var1 = 5;"},
176 : {"var var1; if (true) { var var1; }"},
177 : {"if (true) { var var1; var var1; }"},
178 : {"var var1; if (true) { var var1; var1 = 5; }"},
179 : {"if (true) { var var1; var var1; var1 = 5; }"},
180 : {"var var1; var var1; function f() { var1; }"},
181 : {"var var1; var var1; function f() { var1 = 5; }"},
182 :
183 : // Shadowing declarations.
184 : {"var var1; if (true) { var var1; }"},
185 : {"var var1; if (true) { let var1; }"},
186 : {"let var1; if (true) { let var1; }"},
187 :
188 : {"var var1; if (true) { const var1 = 0; }"},
189 : {"const var1 = 0; if (true) { const var1 = 0; }"},
190 :
191 : // Variables deeper in the subscopes (scopes without variables inbetween).
192 : {"if (true) { if (true) { function f() { var var1 = 5; } } }"},
193 :
194 : // Arguments and this.
195 : {"arguments;"},
196 : {"arguments = 5;", SKIP_STRICT},
197 : {"if (true) { arguments; }"},
198 : {"if (true) { arguments = 5; }", SKIP_STRICT},
199 : {"() => { arguments; };"},
200 : {"var1, var2, var3", "arguments;"},
201 : {"var1, var2, var3", "arguments = 5;", SKIP_STRICT},
202 : {"var1, var2, var3", "() => { arguments; };"},
203 : {"var1, var2, var3", "() => { arguments = 5; };", SKIP_STRICT},
204 :
205 : {"this;"},
206 : {"if (true) { this; }"},
207 : {"() => { this; };"},
208 :
209 : // Variable called "arguments"
210 : {"var arguments;", SKIP_STRICT},
211 : {"var arguments; arguments = 5;", SKIP_STRICT},
212 : {"if (true) { var arguments; }", SKIP_STRICT, PreciseMaybeAssigned::NO},
213 : {"if (true) { var arguments; arguments = 5; }", SKIP_STRICT},
214 : {"var arguments; function f() { arguments; }", SKIP_STRICT},
215 : {"var arguments; arguments = 5; function f() { arguments; }",
216 : SKIP_STRICT},
217 : {"var arguments; function f() { arguments = 5; }", SKIP_STRICT},
218 :
219 : {"let arguments;", SKIP_STRICT},
220 : {"let arguments; arguments = 5;", SKIP_STRICT},
221 : {"if (true) { let arguments; }", SKIP_STRICT},
222 : {"if (true) { let arguments; arguments = 5; }", SKIP_STRICT},
223 : {"let arguments; function f() { arguments; }", SKIP_STRICT},
224 : {"let arguments; arguments = 5; function f() { arguments; }",
225 : SKIP_STRICT},
226 : {"let arguments; function f() { arguments = 5; }", SKIP_STRICT},
227 :
228 : {"const arguments = 5;", SKIP_STRICT},
229 : {"if (true) { const arguments = 5; }", SKIP_STRICT},
230 : {"const arguments = 5; function f() { arguments; }", SKIP_STRICT},
231 :
232 : // Destructuring declarations.
233 : {"var [var1, var2] = [1, 2];"},
234 : {"var [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
235 : {"var [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
236 : {"var [var1, ...var2] = [1, 2, 3];"},
237 :
238 : {"var {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
239 : {"var {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
240 : {"var {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
241 :
242 : {"let [var1, var2] = [1, 2];"},
243 : {"let [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
244 : {"let [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
245 : {"let [var1, ...var2] = [1, 2, 3];"},
246 :
247 : {"let {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
248 : {"let {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
249 : {"let {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
250 :
251 : {"const [var1, var2] = [1, 2];"},
252 : {"const [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"},
253 : {"const [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"},
254 : {"const [var1, ...var2] = [1, 2, 3];"},
255 :
256 : {"const {var1: var2, var3: var4} = {var1: 1, var3: 2};"},
257 : {"const {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"},
258 : {"const {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
259 :
260 : // Referencing the function variable.
261 : {"test;"},
262 : {"function f1() { f1; }"},
263 : {"function f1() { function f2() { f1; } }"},
264 : {"function arguments() {}", SKIP_STRICT},
265 : {"function f1() {} function f1() {}", SKIP_STRICT},
266 : {"var f1; function f1() {}"},
267 :
268 : // Assigning to the function variable.
269 : {"test = 3;"},
270 : {"function f1() { f1 = 3; }"},
271 : {"function f1() { f1; } f1 = 3;"},
272 : {"function arguments() {} arguments = 8;", SKIP_STRICT},
273 : {"function f1() {} f1 = 3; function f1() {}", SKIP_STRICT},
274 :
275 : // Evals.
276 : {"var var1; eval('');"},
277 : {"var var1; function f1() { eval(''); }"},
278 : {"let var1; eval('');"},
279 : {"let var1; function f1() { eval(''); }"},
280 : {"const var1 = 10; eval('');"},
281 : {"const var1 = 10; function f1() { eval(''); }"},
282 :
283 : // Standard for loops.
284 : {"for (var var1 = 0; var1 < 10; ++var1) { }"},
285 : {"for (let var1 = 0; var1 < 10; ++var1) { }"},
286 : {"for (const var1 = 0; var1 < 10; ++var1) { }"},
287 :
288 : {"for (var var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
289 : {"for (let var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
290 : {"for (const var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"},
291 :
292 : // For of loops
293 : {"for (var1 of [1, 2]) { }"},
294 : {"for (var var1 of [1, 2]) { }"},
295 : {"for (let var1 of [1, 2]) { }"},
296 : {"for (const var1 of [1, 2]) { }"},
297 :
298 : {"for (var1 of [1, 2]) { var1; }"},
299 : {"for (var var1 of [1, 2]) { var1; }"},
300 : {"for (let var1 of [1, 2]) { var1; }"},
301 : {"for (const var1 of [1, 2]) { var1; }"},
302 :
303 : {"for (var1 of [1, 2]) { var1 = 0; }"},
304 : {"for (var var1 of [1, 2]) { var1 = 0; }"},
305 : {"for (let var1 of [1, 2]) { var1 = 0; }"},
306 : {"for (const var1 of [1, 2]) { var1 = 0; }"},
307 :
308 : {"for (var1 of [1, 2]) { function foo() { var1; } }"},
309 : {"for (var var1 of [1, 2]) { function foo() { var1; } }"},
310 : {"for (let var1 of [1, 2]) { function foo() { var1; } }"},
311 : {"for (const var1 of [1, 2]) { function foo() { var1; } }"},
312 :
313 : {"for (var1 of [1, 2]) { function foo() { var1 = 0; } }"},
314 : {"for (var var1 of [1, 2]) { function foo() { var1 = 0; } }"},
315 : {"for (let var1 of [1, 2]) { function foo() { var1 = 0; } }"},
316 : {"for (const var1 of [1, 2]) { function foo() { var1 = 0; } }"},
317 :
318 : // For in loops
319 : {"for (var1 in {a: 6}) { }"},
320 : {"for (var var1 in {a: 6}) { }"},
321 : {"for (let var1 in {a: 6}) { }"},
322 : {"for (const var1 in {a: 6}) { }"},
323 :
324 : {"for (var1 in {a: 6}) { var1; }"},
325 : {"for (var var1 in {a: 6}) { var1; }"},
326 : {"for (let var1 in {a: 6}) { var1; }"},
327 : {"for (const var1 in {a: 6}) { var1; }"},
328 :
329 : {"for (var1 in {a: 6}) { var1 = 0; }"},
330 : {"for (var var1 in {a: 6}) { var1 = 0; }"},
331 : {"for (let var1 in {a: 6}) { var1 = 0; }"},
332 : {"for (const var1 in {a: 6}) { var1 = 0; }"},
333 :
334 : {"for (var1 in {a: 6}) { function foo() { var1; } }"},
335 : {"for (var var1 in {a: 6}) { function foo() { var1; } }"},
336 : {"for (let var1 in {a: 6}) { function foo() { var1; } }"},
337 : {"for (const var1 in {a: 6}) { function foo() { var1; } }"},
338 :
339 : {"for (var1 in {a: 6}) { function foo() { var1 = 0; } }"},
340 : {"for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"},
341 : {"for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"},
342 : {"for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"},
343 :
344 : {"for (var1 in {a: 6}) { function foo() { var1 = 0; } }"},
345 : {"for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"},
346 : {"for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"},
347 : {"for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"},
348 :
349 : // Destructuring loop variable
350 : {"for ([var1, var2] of [[1, 1], [2, 2]]) { }"},
351 : {"for (var [var1, var2] of [[1, 1], [2, 2]]) { }"},
352 : {"for (let [var1, var2] of [[1, 1], [2, 2]]) { }"},
353 : {"for (const [var1, var2] of [[1, 1], [2, 2]]) { }"},
354 :
355 : {"for ([var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
356 : {"for (var [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
357 : {"for (let [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
358 : {"for (const [var1, var2] of [[1, 1], [2, 2]]) { var2 = 3; }"},
359 :
360 : {"for ([var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
361 : {"for (var [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
362 : {"for (let [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
363 : {"for (const [var1, var2] of [[1, 1], [2, 2]]) { () => { var2 = 3; } }"},
364 :
365 : // Skippable function in loop header
366 : {"for (let [var1, var2 = function() { }] of [[1]]) { }"},
367 : {"for (let [var1, var2 = function() { var1; }] of [[1]]) { }"},
368 : {"for (let [var1, var2 = function() { var2; }] of [[1]]) { }"},
369 : {"for (let [var1, var2 = function() { var1; var2; }] of [[1]]) { }"},
370 : {"for (let [var1, var2 = function() { var1 = 0; }] of [[1]]) { }"},
371 : {"for (let [var1, var2 = function() { var2 = 0; }] of [[1]]) { }"},
372 : {"for (let [var1, var2 = function() { var1 = 0; var2 = 0; }] of [[1]]) { "
373 : "}"},
374 :
375 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
376 : "var1; } }"},
377 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
378 : "var2; } }"},
379 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
380 : "var1; var2; } }"},
381 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
382 : "var1 = 0; } }"},
383 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
384 : "var2 = 0; } }"},
385 : {"for (let [var1, var2 = function() { }] of [[1]]) { function f() { "
386 : "var1 = 0; var2 = 0; } }"},
387 : {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
388 : "function f() { var1; } }"},
389 : {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
390 : "function f() { var2; } }"},
391 : {"for (let [var1, var2 = function() { var1; }] of [[1]]) { "
392 : "function f() { var1; var2; } }"},
393 : {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
394 : "function f() { var1; } }"},
395 : {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
396 : "function f() { var2; } }"},
397 : {"for (let [var1, var2 = function() { var2; }] of [[1]]) { "
398 : "function f() { var1; var2; } }"},
399 :
400 : // Loops without declarations
401 : {"var var1 = 0; for ( ; var1 < 2; ++var1) { }"},
402 : {"var var1 = 0; for ( ; var1 < 2; ++var1) { function foo() { var1; } }"},
403 : {"var var1 = 0; for ( ; var1 > 2; ) { }"},
404 : {"var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1; } }"},
405 : {"var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1 = 6; } }"},
406 :
407 : {"var var1 = 0; for(var1; var1 < 2; ++var1) { }"},
408 : {"var var1 = 0; for (var1; var1 < 2; ++var1) { function foo() { var1; } "
409 : "}"},
410 : {"var var1 = 0; for (var1; var1 > 2; ) { }"},
411 : {"var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1; } }"},
412 : {"var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1 = 6; } }"},
413 :
414 : // Block functions (potentially sloppy).
415 : {"if (true) { function f1() {} }"},
416 : {"if (true) { function f1() {} function f1() {} }", SKIP_STRICT},
417 : {"if (true) { if (true) { function f1() {} } }"},
418 : {"if (true) { if (true) { function f1() {} function f1() {} } }",
419 : SKIP_STRICT},
420 : {"if (true) { function f1() {} f1 = 3; }"},
421 :
422 : {"if (true) { function f1() {} function foo() { f1; } }"},
423 : {"if (true) { function f1() {} } function foo() { f1; }"},
424 : {"if (true) { function f1() {} function f1() {} function foo() { f1; } "
425 : "}",
426 : SKIP_STRICT},
427 : {"if (true) { function f1() {} function f1() {} } function foo() { f1; "
428 : "}",
429 : SKIP_STRICT},
430 : {"if (true) { if (true) { function f1() {} } function foo() { f1; } }"},
431 : {"if (true) { if (true) { function f1() {} function f1() {} } function "
432 : "foo() { f1; } }",
433 : SKIP_STRICT},
434 : {"if (true) { function f1() {} f1 = 3; function foo() { f1; } }"},
435 : {"if (true) { function f1() {} f1 = 3; } function foo() { f1; }"},
436 :
437 : {"var f1 = 1; if (true) { function f1() {} }"},
438 : {"var f1 = 1; if (true) { function f1() {} } function foo() { f1; }"},
439 :
440 : {"if (true) { function f1() {} function f2() { f1(); } }"},
441 :
442 : {"if (true) { function *f1() {} }"},
443 : {"if (true) { async function f1() {} }"},
444 :
445 : // (Potentially sloppy) block function shadowing a catch variable.
446 : {"try { } catch(var1) { if (true) { function var1() {} } }"},
447 :
448 : // Simple parameters.
449 : {"var1", ""},
450 : {"var1", "var1;"},
451 : {"var1", "var1 = 9;"},
452 : {"var1", "function f1() { var1; }"},
453 : {"var1", "function f1() { var1 = 9; }"},
454 :
455 : {"var1, var2", ""},
456 : {"var1, var2", "var2;"},
457 : {"var1, var2", "var2 = 9;"},
458 : {"var1, var2", "function f1() { var2; }"},
459 : {"var1, var2", "function f1() { var2 = 9; }"},
460 : {"var1, var2", "var1;"},
461 : {"var1, var2", "var1 = 9;"},
462 : {"var1, var2", "function f1() { var1; }"},
463 : {"var1, var2", "function f1() { var1 = 9; }"},
464 :
465 : // Duplicate parameters.
466 : {"var1, var1", "", SkipTests(SKIP_STRICT | SKIP_ARROW)},
467 : {"var1, var1", "var1;", SkipTests(SKIP_STRICT | SKIP_ARROW)},
468 : {"var1, var1", "var1 = 9;", SkipTests(SKIP_STRICT | SKIP_ARROW)},
469 : {"var1, var1", "function f1() { var1; }",
470 : SkipTests(SKIP_STRICT | SKIP_ARROW)},
471 : {"var1, var1", "function f1() { var1 = 9; }",
472 : SkipTests(SKIP_STRICT | SKIP_ARROW)},
473 :
474 : // If the function declares itself strict, non-simple parameters aren't
475 : // allowed.
476 :
477 : // Rest parameter.
478 : {"...var2", "", SKIP_STRICT_FUNCTION},
479 : {"...var2", "var2;", SKIP_STRICT_FUNCTION},
480 : {"...var2", "var2 = 9;", SKIP_STRICT_FUNCTION},
481 : {"...var2", "function f1() { var2; }", SKIP_STRICT_FUNCTION},
482 : {"...var2", "function f1() { var2 = 9; }", SKIP_STRICT_FUNCTION},
483 :
484 : {"var1, ...var2", "", SKIP_STRICT_FUNCTION},
485 : {"var1, ...var2", "var2;", SKIP_STRICT_FUNCTION},
486 : {"var1, ...var2", "var2 = 9;", SKIP_STRICT_FUNCTION},
487 : {"var1, ...var2", "function f1() { var2; }", SKIP_STRICT_FUNCTION},
488 : {"var1, ...var2", "function f1() { var2 = 9; }", SKIP_STRICT_FUNCTION},
489 :
490 : // Default parameters.
491 : {"var1 = 3", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
492 : {"var1, var2 = var1", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
493 : {"var1, var2 = 4, ...var3", "", SKIP_STRICT_FUNCTION,
494 : PreciseMaybeAssigned::NO},
495 :
496 : // Destructuring parameters. Because of the search space explosion, we
497 : // cannot test all interesting cases. Let's try to test a relevant subset.
498 : {"[]", "", SKIP_STRICT_FUNCTION},
499 : {"{}", "", SKIP_STRICT_FUNCTION},
500 :
501 : {"[var1]", "", SKIP_STRICT_FUNCTION},
502 : {"{name1: var1}", "", SKIP_STRICT_FUNCTION},
503 : {"{var1}", "", SKIP_STRICT_FUNCTION},
504 :
505 : {"[var1]", "var1;", SKIP_STRICT_FUNCTION},
506 : {"{name1: var1}", "var1;", SKIP_STRICT_FUNCTION},
507 : {"{name1: var1}", "name1;", SKIP_STRICT_FUNCTION},
508 : {"{var1}", "var1;", SKIP_STRICT_FUNCTION},
509 :
510 : {"[var1]", "var1 = 16;", SKIP_STRICT_FUNCTION},
511 : {"{name1: var1}", "var1 = 16;", SKIP_STRICT_FUNCTION},
512 : {"{name1: var1}", "name1 = 16;", SKIP_STRICT_FUNCTION},
513 : {"{var1}", "var1 = 16;", SKIP_STRICT_FUNCTION},
514 :
515 : {"[var1]", "() => { var1; };", SKIP_STRICT_FUNCTION},
516 : {"{name1: var1}", "() => { var1; };", SKIP_STRICT_FUNCTION},
517 : {"{name1: var1}", "() => { name1; };", SKIP_STRICT_FUNCTION},
518 : {"{var1}", "() => { var1; };", SKIP_STRICT_FUNCTION},
519 :
520 : {"[var1, var2, var3]", "", SKIP_STRICT_FUNCTION},
521 : {"{name1: var1, name2: var2, name3: var3}", "", SKIP_STRICT_FUNCTION},
522 : {"{var1, var2, var3}", "", SKIP_STRICT_FUNCTION},
523 :
524 : {"[var1, var2, var3]", "() => { var2 = 16;};", SKIP_STRICT_FUNCTION},
525 : {"{name1: var1, name2: var2, name3: var3}", "() => { var2 = 16;};",
526 : SKIP_STRICT_FUNCTION},
527 : {"{name1: var1, name2: var2, name3: var3}", "() => { name2 = 16;};",
528 : SKIP_STRICT_FUNCTION},
529 : {"{var1, var2, var3}", "() => { var2 = 16;};", SKIP_STRICT_FUNCTION},
530 :
531 : // Nesting destructuring.
532 : {"[var1, [var2, var3], {var4, name5: [var5, var6]}]", "",
533 : SKIP_STRICT_FUNCTION},
534 :
535 : // Complicated params.
536 : {"var1, [var2], var3 = 24, [var4, var5] = [2, 4], var6, {var7}, var8, "
537 : "{name9: var9, name10: var10}, ...var11",
538 : "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
539 :
540 : // Complicated cases from bugs.
541 : {"var1 = {} = {}", "", SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
542 :
543 : // Destructuring rest. Because we can.
544 : {"var1, ...[var2]", "", SKIP_STRICT_FUNCTION},
545 : {"var1, ...[var2]", "() => { var2; };", SKIP_STRICT_FUNCTION},
546 : {"var1, ...{0: var2}", "", SKIP_STRICT_FUNCTION},
547 : {"var1, ...{0: var2}", "() => { var2; };", SKIP_STRICT_FUNCTION},
548 : {"var1, ...[]", "", SKIP_STRICT_FUNCTION},
549 : {"var1, ...{}", "", SKIP_STRICT_FUNCTION},
550 : {"var1, ...[var2, var3]", "", SKIP_STRICT_FUNCTION},
551 : {"var1, ...{0: var2, 1: var3}", "", SKIP_STRICT_FUNCTION},
552 :
553 : // Default parameters for destruring parameters.
554 : {"[var1, var2] = [2, 4]", "", SKIP_STRICT_FUNCTION,
555 : PreciseMaybeAssigned::NO},
556 : {"{var1, var2} = {var1: 3, var2: 3}", "", SKIP_STRICT_FUNCTION,
557 : PreciseMaybeAssigned::NO},
558 :
559 : // Default parameters inside destruring parameters.
560 : {"[var1 = 4, var2 = var1]", "", SKIP_STRICT_FUNCTION,
561 : PreciseMaybeAssigned::NO},
562 : {"{var1 = 4, var2 = var1}", "", SKIP_STRICT_FUNCTION,
563 : PreciseMaybeAssigned::NO},
564 :
565 : // Locals shadowing parameters.
566 : {"var1, var2", "var var1 = 16; () => { var1 = 17; };"},
567 :
568 : // Locals shadowing destructuring parameters and the rest parameter.
569 : {"[var1, var2]", "var var1 = 16; () => { var1 = 17; };",
570 : SKIP_STRICT_FUNCTION},
571 : {"{var1, var2}", "var var1 = 16; () => { var1 = 17; };",
572 : SKIP_STRICT_FUNCTION},
573 : {"var1, var2, ...var3", "var var3 = 16; () => { var3 = 17; };",
574 : SKIP_STRICT_FUNCTION},
575 : {"var1, var2 = var1", "var var1 = 16; () => { var1 = 17; };",
576 : SKIP_STRICT_FUNCTION, PreciseMaybeAssigned::NO},
577 :
578 : // Hoisted sloppy block function shadowing a parameter.
579 : // FIXME(marja): why is maybe_assigned inaccurate?
580 : {"var1, var2", "for (;;) { function var1() { } }", DONT_SKIP,
581 : PreciseMaybeAssigned::NO},
582 :
583 : // Sloppy eval in default parameter.
584 : {"var1, var2 = eval(''), var3", "let var4 = 0;", SKIP_STRICT_FUNCTION,
585 : Bailout::BAILOUT_IF_OUTER_SLOPPY},
586 : {"var1, var2 = eval(''), var3 = eval('')", "let var4 = 0;",
587 : SKIP_STRICT_FUNCTION, Bailout::BAILOUT_IF_OUTER_SLOPPY},
588 :
589 : // Sloppy eval in arrow function parameter list which is inside another
590 : // arrow function parameter list.
591 : {"var1, var2 = (var3, var4 = eval(''), var5) => { let var6; }, var7",
592 : "let var8 = 0;", SKIP_STRICT_FUNCTION, Bailout::BAILOUT_IF_OUTER_SLOPPY},
593 :
594 : // Sloppy eval in a function body with non-simple parameters.
595 : {"var1 = 1, var2 = 2", "eval('');", SKIP_STRICT_FUNCTION},
596 :
597 : // Catch variable
598 : {"try { } catch(var1) { }"},
599 : {"try { } catch(var1) { var1; }"},
600 : {"try { } catch(var1) { var1 = 3; }"},
601 : {"try { } catch(var1) { function f() { var1; } }"},
602 : {"try { } catch(var1) { function f() { var1 = 3; } }"},
603 :
604 : {"try { } catch({var1, var2}) { function f() { var1 = 3; } }"},
605 : {"try { } catch([var1, var2]) { function f() { var1 = 3; } }"},
606 : {"try { } catch({}) { }"},
607 : {"try { } catch([]) { }"},
608 :
609 : // Shadowing the catch variable
610 : {"try { } catch(var1) { var var1 = 3; }"},
611 : {"try { } catch(var1) { var var1 = 3; function f() { var1 = 3; } }"},
612 :
613 : // Classes
614 : {"class MyClass {}"},
615 : {"var1 = class MyClass {};"},
616 : {"var var1 = class MyClass {};"},
617 : {"let var1 = class MyClass {};"},
618 : {"const var1 = class MyClass {};"},
619 : {"var var1 = class {};"},
620 : {"let var1 = class {};"},
621 : {"const var1 = class {};"},
622 :
623 : {"class MyClass { constructor() {} }"},
624 : {"class MyClass { constructor() { var var1; } }"},
625 : {"class MyClass { constructor() { var var1 = 11; } }"},
626 : {"class MyClass { constructor() { var var1; function foo() { var1 = 11; "
627 : "} } }"},
628 :
629 : {"class MyClass { m() {} }"},
630 : {"class MyClass { m() { var var1; } }"},
631 : {"class MyClass { m() { var var1 = 11; } }"},
632 : {"class MyClass { m() { var var1; function foo() { var1 = 11; } } }"},
633 :
634 : {"class MyClass { static m() {} }"},
635 : {"class MyClass { static m() { var var1; } }"},
636 : {"class MyClass { static m() { var var1 = 11; } }"},
637 : {"class MyClass { static m() { var var1; function foo() { var1 = 11; } } "
638 : "}"},
639 :
640 : {"class MyBase {} class MyClass extends MyBase {}"},
641 : {"class MyClass extends MyBase { constructor() {} }"},
642 : {"class MyClass extends MyBase { constructor() { super(); } }"},
643 : {"class MyClass extends MyBase { constructor() { var var1; } }"},
644 : {"class MyClass extends MyBase { constructor() { var var1 = 11; } }"},
645 : {"class MyClass extends MyBase { constructor() { var var1; function "
646 : "foo() { var1 = 11; } } }"},
647 :
648 : {"class MyClass extends MyBase { m() {} }"},
649 : {"class MyClass extends MyBase { m() { super.foo; } }"},
650 : {"class MyClass extends MyBase { m() { var var1; } }"},
651 : {"class MyClass extends MyBase { m() { var var1 = 11; } }"},
652 : {"class MyClass extends MyBase { m() { var var1; function foo() { var1 = "
653 : "11; } } }"},
654 :
655 : {"class MyClass extends MyBase { static m() {} }"},
656 : {"class MyClass extends MyBase { static m() { super.foo; } }"},
657 : {"class MyClass extends MyBase { static m() { var var1; } }"},
658 : {"class MyClass extends MyBase { static m() { var var1 = 11; } }"},
659 : {"class MyClass extends MyBase { static m() { var var1; function foo() { "
660 : "var1 = 11; } } }"},
661 :
662 : {"class X { ['bar'] = 1; }; new X;",
663 55 : [] { i::FLAG_harmony_public_fields = true; },
664 55 : [] { i::FLAG_harmony_public_fields = false; }},
665 : {"class X { static ['foo'] = 2; }; new X;",
666 : [] {
667 55 : i::FLAG_harmony_public_fields = true;
668 55 : i::FLAG_harmony_static_fields = true;
669 : },
670 : [] {
671 55 : i::FLAG_harmony_public_fields = false;
672 55 : i::FLAG_harmony_static_fields = false;
673 : }},
674 : {"class X { ['bar'] = 1; static ['foo'] = 2; }; new X;",
675 : [] {
676 55 : i::FLAG_harmony_public_fields = true;
677 55 : i::FLAG_harmony_static_fields = true;
678 : },
679 : [] {
680 55 : i::FLAG_harmony_public_fields = false;
681 55 : i::FLAG_harmony_static_fields = false;
682 : }},
683 : {"class X { #x = 1 }; new X;",
684 55 : [] { i::FLAG_harmony_private_fields = true; },
685 55 : [] { i::FLAG_harmony_private_fields = false; }},
686 : {"function t() { return class { #x = 1 }; } new t();",
687 55 : [] { i::FLAG_harmony_private_fields = true; },
688 55 : [] { i::FLAG_harmony_private_fields = false; }},
689 1885 : };
690 :
691 115 : for (unsigned i = 0; i < arraysize(outers); ++i) {
692 55 : struct Outer outer = outers[i];
693 39765 : for (unsigned j = 0; j < arraysize(inners); ++j) {
694 37200 : struct Inner inner = inners[j];
695 22365 : if (outer.strict_outer && (inner.skip & SKIP_STRICT_OUTER)) continue;
696 19155 : if (outer.strict_test_function && (inner.skip & SKIP_STRICT_FUNCTION)) {
697 : continue;
698 : }
699 17430 : if (outer.arrow && (inner.skip & SKIP_ARROW)) continue;
700 :
701 : const char* code = outer.code;
702 17405 : int code_len = Utf8LengthHelper(code);
703 :
704 17405 : int params_len = Utf8LengthHelper(inner.params);
705 17405 : int source_len = Utf8LengthHelper(inner.source);
706 17405 : int len = code_len + params_len + source_len;
707 :
708 17405 : if (inner.prologue != nullptr) inner.prologue();
709 :
710 17405 : i::ScopedVector<char> program(len + 1);
711 17405 : i::SNPrintF(program, code, inner.params, inner.source);
712 :
713 : i::HandleScope scope(isolate);
714 :
715 : i::Handle<i::String> source =
716 17405 : factory->InternalizeUtf8String(program.start());
717 34810 : source->PrintOn(stdout);
718 : printf("\n");
719 :
720 : // Compile and run the script to get a pointer to the lazy function.
721 : v8::Local<v8::Value> v = CompileRun(program.start());
722 : i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
723 : i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
724 : i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
725 :
726 17405 : if (inner.bailout == Bailout::BAILOUT_IF_OUTER_SLOPPY &&
727 : !outer.strict_outer) {
728 60 : CHECK(!shared->HasUncompiledDataWithPreparseData());
729 : continue;
730 : }
731 :
732 17345 : CHECK(shared->HasUncompiledDataWithPreparseData());
733 : i::Handle<i::PreparseData> produced_data_on_heap(
734 : shared->uncompiled_data_with_preparse_data()->preparse_data(),
735 : isolate);
736 :
737 : // Parse the lazy function using the scope data.
738 34690 : i::ParseInfo using_scope_data(isolate, shared);
739 : using_scope_data.set_lazy_compile();
740 : using_scope_data.set_consumed_preparse_data(
741 34690 : i::ConsumedPreparseData::For(isolate, produced_data_on_heap));
742 17345 : CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate));
743 :
744 : // Verify that we skipped at least one function inside that scope.
745 : i::DeclarationScope* scope_with_skipped_functions =
746 : using_scope_data.literal()->scope();
747 17345 : CHECK(i::ScopeTestHelper::HasSkippedFunctionInside(
748 : scope_with_skipped_functions));
749 :
750 : // Do scope allocation (based on the preparsed scope data).
751 17345 : CHECK(i::DeclarationScope::Analyze(&using_scope_data));
752 :
753 : // Parse the lazy function again eagerly to produce baseline data.
754 34690 : i::ParseInfo not_using_scope_data(isolate, shared);
755 : not_using_scope_data.set_lazy_compile();
756 17345 : CHECK(i::parsing::ParseFunction(¬_using_scope_data, shared, isolate));
757 :
758 : // Verify that we didn't skip anything (there's no preparsed scope data,
759 : // so we cannot skip).
760 : i::DeclarationScope* scope_without_skipped_functions =
761 : not_using_scope_data.literal()->scope();
762 17345 : CHECK(!i::ScopeTestHelper::HasSkippedFunctionInside(
763 : scope_without_skipped_functions));
764 :
765 : // Do normal scope allocation.
766 17345 : CHECK(i::DeclarationScope::Analyze(¬_using_scope_data));
767 :
768 : // Verify that scope allocation gave the same results when parsing w/ the
769 : // scope data (and skipping functions), and when parsing without.
770 17345 : i::ScopeTestHelper::CompareScopes(
771 : scope_without_skipped_functions, scope_with_skipped_functions,
772 34690 : inner.precise_maybe_assigned == PreciseMaybeAssigned::YES);
773 :
774 17345 : if (inner.epilogue != nullptr) inner.epilogue();
775 : }
776 : }
777 5 : }
778 :
779 : // Regression test for
780 : // https://bugs.chromium.org/p/chromium/issues/detail?id=753896. Should not
781 : // crash.
782 26644 : TEST(Regress753896) {
783 : i::Isolate* isolate = CcTest::i_isolate();
784 : i::Factory* factory = isolate->factory();
785 : i::HandleScope scope(isolate);
786 5 : LocalContext env;
787 :
788 : i::Handle<i::String> source = factory->InternalizeUtf8String(
789 5 : "function lazy() { let v = 0; if (true) { var v = 0; } }");
790 5 : i::Handle<i::Script> script = factory->NewScript(source);
791 10 : i::ParseInfo info(isolate, script);
792 :
793 : // We don't assert that parsing succeeded or that it failed; currently the
794 : // error is not detected inside lazy functions, but it might be in the future.
795 5 : i::parsing::ParseProgram(&info, isolate);
796 5 : }
797 :
798 26644 : TEST(ProducingAndConsumingByteData) {
799 : i::Isolate* isolate = CcTest::i_isolate();
800 : i::HandleScope scope(isolate);
801 5 : LocalContext env;
802 :
803 10 : i::Zone zone(isolate->allocator(), ZONE_NAME);
804 : std::vector<uint8_t> buffer;
805 : i::PreparseDataBuilder::ByteData bytes;
806 5 : bytes.Start(&buffer);
807 :
808 5 : bytes.Reserve(32);
809 5 : bytes.Reserve(32);
810 5 : CHECK_EQ(buffer.size(), 32);
811 : const int kBufferSize = 64;
812 5 : bytes.Reserve(kBufferSize);
813 5 : CHECK_EQ(buffer.size(), kBufferSize);
814 :
815 : // Write some data.
816 : #ifdef DEBUG
817 : bytes.WriteUint32(1983); // This will be overwritten.
818 : #else
819 5 : bytes.WriteVarint32(1983);
820 : #endif
821 5 : bytes.WriteVarint32(2147483647);
822 5 : bytes.WriteUint8(4);
823 5 : bytes.WriteUint8(255);
824 5 : bytes.WriteVarint32(0);
825 5 : bytes.WriteUint8(0);
826 : #ifdef DEBUG
827 : bytes.SaveCurrentSizeAtFirstUint32();
828 : int saved_size = 21;
829 : CHECK_EQ(buffer.size(), kBufferSize);
830 : CHECK_EQ(bytes.length(), saved_size);
831 : #endif
832 5 : bytes.WriteUint8(100);
833 : // Write quarter bytes between uint8s and uint32s to verify they're stored
834 : // correctly.
835 5 : bytes.WriteQuarter(3);
836 5 : bytes.WriteQuarter(0);
837 5 : bytes.WriteQuarter(2);
838 5 : bytes.WriteQuarter(1);
839 5 : bytes.WriteQuarter(0);
840 5 : bytes.WriteUint8(50);
841 :
842 5 : bytes.WriteQuarter(0);
843 5 : bytes.WriteQuarter(1);
844 5 : bytes.WriteQuarter(2);
845 5 : bytes.WriteQuarter(3);
846 5 : bytes.WriteVarint32(50);
847 :
848 : // End with a lonely quarter.
849 5 : bytes.WriteQuarter(0);
850 5 : bytes.WriteQuarter(1);
851 5 : bytes.WriteQuarter(2);
852 5 : bytes.WriteVarint32(0xff);
853 :
854 : // End with a lonely quarter.
855 5 : bytes.WriteQuarter(2);
856 :
857 5 : CHECK_EQ(buffer.size(), 64);
858 : #ifdef DEBUG
859 : const int kDataSize = 42;
860 : #else
861 : const int kDataSize = 21;
862 : #endif
863 5 : CHECK_EQ(bytes.length(), kDataSize);
864 5 : CHECK_EQ(buffer.size(), kBufferSize);
865 :
866 : // Copy buffer for sanity checks later-on.
867 5 : std::vector<uint8_t> copied_buffer(buffer);
868 :
869 : // Move the data from the temporary buffer into the zone for later
870 : // serialization.
871 5 : bytes.Finalize(&zone);
872 5 : CHECK_EQ(buffer.size(), 0);
873 5 : CHECK_EQ(copied_buffer.size(), kBufferSize);
874 :
875 : {
876 : // Serialize as a ZoneConsumedPreparseData, and read back data.
877 : i::ZonePreparseData* data_in_zone = bytes.CopyToZone(&zone, 0);
878 : i::ZoneConsumedPreparseData::ByteData bytes_for_reading;
879 : i::ZoneVectorWrapper wrapper(data_in_zone->byte_data());
880 : i::ZoneConsumedPreparseData::ByteData::ReadingScope reading_scope(
881 : &bytes_for_reading, wrapper);
882 :
883 5 : CHECK_EQ(wrapper.data_length(), kDataSize);
884 :
885 215 : for (int i = 0; i < kDataSize; i++) {
886 210 : CHECK_EQ(copied_buffer.at(i), wrapper.get(i));
887 : }
888 :
889 : #ifdef DEBUG
890 : CHECK_EQ(bytes_for_reading.ReadUint32(), saved_size);
891 : #else
892 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 1983);
893 : #endif
894 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 2147483647);
895 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 4);
896 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 255);
897 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 0);
898 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 0);
899 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 100);
900 :
901 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
902 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
903 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
904 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
905 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
906 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 50);
907 :
908 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
909 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
910 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
911 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
912 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 50);
913 :
914 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
915 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
916 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
917 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 0xff);
918 :
919 10 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
920 : // We should have consumed all data at this point.
921 5 : CHECK(!bytes_for_reading.HasRemainingBytes(1));
922 : }
923 :
924 : {
925 : // Serialize as an OnHeapConsumedPreparseData, and read back data.
926 5 : i::Handle<i::PreparseData> data_on_heap = bytes.CopyToHeap(isolate, 0);
927 5 : CHECK_EQ(data_on_heap->data_length(), kDataSize);
928 5 : CHECK_EQ(data_on_heap->children_length(), 0);
929 : i::OnHeapConsumedPreparseData::ByteData bytes_for_reading;
930 : i::OnHeapConsumedPreparseData::ByteData::ReadingScope reading_scope(
931 : &bytes_for_reading, *data_on_heap);
932 :
933 215 : for (int i = 0; i < kDataSize; i++) {
934 210 : CHECK_EQ(copied_buffer[i], data_on_heap->get(i));
935 : }
936 :
937 : #ifdef DEBUG
938 : CHECK_EQ(bytes_for_reading.ReadUint32(), saved_size);
939 : #else
940 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 1983);
941 : #endif
942 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 2147483647);
943 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 4);
944 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 255);
945 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 0);
946 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 0);
947 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 100);
948 :
949 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
950 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
951 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
952 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
953 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
954 5 : CHECK_EQ(bytes_for_reading.ReadUint8(), 50);
955 :
956 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
957 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
958 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
959 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 3);
960 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 50);
961 :
962 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 0);
963 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 1);
964 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
965 5 : CHECK_EQ(bytes_for_reading.ReadVarint32(), 0xff);
966 :
967 5 : CHECK_EQ(bytes_for_reading.ReadQuarter(), 2);
968 : // We should have consumed all data at this point.
969 5 : CHECK(!bytes_for_reading.HasRemainingBytes(1));
970 : }
971 79922 : }
|